我已经编写了一个算法,它可以获取地理空间数据并执行许多步骤。输入数据是大型光栅研究区域(约1.5亿像素)的多边形和协变量光栅的形状文件。步骤如下:
整个过程需要迭代很多次(比如100次),但是每次迭代都需要一个多小时。对于每个迭代,最耗时的部分是第4步和第5步。因为目标网格太大了,我一次只处理一个块(比如1000行)。在
我有一个6核CPU和32GB RAM,因此在每次迭代中,我都尝试使用Python的multiprocessing
模块和Pool
对象同时处理多个块(步骤4和5),然后使用调用全局输出写入函数的回调函数将输出(预测)写入公共输出网格集。这似乎是可行的,但并不比处理串联中的每个块快(实际上,它可能慢)。在
所以我的问题是,有没有一种更有效的方法?我对多处理模块的Queue
类感兴趣,但我不太确定它是如何工作的。例如,我想知道让一个执行步骤4和步骤5的队列将结果传递给执行步骤6的另一个队列是否更有效。或者这就是排队的目的?在
如有任何建议,我们将不胜感激。在
Python的多处理能力的当前状态对于CPU受限的处理来说不是很好。我害怕告诉您,使用
multiprocessing
模块无法使它运行得更快,您使用multiprocessing
也不是问题所在。在真正的问题是Python仍然受GlobalInterpreterLock(GIL)规则的约束(我强烈建议使用slides)。关于GIL的工作,已经有了一些令人兴奋的理论和experimental advances。python3.2事件包含一个新的GIL,它解决了一些问题,但引入了其他问题。在
现在,用一个串行线程执行多个Python进程比在一个进程中运行多个线程要快。这将允许您避免在线程之间获取GIL的问题(通过有效地拥有更多GIL)。但是,只有在Python进程之间的IPC开销没有掩盖处理的好处时,这才是有益的。在
Eli Bendersky写了一篇不错的overview article关于他尝试用多处理使CPU绑定的进程运行更快的经验。在
值得注意的是,PEP 371希望通过引入
multiprocessing
模块(以前是一个名为pyProcessing
的非标准包装)来“绕过”GIL。然而,GIL似乎仍然在Python解释器中扮演了太大的角色,使得它不能很好地与CPU绑定的算法一起工作。许多不同的人都致力于删除/重写GIL,但是没有任何东西能让它成为Python版本。在因为Python并不意味着要进行密集的数字压缩,所以我通常开始将Python程序的关键部分转换成C/C++,并加快速度。在
而且,python的多线程处理也不是很好。Python一直在为各种事情使用全局信号量。因此,即使使用python提供的线程,事情也不会变得更快。线程对于应用程序很有用,在这些应用程序中,线程通常会等待IO之类的东西。在
在制作C模块时,可以在处理数据时手动释放全局信号量(当然,这样就不再访问python值了)。在
使用capi需要一些练习,但是它的结构清晰,而且比Java原生API更容易使用。在
请参见python文档中的“扩展和嵌入”。在
这种方式可以在C/C++中制作时间关键部件,而在Python中用更快速的编程工作更慢的部分…在
中的一些多处理示例python.org网站我不太清楚,很容易从一个有缺陷的设计开始。下面是一个简单化的例子,让我开始一个项目:
这将使3个处理器运行15秒。它应该很容易修改为更多。也许这将有助于调试您当前的代码,并确保您真正生成多个独立的进程。在
如果由于RAM限制而必须共享数据,那么我建议您: http://docs.python.org/library/multiprocessing.html#sharing-state-between-processes
相关问题 更多 >
编程相关推荐