2012-01-10 65 views
3

在Python + Python图像库脚本中,有一个称为processPixel(image,pos)的函数,该函数根据图像和位置计算数学指数。使用简单的for循环为每个像素计算此索引:使用多线程在python上更快地处理图像?

for x in range(image.size[0)): 
    for y in range(image.size[1)): 
     myIndex[x,y] = processPixel(image,[x,y]) 

这花费了太多时间。如何执行线程来分割加速它的工作?多线程代码可以多快?特别是,这是由处理器内核的数量来定义的吗?

+0

另外,我很愿意打赌'processPixel'可能是“numpy的-指明分数”,在这种情况下,你会看到在你目前所采用的巨大加速。 – 2012-01-11 15:23:16

回答

6

由于Global Interpreter Lock,您无法使用螺纹加速。 Python解释器的某些内部状态受该锁的保护,这可防止需要修改该状态的不同线程同时运行。

可能通过使用multiprocessing产卵实际进程加速它。每个进程都会在自己的解释器中运行,从而绕过线程的限制。通过多处理,您可以使用共享内存,也可以为每个进程分配自己的数据副本/分区。

根据您的任务,您可以通过对单个图像进行分区来并行处理,也可以并行处理图像列表(后者很容易使用pool完成)。如果您想使用前者,您可能需要将图像存储在可作为共享内存访问的Array中,但仍需解决写入结果的问题(写入共享内存会损害性能严重)。还要注意,进程之间的特定通信类型(队列,管道或模块中某些函数的参数/返回值传递)需要使用Pickle对数据进行序列化。这对数据施加了一定的限制,并可能造成显着的性能开销(特别是如果您有许多小任务)。

为提高此类操作的性能的另一种方法是尝试在Cython写他们,它有自己的support for parallelization使用OpenMP - 我从来没有使用过,虽然,所以我不知道多少的帮助可以。

+0

如果您需要处理图像(或你这样做需要大量计算能力的任何操作),那么你也应该看看GPU。 Python肯定支持它。 – freakish 2012-01-10 12:08:29

+0

由于@freakish建议,你应该使用[基于GPU(http://stackoverflow.com/a/8821745/462302)解决方案,为这类问题。你所说的GIL和多处理是正确的,但对图像处理仍然没有帮助。而且,当涉及到阵列处理I [推荐使用NumPy的](http://stackoverflow.com/a/8821745/462302),因为它被设计用于有效的阵列处理。 – aculich 2012-01-11 15:26:41

0

关于多处理,请看Doug Hellmans tutorial。正如Björn所指出的那样,在并行处理方面存在着各种各样的问题,您需要花费一些时间,但这确实值得付出努力。

提示:您可以使用multiprocessing.cpu_count()来检查可用的核心数量。

1

这里有图书馆,你会想探索做高效影像处理的列表:

OpenCV - 是的编程功能的实时计算机视觉和包含Python绑定图像处理库。

PyOpenCL允许您从Python访问GPU和其他大规模并行计算设备。

PyCUDA是姊妹项目PyOpenCL

NumPy and SciPy是这样做的科学计算,其可以是具有这样做有效的图像和阵列处理上述程序包有帮助基本包。

还要注意的是做图像处理多道库,有些人认为是不会帮助你有效地处理图像处理,所以你应该避免使用操作系统线程来做到这一点。如果由于某种原因,你需要做的粗粒度并行,那么你可以使用python library for MPI,但你可能想坚持GPU-based libraries