首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python多处理设计

Python多处理设计
EN

Stack Overflow用户
提问于 2012-06-01 01:12:46
回答 4查看 2.1K关注 0票数 18

我编写了一个获取地理空间数据的算法,并执行了许多步骤。输入的数据是一个多边形的形状文件和一个大的栅格研究区域(约1.5亿像素)的协变量光栅。这些步骤如下:

  1. 来自shapefile内多边形的样本点
  2. 对于每个取样点,从协变量栅格中提取值。
  3. 在采样点上建立预测模型
  4. 提取目标网格点的协变量
  5. 预测模型在目标网格中的应用
  6. 将预测写入一组输出网格

整个过程需要多次迭代(例如100次),但每次迭代目前需要一个多小时的时间来进行串联处理。对于每一次迭代,最耗时的部分是步骤4和第5步,因为目标网格太大了,所以我一直在一次处理一个块(例如1000行)。

我有一个6核CPU,内存为32 Gb,因此在每次迭代中,我尝试使用Python的multiprocessing模块和一个Pool对象同时处理多个块(步骤4和步骤5),然后使用调用全局输出写入函数的回调函数将输出(预测)写入到常见的输出网格集。这似乎是可行的,但并不比串联处理每个块更快(实际上,可能更慢)。

所以我的问题是,有没有更有效的方法来做到这一点?我对多处理模块的Queue类感兴趣,但我不太确定它是如何工作的。例如,我想知道是否有一个执行步骤4和步骤5的队列,然后将结果传递给另一个执行步骤6的队列,或者这是为了什么队列?

如有任何指示,将不胜感激。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-06-20 14:24:49

Python的多处理功能的当前状态对于CPU绑定处理不是很好。我恐怕要告诉您,使用multiprocessing模块无法使其运行得更快,问题也不在于您对multiprocessing的使用。

真正的问题是Python仍然受GlobalInterpreterLock(GIL)规则的约束(我强烈建议使用幻灯片)。有一些令人兴奋的理论和实验进展围绕吉尔工作。Python3.2事件包含一个新的GIL,它解决了一些问题,但引入了其他问题。

目前,使用单个串行线程执行多个Python进程要比尝试在一个进程中运行多个线程要快。这将使您避免在线程之间获取GIL的问题(通过有效地拥有更多的GIL)。但是,只有在您的Python进程之间的IPC开销没有超过处理的好处时,这才是有益的。

Eli写了一篇像样的概述条款,讲述了他试图通过多处理使CPU绑定进程运行得更快的经验。

值得注意的是,佩普371希望通过引入multiprocessing模块(以前是一种名为pyProcessing的非标准包)而“绕开”GIL。然而,GIL在Python解释器中仍然扮演着太大的角色,无法很好地处理CPU绑定算法。许多不同的人都致力于移除/重写GIL,但是没有什么东西能使它成为Python版本。

票数 3
EN

Stack Overflow用户

发布于 2012-06-15 22:31:13

python.org的一些多处理示例并不十分清楚,而且很容易从有缺陷的设计开始。下面是一个简单的例子,让我开始一个项目:

代码语言:javascript
运行
复制
import os, time, random, multiprocessing
def busyfunc(runseconds):
    starttime = int(time.clock())
    while 1:
        for randcount in range(0,100):
            testnum = random.randint(1, 10000000)
            newnum = testnum / 3.256
        newtime = int(time.clock())
        if newtime - starttime > runseconds:
            return

def main(arg):
    print 'arg from init:', arg
    print "I am " + multiprocessing.current_process().name

    busyfunc(15)

if __name__ == '__main__':

    p = multiprocessing.Process(name = "One", target=main, args=('passed_arg1',))
    p.start()

    p = multiprocessing.Process(name = "Two", target=main, args=('passed_arg2',))
    p.start()

    p = multiprocessing.Process(name = "Three", target=main, args=('passed_arg3',))
    p.start()

    time.sleep(5)

这应该练习3个处理器15秒。它应该很容易修改它的更多。也许这将有助于调试当前代码,并确保您确实生成了多个独立的进程。

如果由于内存限制必须共享数据,那么我建议如下:http://docs.python.org/library/multiprocessing.html#sharing-state-between-processes

票数 1
EN

Stack Overflow用户

发布于 2012-06-20 08:32:33

因为python并不真正意味着要做大量的数字技巧,所以我通常开始将python程序的关键时间部分转换为C/C++,并大大加快速度。

而且,python多线程也不是很好。Python一直在使用全局信号量来处理各种事情。因此,即使您使用python提供的线程,事情也不会变得更快。线程对于应用程序很有用,在应用程序中,线程通常会等待IO之类的东西。

在生成C模块时,您可以在处理数据时手动释放全局信号量(当然,不再访问python值)。

它需要一些使用C API的练习,但它的结构清晰,使用起来比Java原生API容易得多。

请参阅python文档中的“扩展和嵌入”。

这种方法可以使时间关键部分在C/C++中运行,而速度较慢的部分在python中运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10843240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档