我有两个简单的函数(一个范围内的循环)可以单独运行而没有任何依赖。我正在尝试使用Python多处理模块以及多线程模块运行这两个函数。
当我比较输出时,我发现多进程应用程序比多线程模块多1秒钟。
由于全局解释器锁定,我认为多线程效率不高......
基于以上陈述 -
1.如果两个进程之间没有依赖关系,最好使用多处理吗?
2.如何计算我可以在机器中运行的进程/线程数,以实现最高效率。
3.此外,有没有办法通过使用多线程来计算程序的效率......
多线程模块......
from multiprocessing import Process
import thread
import platform
import os
import time
import threading
class Thread1(threading.Thread):
def __init__(self,threadindicator):
threading.Thread.__init__(self)
self.threadind = threadindicator
def run(self):
starttime = time.time()
if self.threadind == 'A':
process1()
else:
process2()
endtime = time.time()
print 'Thread 1 complete : Time Taken = ', endtime - starttime
def process1():
starttime = time.time()
for i in range(100000):
for j in range(10000):
pass
endtime = time.time()
def process2():
for i in range(1000):
for j in range(1000):
pass
def main():
print 'Main Thread'
starttime = time.time()
thread1 = Thread1('A')
thread2 = Thread1('B')
thread1.start()
thread2.start()
threads = []
threads.append(thread1)
threads.append(thread2)
for t in threads:
t.join()
endtime = time.time()
print 'Main Thread Complete , Total Time Taken = ', endtime - starttime
if __name__ == '__main__':
main()
多进程模块
from multiprocessing import Process
import platform
import os
import time
def process1():
# print 'process_1 processor =',platform.processor()
starttime = time.time()
for i in range(100000):
for j in range(10000):
pass
endtime = time.time()
print 'Process 1 complete : Time Taken = ', endtime - starttime
def process2():
# print 'process_2 processor =',platform.processor()
starttime = time.time()
for i in range(1000):
for j in range(1000):
pass
endtime = time.time()
print 'Process 2 complete : Time Taken = ', endtime - starttime
def main():
print 'Main Process start'
starttime = time.time()
processlist = []
p1 = Process(target=process1)
p1.start()
processlist.append(p1)
p2 = Process(target = process2)
p2.start()
processlist.append(p2)
for i in processlist:
i.join()
endtime = time.time()
print 'Main Process Complete - Total time taken = ', endtime - starttime
if __name__ == '__main__':
main()
答案 0 :(得分:6)
如果您的计算机上有两个可用的CPU,则您有两个无需通信的进程,并且您希望同时使用它们来使程序更快,您应该使用多处理模块,而不是线程模块。
全局解释器锁(GIL)阻止Python解释器通过使用多个线程有效地使用多个CPU,因为一次只有一个线程可以执行Python字节码。因此,多线程不会改善应用程序的整体运行时间,除非您有阻塞的调用(例如,等待IO)或释放GIL(例如numpy
将对某些昂贵的调用执行此操作)延长时间。但是,多处理库会创建单独的子进程,因此会创建多个解释器副本,因此可以有效地使用多个CPU。
但是,在您给出的示例中,您有一个进程非常快速地完成(在我的机器上不到0.1秒),并且一个进程需要大约18秒才能完成另一个进程。具体数字可能因硬件而异。在这种情况下,几乎所有工作都在一个进程中进行,因此您实际上只使用一个CPU。在这种情况下,产生进程与线程的开销增加可能导致基于进程的版本变慢。
如果让两个进程都执行18秒嵌套循环,您应该会看到多处理代码的速度要快得多(假设您的计算机实际上有多个CPU)。在我的机器上,我看到多处理代码在大约18.5秒内完成,多线程代码在71.5秒内完成。我不确定为什么多线程的花费时间超过36秒,但我的猜测是GIL导致某种线程争用问题,这会减慢两个线程的执行速度。
至于你的第二个问题,假设系统上没有其他负载,你应该使用一些等于你系统上CPU数量的进程。您可以通过在Linux系统上执行lscpu
,在Mac系统上执行sysctl hw.ncpu
,或在Windows上的“运行”对话框中运行dxdiag
来发现这一点(可能还有其他方法,但这就是我的方式总是这样做。)
对于第三个问题,确定从额外流程获得多少效率的最简单方法就是使用time.time()
或{time
来衡量程序的总运行时间。 Linux中的实用程序(例如time python myprog.py
)。理想的加速比应该等于您正在使用的进程数,因此在4个CPU上运行的4个进程程序应该最多比具有1个进程的相同程序快4倍,假设您获得最大值受益于额外的流程。如果其他流程对您没那么大帮助,那么它将不到4倍。