【问题标题】:Paralelization python list comprehension not enhancing performance并行化 python 列表理解不会提高性能
【发布时间】:2016-07-20 12:44:14
【问题描述】:

最近我一直在尝试并行化一些列表推导以加速我的代码,但我发现并行化会导致更糟糕的执行时间......有人可以帮我理解为什么吗?

我的电脑是 i7 4 核 8 线程,核心速度约为 3GHz,我使用的是 python 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)))

我希望代码通过并行化更快,因为除了 1 个内核之外,使用了 8 个内核,但事实并非如此......

编辑:

如果我修改代码使函数 parAddRandom 只接受一个值,那么它会非常快...

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”...

【问题讨论】:

  • 据我所知,操作系统已经使用所有内核来固定该程序,这意味着在后台进行并行化。所以它已经完全使用了cpu。当您创建线程时,您只需分配 cpu 功率,这会导致更多操作以使用相同的资源解决相同的问题。
  • 据我所知,在 python 2.7 中,列表理解只使用一个核心和一个线程...programmers.stackexchange.com/questions/313013/…
  • 那么请原谅我,我想到的另一件事是 GIL 可能会放慢速度。

标签: python multithreading multiprocessing python-multithreading python-multiprocessing


【解决方案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))

function alone 调用增加了 18.59% 的开销 :(

我的猜测是其他多处理机器在您的示例中添加了几乎 100% ...

如果你想让它有效,你必须创建一个每次都占用更大块的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    • 2012-10-10
    • 1970-01-01
    相关资源
    最近更新 更多