并行Python:4个线程的速度与2个线程相同
我使用它在多个核上执行计算量大的代码。 我有一个处理器,它有2个内核和4个线程 有趣的是,如果我使用2或4 thead,计算所需的时间几乎相同。我编写了一个小示例代码,演示了这种现象并行Python:4个线程的速度与2个线程相同,python,multithreading,python-2.7,parallel-python,Python,Multithreading,Python 2.7,Parallel Python,我使用它在多个核上执行计算量大的代码。 我有一个处理器,它有2个内核和4个线程 有趣的是,如果我使用2或4 thead,计算所需的时间几乎相同。我编写了一个小示例代码,演示了这种现象 import itertools import pp import time def cc(data, n): count = 0 for A in data: for B in itertools.product((-1,0,1), repeat=n):
import itertools
import pp
import time
def cc(data, n):
count = 0
for A in data:
for B in itertools.product((-1,0,1), repeat=n):
inner_product = sum(a*b for a,b in zip(A,B))
if inner_product == 0:
count += 1
return count
n = 9
for thread_count in (1, 2, 3, 4):
print("Thread_count = {}".format(thread_count))
ppservers = ()
job_server = pp.Server(thread_count, ppservers=ppservers)
datas = [[] for _ in range(thread_count)]
for index, A in enumerate(itertools.product((0,1), repeat=n)):
datas[index%thread_count].append(A)
print("Data sizes: {}".format(map(len, datas)))
time_start = time.time()
jobs = [job_server.submit(cc,(data,n), (), ("itertools",)) for data in datas]
result = sum(job() for job in jobs)
time_end = time.time()
print("Time = {}".format(time_end - time_start))
print("Result = {}".format(result))
print
这里有一个运行程序和cpu使用情况的简短视频:当我使用2个线程时,cpu使用率为50%,如果我使用4个线程,cpu使用率为100%。但它只是稍微快一点。使用2个线程,我的加速比为1.8倍,使用3个线程,我的加速比为1.9倍,使用4个线程,我的加速比为2倍
如果代码太快,请使用
n=10
或n=11
。但是要小心,复杂性是6^n
。因此n=10
将花费6倍于n=9
的时间 2个内核和4个线程意味着每个内核上有两个超线程,它们不会线性扩展,因为它们共享资源,并且可以根据工作负载相互妨碍。并行Python在后台使用进程和IPC。每个核心都在调度两个不同的进程,因此您可能会看到缓存抖动(核心缓存在超线程之间共享)。我知道此线程有点旧,但我认为添加一些数据点可能会有所帮助。我在一个有4个虚拟CPU(2.93Ghz X5670 xeon)和8GB内存分配的虚拟机上运行了这个程序。虚拟机托管在Hyper-V上,在Ubuntu 14.10 64位上运行Python 2.7.8,但我的PP版本是fork PPFT
在第一次运行中,线程数为4。在第二个循环中,我将for循环修改为8
输出:
再添加4个内核,并将ram加倍,循环相同,循环8:
输出:每个线程所做的工作强度有多大?这可能只是因为,对于较小的计算来说,差异可以忽略。每个作业在几分钟内使用25%的cpu。您知道,即使您的核心有多个线程,Python也会阻止同时执行多个线程吗?因此,您的两个处理器将连续执行程序的每个进程,无论您使用2个线程(每个核心1个线程)还是4个线程(每个核心2个线程)。@RickTeachey通读了问题链接到的。是的,我知道它不会线性扩展。但我没想到会这么糟。当使用两倍的cpu时,执行速度提高5%是非常糟糕的。