使用Python多处理降低执行速度

2024-05-17 03:42:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我可能有点过头了,但我正在用python开发一个小的生物信息学项目。我正在尝试并行化一个程序,该程序分析一个包含字符串集的大字典(RAM中为~2-3GB)。我发现多处理版本在我使用较小的字典时速度更快,但是对于大型字典则没有什么好处,而且大多数情况下速度较慢。我的第一个理论是内存不足会减慢一切,而瓶颈是从交换到虚拟内存。但是,我在一个有4*48GB内存的集群上运行这个程序,同样的速度减慢了。我的第二个理论是对某些数据的访问被锁定了。如果一个线程正在尝试访问另一个线程中当前正在访问的引用,该线程是否必须等待?我试着复制我想操作的词典,但那似乎效率极低。还有什么会导致我的问题?在

我的多重处理方法如下:

def worker(seqDict, oQueue):
     #do stuff with the given partial dictionary
     oQueue.put(seqDict)
oQueue = multiprocessing.Queue()
chunksize = int(math.ceil(len(sdict)/4)) # 4 cores
inDict = {}
i=0
dicts = list() 
for key in sdict.keys():
    i+=1
    if len(sdict[key]) > 0:
        inDict[key] = sdict[key]
    if i%chunksize==0 or i==len(sdict.keys()):
        print(str(len(inDict.keys())) + ", size")
        dicts.append(copy(inDict))
        inDict.clear()

for pdict in dicts:
    p =multiprocessing.Process(target = worker,args = (pdict, oQueue)) 
    p.start()
finalDict = {}

for i in range(4):
    finalDict.update(oQueue.get())
return finalDict

Tags: keyin程序forlen字典keys理论
3条回答

通过队列的每个数据都将使用pickle进行序列化和反序列化。我想这可能是一个瓶颈,如果你通过大量的数据轮。在

您可以减少数据量,利用共享内存,在c扩展中编写多线程版本,或者使用python的多线程安全实现尝试多线程版本(可能是jython或pypy;我不知道)。在

哦,顺便说一句:您使用的是多处理而不是多线程。在

正如我在评论中所说的,以及Kinch在他的回答中所说的,传递给子流程的所有内容都必须经过pickle和unpickle,以便在派生的流程的本地上下文中复制它。{{{2>在cd1}上创建的共享进程{2>应该使用该进程在cd1}上共享共享的进程。但是在处理共享对象的服务器通信步骤中,您仍然可能会遇到瓶颈。如果是这样的话,您就必须考虑简化数据,以便使用multiprocess.Array或{}的真正共享内存,或者查看{}来创建自定义数据结构,以便在进程之间共享。在

似乎“字符串集的大字典”中的数据可以重新格式化为可以存储在文件或字符串中的内容,从而允许您使用mmap模块在所有进程之间共享它。如果每个进程需要将数据转换回其他更可取的形式,那么每个进程可能会产生一些启动开销,但是可以通过向每个进程传递一些信息来最小化这一开销,这些信息指示它们应该在共享内存中对整个数据集的哪个子集进行处理,并且只重新构造该进程所需的部分。在

相关问题 更多 >