2016-08-11 5 views
0

Ma question concerne le multi-threading en python. Le problème sur lequel je travaille est de trouver 80% de tableaux similaires (les longueurs sont 64) à un tableau donné avec la même longueur à partir de 10 millions de tableaux. Le problème est que bien que mon code s'exécute en 12.148 secondes quand je l'itère linéairement dans une boucle while, il ne s'exécute pas en 28-30 secondes quand j'utilise le multi threading. Les deux implémentations sont ci-dessous. Tout conseil apprécié et s'il vous plaît éclairez-moi, pourquoi est-ce que cela le rend plus lent à multi-thread dans ce cas? Code Première:Pourquoi le thread ne rend-il pas plus rapide l'itération sur un tableau numpy?

import timeit 
import numpy as np 

ph = np.load('newDataPhoto.npy') 
myPhoto1 = np.array([ 1. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0. 
, 0. , 1. , 1. , 0. , 1. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 1. 
, 1. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 0. ]) 



start = timeit.default_timer() 

kk=0 
i=0 
while i< 10000000: 
    u = np.count_nonzero(ph[i] != myPhoto1) 
    if u <= 14: 
     kk+=1 
    i+=1 

print(kk) 

stop = timeit.default_timer() 
print stop-start 

seconde (multi-thread):

from threading import Thread 
import numpy as np 
import timeit 

start = timeit.default_timer() 
ph = np.load('newDataPhoto.npy') 
pc = np.load('newDataPopCount.npy') 

myPhoto1 = np.array([ 1. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0. 
, 0. , 1. , 1. , 0. , 1. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 1. 
, 1. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 0. ]) 

def hamming_dist(left, right, name): 
    global kk 
    start = timeit.default_timer() 
    while left<=right: 
     if(np.count_nonzero(ph[left] != myPhoto1)<=14): 
      kk+=1 
     left+=1 

    stop=timeit.default_timer() 
    print name 
    print stop-start 

def Main(): 
    global kk 
    kk=0 
    t1 = Thread(target=hamming_dist, args=(0,2500000, 't1')) 
    t2 = Thread(target=hamming_dist, args=(2500001, 5000000, 't2')) 
    t3 = Thread(target=hamming_dist, args=(5000001, 7500000,'t3')) 
    t4 = Thread(target=hamming_dist, args=(7500001, 9999999, 't4')) 

    t1.start() 
    t2.start() 
    t3.start() 
    t4.start() 

    print ('main done') 

if __name__ == "__main__": 
    Main() 

et leurs sorties dans l'ordre:

38 
12.148679018 
##### 
main done 
t4 
26.4695241451 
t2 
27.4959039688 
t3 
27.5113890171 
t1 
27.5896160603 
+0

À moins que votre code ne soit lié aux E/S, il est peu probable que le filetage le rende plus rapide. En fait, le surdébit introduit le rend souvent plus lent. – martineau

+0

Je comprends, merci. –

Répondre

0

je résolu le problème. J'ai découvert que le threading est bloqué par GIL qui ne permet jamais d'utiliser plus que le processeur actuel. Cependant en utilisant le module de multi-traitement travaillé. Voici la modification que j'ai faite:

import numpy as np 
import multiprocessing 
import timeit 

start = timeit.default_timer() 
ph = np.load('newDataPhoto.npy') 
pc = np.load('newDataPopCount.npy') 

myPhoto1 = np.array([ 1. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0. 
, 0. , 1. , 1. , 0. , 1. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 1. 
, 1. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 0. ]) 

def hamming_dist(left, right, name): 
    global kk 
    start = timeit.default_timer() 
    while left<=right: 
     if(np.count_nonzero(ph[left] != myPhoto1)<=14): 
      kk+=1 
     left+=1 

    stop=timeit.default_timer() 
    print name 
    print stop-start 

def Main(): 
    global kk 
    kk=0 
    t1 = multiprocessing.Process(target=hamming_dist, args=(0,2500000, 't1')) 
    t2 = multiprocessing.Process(target=hamming_dist, args=(2500001, 5000000, 't2')) 
    t3 = multiprocessing.Process(target=hamming_dist, args=(5000001, 7500000,'t3')) 
    t4 = multiprocessing.Process(target=hamming_dist, args=(7500001, 9999999, 't4')) 

    t1.start() 
    t2.start() 
    t3.start() 
    t4.start() 

    print ('main done') 

if __name__ == "__main__": 
    Main()