Taj*_*any 9 python performance timing multiprocessing python-multiprocessing
我在具有8 GB RAM的macOS上具有4个内核(8线程超线程)的Intel i7并行生成大约400,000,000(4亿)个随机数.
但是,我也在DigitalOcean服务器上生成400,000,000个随机数,Debian上有20个内核,64 GB RAM.
这是代码:
import multiprocessing
import random
rangemin = 1
rangemax = 9
def randomGenPar_backend(backinput):
return random.randint(rangemin, rangemax)
def randomGenPar(num):
pool = multiprocessing.Pool()
return pool.map(randomGenPar_backend, range(0, num))
randNum = 400000000
random.seed(999)
randomGenPar(randNum)
Run Code Online (Sandbox Code Playgroud)
这些是基准测试的结果:
5,000,000 Random Numbers:
1 Core: 5.984
8 Core: 1.982
50,000,000 Random Numbers:
1 Core: 57.28
8 Core: 19.799
20 Core: 18.257
Times Benefit (20 core vs. 8 core) = 1.08
100,000,000 Random Numbers:
1 Core: 115
8 Core: 40.434
20 Core: 31.652
Times Benefit (20 core vs. 8 core) = 1.28
200,000,000 Random Numbers:
8 Core: 87
20 Core: 60
Times Benefit (20 core vs. 8 core) = 1.45
300,000,000 Random Numbers:
8 Core: 157
20 Core: 88
Times Benefit (20 core vs. 8 core) = 1.78
400,000,000 Random Numbers:
8 Core: 202
20 Core: 139
Times Benefit (20 core vs. 8 core) = 1.45 (DIP!)
500,000,000 Random Numbers:
8 Core: 280
20 Core: 171
Times Benefit (20 core vs. 8 core) = 1.64 (INCREASE!)
600,000,000 Random Numbers:
8 Core: 342
20 Core: 198
Times Benefit (20 core vs. 8 core) = 1.73
700,000,000 Random Numbers:
8 Core: 410
20 Core: 206
Times Benefit (20 core vs. 8 core) = 1.99
800,000,000 Random Numbers:
8 Core: 482
20 Core: 231
Times Benefit (20 core vs. 8 core) = 2.09
Run Code Online (Sandbox Code Playgroud)
通常,生成的随机数越多,可以使用20核CPU的并行性越多.因此,速度从8核到20核的"时间增加"随着时间的推移而增加.
然而,在3亿随机数之后,这个减少了,并且再次增加到8亿(我没有进一步测试).
为什么是这样?有具体原因吗?它只是随机的吗?(我重复了两次,两次都得到了相同的结果)
编辑:如果它有任何区别,我正在使用该time
函数来计算脚本的执行时间.此外,两台机器上的操作系统不同(8核 - macOS,20核 - Debian).
我想到了两种可能的解释。
这可能是垃圾收集启动的产物。一个简单的实验是关闭 GC 并查看“下降”是否持续:
>>> import gc
>>> gc.disable()
Run Code Online (Sandbox Code Playgroud)
另一种可能性是,这是在幕后使用realloc()实现列表增长的产物。实现的列表是固定长度的指针数组。当map()使用append()增加列表时,会定期调用C函数realloc()来调整指针数组的大小。通常,此调用的成本非常低,因为无需移动任何数据。但是,如果内存中的单个字节“阻碍”了大小调整,则所有数据都必须重新定位。这是非常昂贵的,如果在执行时多处理正在创建一个阻塞字节,则可能会导致您的“下降”。
为了测试这个假设,您可以使用imap()而不是map()并将结果输入到collections.deque()而不是list()。双端队列实现没有使用relloc,因此面对碎片内存时其性能是一致的(内部只是重复调用malloc()来获得固定长度的内存块)。
归档时间: |
|
查看次数: |
261 次 |
最近记录: |