为什么整个计算(在这种情况下为benchmking_f)花费的时间比连续方法花费的时间这么长?

时间:2019-09-03 04:30:49

标签: python parallel-processing multiprocessing

我正在尝试比较Python中的顺序计算和并行计算。

这是基准功能。

def benchmking_f(n=0):
    import time
    items = range(int(10**(6+n)))

    def f2(x):return x*x

    start = time.time()
    sum_squared = 0
    for i in items:
        sum_squared += f2(i)
    return time.time() - start

此顺序计算

problem_size = 2

import time
start = time.time()
tlist = []
for i in range(5):
    tlist.append(benchmking_f(problem_size))
print('for loop took {}s'.format(time.time() - start))
print('each iterate took')
print(tlist)

花了大约70来完成工作;每个迭代 [14.209498167037964、13.92169737815857、13.949078798294067、13.94432258605957、14.004642486572266]

这种并行方法

problem_size = 2

import itertools
import multiprocessing
start = time.time()
pool = multiprocessing.Pool(5)
tlist = list(pool.map(benchmking_f, itertools.repeat(problem_size, 5)))
print('pool.map took {}s'.format(time.time() - start))
print('each iterate took')
print(tlist)

大约花费42.45秒;每个迭代 [41.17476940155029、41.92032074928284、41.50966739654541、41.348535776138306、41.06284761428833]

问题

整个计算中的一部分(在本例中为benchmking_f)大约耗时14s,并行耗时42.45s

那是为什么?

注意: 我没有问总时间。我问的时间是整个计算的一部分,它在for循环中进行一次迭代,并在一个进程/线程中并行进行。

1-iter benchmking_f需要。

2 个答案:

答案 0 :(得分:3)

您有多少个物理(非逻辑)核心?您正在尝试同时运行该函数的5个副本,该函数在运行时会占用一个核心的100%,并且除非您拥有至少5个物理核心,否则它们将互相竞争,互为争夺

我有4个物理核心,但也想将我的机器用于其他用途,因此将Pool(5)减少为Pool(3)然后每次迭代的时机大致相同。

信封的背面

假设您有一个任务需要T秒内占用100%的CPU。如果要同时运行该任务的S个副本,则总共需要T*S cpu-seconds。如果您有C个完全免费的物理核心可以投入使用,那么最多min(C, S)个核心可以同时在聚合上工作,因此初步估算所需时间为:

T*S / min(C, S)

正如另一个答复所说,当您运行的进程比内核多时,操作系统会在整个持续时间内循环运行这些进程,以使它们全部花费相同的挂钟时间(在每个进程中一定数量的时间)除了等待操作系统让它再次运行一段时间之外,什么也没做。

我猜您有2个物理核心。以您的示例为例,T约为14秒,而S为5,因此,如果您有C=2个内核可以解决

14*5 / min(2, 5) = 14*5/2 = 35

秒。您实际上看到的值接近41。部分原因是开销,但是您的计算机似乎同时也在执行其他工作,因此您的测试运行没有获得2个内核的100%。

答案 1 :(得分:1)

总时间减少:70秒vs 42秒。

您的计算机可能同时以循环方式处理5件事。发生线程开销(上下文加载等),每个线程花费的时间更长。但是,由于更长的线程并行运行,因此5个线程在42秒内完成。

对于顺序操作,您的计算机将同一事物处理5次。每个线程可以运行直到完成而不会中断(因此,没有开销)。然而,所有这些都需要70秒才能完成。