在Python + Python图像库脚本中,有一个名为processPixel(image,pos)的函数,它根据图像及其上的位置计算数学索引。使用简单的for循环计算每个像素的索引:
for x in range(image.size[0)):
for y in range(image.size[1)):
myIndex[x,y] = processPixel(image,[x,y])
这花费了太多时间。如何实现线程来分割加速它的工作?多线程代码的速度有多快?特别是,这是由处理器核心数量定义的吗?
答案 0 :(得分:6)
由于Global Interpreter Lock,您无法使用线程加快速度。 Python解释器的某些内部状态受该锁的保护,这可以防止需要修改该状态的不同线程同时运行。
您可以通过使用multiprocessing
生成实际流程来加快速度。每个进程都将在自己的解释器中运行,从而避免了线程的限制。使用多处理,您可以使用共享内存,也可以为每个进程提供自己的数据副本/分区。
根据您的任务,您可以通过对单个图像进行分区来并行处理单个图像,也可以并行处理图像列表(后者可以使用pool
轻松完成)。如果您想使用前者,您可能希望将图像存储在可以作为共享内存访问的Array
中,但您仍然必须解决写入结果的位置问题(写入共享记忆会严重损害表现。另请注意,进程之间的某些类型的通信(队列,管道或模块中某些函数的参数/返回值传递)需要使用Pickle序列化数据。这对数据施加了某些限制,并且可能会产生显着的性能开销(特别是如果您有许多小任务)。
另一种提高此类操作性能的方法是尝试在Cython中编写它们,它有自己的support for parallelization使用OpenMP - 我从来没有用过,所以我不知道多少帮助它。
答案 1 :(得分:1)
以下是您要探索的有效图像处理库的列表:
OpenCV - 是一个包含Python绑定的实时计算机视觉和图像处理的编程函数库。
PyOpenCL允许您从Python访问GPU和其他大规模并行计算设备。
的姊妹项目NumPy and SciPy是进行科学计算的基本软件包,可能有助于上述软件包进行高效的图像和数组处理。
另请注意,对于进行图像处理,某些人建议的多处理库不会帮助您有效地处理图像处理,因此您应该避免使用操作系统线程来执行此操作。如果由于某种原因你确实需要粗粒度并行,那么你可以使用python library for MPI,但你可能想要坚持使用GPU-based libraries。
答案 2 :(得分:0)
在多处理上查看Doug Hellmans tutorial。正如Björn指出的那样,关于并行处理存在各种各样的问题,您需要了解它们,但它确实值得付出努力。
提示:您可以使用multiprocessing.cpu_count()检查可用的核心数量。