我有一个函数,可以在将OCR应用于图像之后,获取图像列表并在列表中生成输出。我还有另一个功能,可以使用多重处理来控制该功能的输入。因此,当我只有一个列表(即没有多处理)时,列表中的每个图像大约要花1s,但是当我将必须并行处理的列表增加到4时,每个图像则要花13s的惊人时间。
要了解问题的根源,我尝试创建一个最小的问题工作示例。在这里,我有两个函数eat25
和eat100
,它们打开一个图像name
并将其提供给使用API pytesseract
的OCR。 eat25
做25次,eat100
做100次。
我的目的是在不进行多处理的情况下运行eat100
,而在进行多处理(具有4个进程)的情况下运行eat25
。从理论上讲,如果我有4个单独的处理器(我有2个内核,每个内核有2个线程,因此CPU = 4(如果我错了,请更正我)),时间应该比eat100
少4倍)。
但是,当我看到代码在打印4次“正在处理0”后甚至没有响应时,所有的理论都浪费了。单处理器功能eat100
可以正常工作。
我已经测试了一个简单的范围求值功能,并且在多处理中效果很好,所以我的处理器肯定可以正常工作。唯一的罪魁祸首可能是:
pytesseract
:请参见this `
from pathos.multiprocessing import ProcessingPool
from time import time
from PIL import Image
import pytesseract as pt
def eat25(name):
for i in range(25):
print('Processing :'+str(i))
pt.image_to_string(Image.open(name),lang='hin+eng',config='--psm 6')
def eat100(name):
for i in range(100):
print('Processing :'+str(i))
pt.image_to_string(Image.open(name),lang='hin+eng',config='--psm 6')
st = time()
eat100('normalBox.tiff')
en = time()
print('Direct :'+str(en-st))
#Using pathos
def caller():
pool = ProcessingPool()
pool.map(eat25,['normalBox.tiff','normalBox.tiff','normalBox.tiff','normalBox.tiff'])
if (__name__=='__main__'):
caller()
en2 = time()
print('Pathos :'+str(en2-en))
那么,问题出在哪里呢?任何帮助表示赞赏!
编辑:
图像normalBox.tiff
可以找到here。如果人们能重现代码并检查问题是否仍然存在,我将感到很高兴。
答案 0 :(得分:2)
我是pathos
作者。如果您的代码需要1s
来串行运行,那么很可能在幼稚的进程中并行运行会花费更长的时间。处理朴素的进程并行会产生开销:
我建议您检查一些简单的方法来检查您的问题可能在哪里:
pathos.pools.ThreadPool
使用线程并行而不是进程并行。这样可以减少序列化和扩展池的一些开销。pathos.pools._ProcessPool
更改pathos
管理池的方式。如果没有下划线,pathos
会将池保持为单例状态,并且需要使用“终止符”来明确终止池。如果使用下划线,则删除池对象时池将死亡。请注意,您的caller
函数不是close
或join
(或terminate
)池。dill.dumps
尝试并行处理的元素之一来检查要序列化的数量。大型numpy
阵列之类的内容可能需要一段时间才能序列化。如果要传递的内容很大,则可以考虑使用共享内存数组(即multiprocess.Array
或numpy
数组的等效版本-另请参见:numpy.ctypeslib
)尽量减少每个流程之间传递的内容。后者需要更多工作,但是如果您有很多需要序列化的内容,则可以节省大量资金。没有共享的内存池,因此,如果需要走那条路由,则必须对单个multiprocess.Process
对象进行for循环。