我试图通过使用python的多处理模块来加速一些大规模的模拟,在运行Suse Linux的24个内核的机器上。通过阅读文档,我了解到,只有在单个计算所花费的时间比创建池的开销长得多的情况下,这才有意义。
让我困惑的是,一些单个进程的执行时间要比运行单个进程时长得多。在我的实际模拟中,时间从大约300秒增加到1500秒。有趣的是,当我使用更多的进程时,情况会变得更糟。
下面的示例说明了一个稍微短一些的虚拟循环的问题:
from time import clock,time
import multiprocessing
import os
def simulate(params):
t1 = clock()
result = 0
for i in range(10000):
for j in range(10000):
result+=i*j
pid = os.getpid()
print 'pid: ',pid,' sim time: ',clock() - t1, 'seconds'
return result
if __name__ == '__main__':
for n_procs in [1,5,10,20]:
print n_procs,' processes:'
t1 = time()
result = multiprocessing.Pool(processes = n_procs).map(simulate,range(20))
print 'total: ',time()-t1这将产生以下输出:
1 processes:
pid: 1872 sim time: 8.1 seconds
pid: 1872 sim time: 7.92 seconds
pid: 1872 sim time: 7.93 seconds
pid: 1872 sim time: 7.89 seconds
pid: 1872 sim time: 7.87 seconds
pid: 1872 sim time: 7.74 seconds
pid: 1872 sim time: 7.83 seconds
pid: 1872 sim time: 7.84 seconds
pid: 1872 sim time: 7.88 seconds
pid: 1872 sim time: 7.82 seconds
pid: 1872 sim time: 8.83 seconds
pid: 1872 sim time: 7.91 seconds
pid: 1872 sim time: 7.97 seconds
pid: 1872 sim time: 7.84 seconds
pid: 1872 sim time: 7.87 seconds
pid: 1872 sim time: 7.91 seconds
pid: 1872 sim time: 7.86 seconds
pid: 1872 sim time: 7.9 seconds
pid: 1872 sim time: 7.96 seconds
pid: 1872 sim time: 7.97 seconds
total: 159.337743998
5 processes:
pid: 1906 sim time: 8.66 seconds
pid: 1907 sim time: 8.74 seconds
pid: 1908 sim time: 8.75 seconds
pid: 1905 sim time: 8.79 seconds
pid: 1909 sim time: 9.52 seconds
pid: 1906 sim time: 7.72 seconds
pid: 1908 sim time: 7.74 seconds
pid: 1907 sim time: 8.26 seconds
pid: 1905 sim time: 8.45 seconds
pid: 1909 sim time: 9.25 seconds
pid: 1908 sim time: 7.48 seconds
pid: 1906 sim time: 8.4 seconds
pid: 1907 sim time: 8.23 seconds
pid: 1905 sim time: 8.33 seconds
pid: 1909 sim time: 8.15 seconds
pid: 1908 sim time: 7.47 seconds
pid: 1906 sim time: 8.19 seconds
pid: 1907 sim time: 8.21 seconds
pid: 1905 sim time: 8.27 seconds
pid: 1909 sim time: 8.1 seconds
total: 35.1368539333
10 processes:
pid: 1918 sim time: 8.79 seconds
pid: 1920 sim time: 8.81 seconds
pid: 1915 sim time: 14.78 seconds
pid: 1916 sim time: 14.78 seconds
pid: 1914 sim time: 14.81 seconds
pid: 1922 sim time: 14.81 seconds
pid: 1913 sim time: 14.98 seconds
pid: 1921 sim time: 14.97 seconds
pid: 1917 sim time: 15.13 seconds
pid: 1919 sim time: 15.13 seconds
pid: 1920 sim time: 8.26 seconds
pid: 1918 sim time: 8.34 seconds
pid: 1915 sim time: 9.03 seconds
pid: 1921 sim time: 9.03 seconds
pid: 1916 sim time: 9.39 seconds
pid: 1913 sim time: 9.27 seconds
pid: 1914 sim time: 12.12 seconds
pid: 1922 sim time: 12.17 seconds
pid: 1917 sim time: 12.15 seconds
pid: 1919 sim time: 12.17 seconds
total: 27.4067809582
20 processes:
pid: 1941 sim time: 8.63 seconds
pid: 1939 sim time: 10.32 seconds
pid: 1931 sim time: 12.35 seconds
pid: 1936 sim time: 12.23 seconds
pid: 1937 sim time: 12.82 seconds
pid: 1942 sim time: 12.73 seconds
pid: 1932 sim time: 13.01 seconds
pid: 1946 sim time: 13.0 seconds
pid: 1945 sim time: 13.74 seconds
pid: 1944 sim time: 14.03 seconds
pid: 1929 sim time: 14.44 seconds
pid: 1943 sim time: 14.75 seconds
pid: 1935 sim time: 14.8 seconds
pid: 1930 sim time: 14.79 seconds
pid: 1927 sim time: 14.85 seconds
pid: 1934 sim time: 14.8 seconds
pid: 1928 sim time: 14.83 seconds
pid: 1940 sim time: 14.88 seconds
pid: 1933 sim time: 15.05 seconds
pid: 1938 sim time: 15.06 seconds
total: 15.1311581135我不明白的是,某些过程在一定数量的CPU之上变得更慢。我应该补充一点,这台机器上没有其他任何东西在运行。这是意料之中吗?我做错了什么吗?
发布于 2015-11-09 21:55:59
核心和计算机上的其他任何东西一样,都是共享资源。
操作系统通常会平衡负载。这意味着它将在尽可能多的核心上展开线程。*引导度量将是核心负载。
因此,如果线程数较少,那么内核计数,一些核心将处于空闲状态。(线程架构防止分裂到多个核上)。
如果有更多的线程,那么核心。OS将为单个内核分配多个线程,并在该核心上的这些线程之间执行多任务。在单核上从一个线程切换到另一个线程会带来一定的成本。
把任务从核心转移到另一个,代价更大。(在两个核心资源方面都相当重要)操作系统通常会避免这样的操作。
,所以回到你的故事。。
性能通过线程计数提高到核心计数,因为在那里空闲的内核得到了新的工作。很少有最后的核心,尽管那里忙着操作系统工作,所以这些增加了很少的实际性能。
在线程计数通过核心计数之后,的总体性能仍然提高了。仅仅因为OS可以切换活动线程,如果以前被长期运行的任务(比如I/O)卡住了,那么另一个操作系统就可以使用CPU时间。
如果线程计数显著超过核心计数,则性能将降低。因为太多的线程会争夺相同的资源(CPU时间),而切换成本将聚集到CPU周期的很大一部分。然而,从你的清单上看,它仍然没有发生。
似乎很长的执行时间?是很长的时间!只是线程并没有把它全部用于工作。当他们中的任何人被外部工作(I/O)卡住时,OS都会关闭它们,以最大限度地利用CPU,然后更多地切换到分配给核心的线程之间更均匀地分配CPU时间。
*操作系统也可以使用最少的电源,最大限度地使用I/O等等。特别是Linux在这里非常灵活。但这超出了范围;)如果有兴趣,可以在Linux中阅读各种调度程序。
发布于 2015-11-09 20:29:06
看过不同的问题和文件之后,我能找到最好的答案:
众所周知,multiprocessing在运行时性能方面通常会增加一些开销。这是/可能是许多不同因素的结果,例如分配RAM空间、初始化进程、等待终止、等,等。这就解释了从单数切换到并行处理的时间的增加。
随着进程数量的增加,时间的增加可以用多进程的工作方式来解释。ali_m 在这个链接中的评论是我能找到的最好的解释,解释了为什么会这样:
首先,如果您的线程共享CPU缓存,您可能会遭受更多的缓存错误,这可能导致性能严重下降
当您尝试同时在计算机上运行许多不同的程序时,这是一样的:您的程序开始“滞后”并减速,因为您的CPU一次只能处理这么多请求。
我发现的另一个很好的链接是这。虽然这是一个关于SQL服务器和使用查询的问题,但同样的想法也适用于它(关于开销的数量随着进程/查询的增加而增加)。
到目前为止,这还不是一个完整的答案,但这是我对你为什么得到结果的轻微理解。结论?您正在获得的结果,或者是正常的和预期的多处理结果。
发布于 2015-11-09 21:37:48
这个问题的答案使这个问题变得多余。事实证明,这台机器只有12个物理内核,每个内核可以接受两个线程。
multiprocessing.cpu_count()的输出为24。然而,lscpu产生的结果是,只有两个套接字,每个插座有六个核。
这就解释了为什么上述十个进程,单个进程的运行速度会变慢。
https://stackoverflow.com/questions/33617221
复制相似问题