所以我敲了一些测试代码,看看多处理模块与线程相比如何扩展cpu绑定工作。在Linux上,我得到了我期望的性能提升:
linux (dual quad core xeon): serialrun took 1192.319 ms parallelrun took 346.727 ms threadedrun took 2108.172 ms
我的双核macbook pro显示了相同的行为:
osx (dual core macbook pro) serialrun took 2026.995 ms parallelrun took 1288.723 ms threadedrun took 5314.822 ms
然后我在Windows机器上尝试了它并获得了一些非常不同的结果。
windows (i7 920): serialrun took 1043.000 ms parallelrun took 3237.000 ms threadedrun took 2343.000 ms
为什么哦,为什么,多处理方法在Windows上这么慢?
这是测试代码:
#!/usr/bin/env python import multiprocessing import threading import time def print_timing(func): def wrapper(*arg): t1 = time.time() res = func(*arg) t2 = time.time() print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0) return res return wrapper def counter(): for i in xrange(1000000): pass @print_timing def serialrun(x): for i in xrange(x): counter() @print_timing def parallelrun(x): proclist = [] for i in xrange(x): p = multiprocessing.Process(target=counter) proclist.append(p) p.start() for i in proclist: i.join() @print_timing def threadedrun(x): threadlist = [] for i in xrange(x): t = threading.Thread(target=counter) threadlist.append(t) t.start() for i in threadlist: i.join() def main(): serialrun(50) parallelrun(50) threadedrun(50) if __name__ == '__main__': main()
答案 0 :(得分:25)
python documentation for multiprocessing归咎于缺少os.fork()来解决Windows中的问题。它可能适用于此。
查看导入psyco时会发生什么。首先,easy_install它:
C:\Users\hughdbrown>\Python26\scripts\easy_install.exe psyco
Searching for psyco
Best match: psyco 1.6
Adding psyco 1.6 to easy-install.pth file
Using c:\python26\lib\site-packages
Processing dependencies for psyco
Finished processing dependencies for psyco
将它添加到python脚本的顶部:
import psyco
psyco.full()
我没有得到这些结果:
serialrun took 1191.000 ms
parallelrun took 3738.000 ms
threadedrun took 2728.000 ms
我得到了以下结果:
serialrun took 43.000 ms
parallelrun took 3650.000 ms
threadedrun took 265.000 ms
平行仍然很慢,但其他人烧橡胶。
编辑:同样,尝试使用多处理池。 (这是我第一次尝试这个,而且速度很快,我认为我必须遗漏一些东西。)
@print_timing
def parallelpoolrun(reps):
pool = multiprocessing.Pool(processes=4)
result = pool.apply_async(counter, (reps,))
结果:
C:\Users\hughdbrown\Documents\python\StackOverflow>python 1289813.py
serialrun took 57.000 ms
parallelrun took 3716.000 ms
parallelpoolrun took 128.000 ms
threadedrun took 58.000 ms
答案 1 :(得分:21)
在UNIX变体下,进程的重量要轻得多。 Windows进程很繁重,需要更多时间才能启动。线程是在Windows上进行多处理的推荐方法。
答案 2 :(得分:5)
据说在Windows上创建进程比在linux上更昂贵。如果您在网站上搜索,您会找到一些信息。这是one我很容易找到的。
答案 3 :(得分:2)
刚开始游泳池需要很长时间。我已经在'真实世界'程序中找到了如果我可以保持池打开并将其重用于许多不同的进程,通过方法调用(通常使用map.async)传递引用然后在Linux上我可以节省几个百分比但在Windows上我经常可以把时间减半。对于我的特定问题,Linux总是更快,但即使在Windows上,我也可以从多处理中获得净收益。
答案 4 :(得分:1)
目前,你的counter()函数没有修改很多状态。尝试更改counter(),以便修改许多页面的内存。然后运行一个cpu绑定循环。看看linux和windows之间是否还存在很大差异。
我现在没有运行python 2.6,所以我不能自己尝试。