为什么整个计算的一部分(在这种情况下benchmking_f)并行花费的时间比顺序方法的时间长得多?



我正在尝试比较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(连续大约需要 14 秒,并行需要 42.45 秒

为什么?

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

1-iterbenchmking_f需要。

你有多少个物理(非逻辑(内核? 您尝试同时运行该函数的 5 个副本,只要函数运行,它就会占用一个内核的 100%,除非您至少有 5 个物理内核,否则它们将在周期内相互争斗。

我有 4 个物理内核,但也想将我的机器用于其他事情,因此减少了Pool(3)Pool(5).然后,无论哪种方式,每次迭代的时间都大致相同。

信封背面

假设您有一个任务,该任务将 100% 的 CPU 固定T秒。 如果要同时运行该任务的S个副本,则总共需要T*S个 CPU 秒。 如果你有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的东西。 开销占其中的一部分,但似乎您的机器也可能同时在执行其他工作,因此您的测试运行没有得到 100% 的 2 个内核。

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

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

对于顺序,您的计算机正在处理相同的内容 5 次。每个线程都可以运行,直到它完成而不会中断(因此,没有开销(。然而,所有这些都需要 70 秒才能完成。

最新更新