使用外部程序进行多处理 - 执行速度
问题描述:
我需要在数据上运行一个相对较慢的外部程序几百万次。这个外部程序被称为RNAup,这是一个确定两个RNA之间结合能的程序。在许多情况下,每个RNA-RNA对需要长达10到15分钟。这对于数百万行数据顺序运行来说太慢了,所以我决定通过尽可能并行运行程序来加速进程。但是,它仍然太慢。以下是我如何平行使用它:使用外部程序进行多处理 - 执行速度
import subprocess
import multiprocessing as mult
import uuid
def energy(seq, name):
for item in seq:
item.append([]) # adding new list to house the energy information
stdin = open("stdin" + name + ".in", "w")
stdin.write(item)
stdin.close()
stdin = open("stdin" + name + ".in", "r") # bug: this line is required to prevent bizarre results. maybe to slow down something? time.sleep()ing is no good, you must access this specific file for some reason!
stdout = open("stdout" + name + "out", "w")
subprocess.call("RNAup < stdin" + name + ".in > stdout" + name + ".out", shell=True) # RNAup call slightly modified for brevity and clarity of understanding
stdout.close()
stdout = open("stdout" + name + ".out", "r")
for line in stdout:
item[-1].append(line)
stdout.close()
return seq
def intermediate(seq):
name = str(uuid.uuid4()) # give each item in the array a different ID on disk so as to not have to bother with mutexes or any kind of name collisions
energy(seq, name)
PROCESS_COUNT = mult.cpu_count() * 20 # 4 CPUs, so 80 processes running at any given time
mult.Pool(processes=PROCESS_COUNT).map(intermediate, list_nucleotide_seqs)
我该如何显着提高程序的速度? (顺便说一下,我会接受涉及将部分,大部分或全部程序转移给C的答案)。现在,我需要花半年时间才能完成所有数据,这是不可接受的,而且我需要一些让我的程序更快的方法。
答
如果RNAup
对于输入文件中的每一行都需要10-15分钟的时间,这里没有太多可以做的事情。 是瓶颈,而不是Python代码。将RNAup
的工作扩展到所有可用的内核中是最好的,只需一台机器就可以加快速度,最多只需4个CPU内核即可。但是如果你有一百万双,你仍然在看10分钟x 250,000套运行。假设您无法使RNAup
速度更快,那么您似乎需要使用Celery或其他一些分布式框架将此作品分发到多台计算机上。
'PROCESS_COUNT = mult.cpu_count()* 20'这是一个非常糟糕的主意。你的计算机不能同时执行超过cpu_count()CPU限制的任务,因此启动80个进程意味着浪费大量内存,并迫使你的操作系统进行上下文切换,从而为所有80个进程提供CPU时间。 – dano 2014-09-01 00:07:18
我知道,但不幸的是我没有看到还有什么可以做的,并希望它能以某种方式加快速度。当你平行运行四个时,它也太慢了。 – Matt 2014-09-01 00:09:48
“如果你平行运行四次,速度也会太慢。” - 开始不仅仅是合理的任务不会让它变得更快。 – 2014-09-01 00:13:55