1

Недавно я пытался парализовать некоторые соображения в списках, чтобы ускорить мой код, но я узнал, что паралинизация ведет к худшему исполнению ... может кто-нибудь помочь мне понять, почему?Paralelization python list comprehension не повышает производительность

мой компьютер является i7 4 ядра 8 потоков вокруг скорости ядра 3GHz, и я использую pytthon 2,7

Вот вам пример моего кода:

import numpy as np 
import multiprocessing as mulpro 
import itertools 
d1 = 0.1; 
d2 = 0.2; 
data = range(100000) #Array of data 
#example of list comprehension 
data2 = [i + np.random.uniform(d1,d2) for i in data] #this is faster than the following 
#example of multiprocessing 
def parAddRandom(array): 
    array = list(array) 
    return (array[0] + np.random.uniform(array[1],array[2])) 
pool = mulpro.Pool(processes=8) 
data3 = pool.map(parAddRandom, itertools.izip(data, itertools.repeat(d1), itertools.repeat(d2))) 

Я бы ожидать, что код будет быстрее распараллеливания, так как 8 ядер используются, кроме как от всего 1, но это не так ...

EDIT:

Если я изменить код, чтобы функции parAdd Random принимает только одно значение, то это экстремально быстрее ...

import numpy as np 
import multiprocessing as mulpro 
import itertools 
data = range(100000) #Array of data 
#example of list comprehension 
data2 = [i + np.random.uniform(d1,d2) for i in data] #Now this is not faster than the following 
#example of multiprocessing 
def parAddRandom(value): 
    return (value + np.random.uniform(0.1,0.2)) 
pool = mulpro.Pool(processes=8) 
data3 = pool.map(parAddRandom, data) 

Но мне еще нужно, чтобы иметь возможность изменять параметры «d1» и «d2» из предыдущего кода ...

+0

Насколько я знаю, ОС уже использует все ядра для закрепления этого прозадания, что означает распараллеливание в фоновом режиме. Таким образом, он уже полностью использует процессор. Когда вы создаете потоки, вы просто делите мощность процессора, что приводит к большему количеству операций для решения одной и той же проблемы с одинаковыми ресурсами. – Rockybilly

+0

К моему knowlegde, в python 2.7 в понимании списка используется только один ядро ​​и один поток ... http://programmers.stackexchange.com/questions/313013/is-python-list-comprehension-using-multi-threading-or- распараллелен в любом случае - на – Ignasi

+0

Тогда, простите, другая вещь, которая приходит мне на ум, заключается в том, что GIL может замедлить ее. – Rockybilly

ответ

1

Поскольку ваша функция мала накладные расходы при вызове функции (и других многопроцессорной техники) является доминирующим)

import numpy as np 
import timeit 

d1 = 0.1; 
d2 = 0.2; 

def parAddRandom(array): 

    return (array[0] + np.random.uniform(array[1],array[2])) 


array = 45436, d1, d2 
with_function_calling = timeit.timeit("parAddRandom(array)", globals=globals()) 

without_function_calling = timeit.timeit("array[0] + np.random.uniform(array[1],array[2])", globals=globals()) 

print ("function call adds {:0.2f}% overhead :(".format((100.0*with_function_calling/without_function_calling) - 100.0)) 

функция одна вызов добавляет 18,59% накладных расходов :(

Я думаю, что другая многопроцессорная техника добавить почти 100% в вашем примере ...

Если вы хотите, чтобы быть эффективным, вам придется создать функцию, которая принимает больший Chunk каждый раз ,

Смежные вопросы