2014-09-01 62 views
0

我需要在数据上运行一个相对较慢的外部程序几百万次。这个外部程序被称为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的答案)。现在,我需要花半年时间才能完成所有数据,这是不可接受的,而且我需要一些让我的程序更快的方法。

+1

'PROCESS_COUNT = mult.cpu_count()* 20'这是一个非常糟糕的主意。你的计算机不能同时执行超过cpu_count()CPU限制的任务,因此启动80个进程意味着浪费大量内存,并迫使你的操作系统进行上下文切换,从而为所有80个进程提供CPU时间。 – dano 2014-09-01 00:07:18

+0

我知道,但不幸的是我没有看到还有什么可以做的,并希望它能以某种方式加快速度。当你平行运行四个时,它也太慢了。 – Matt 2014-09-01 00:09:48

+1

“如果你平行运行四次,速度也会太慢。” - 开始不仅仅是合理的任务不会让它变得更快。 – 2014-09-01 00:13:55

回答

1

如果RNAup对于输入文件中的每一行都需要10-15分钟的时间,这里没有太多可以做的事情。 是瓶颈,而不是Python代码。将RNAup的工作扩展到所有可用的内核中是最好的,只需一台机器就可以加快速度,最多只需4个CPU内核即可。但是如果你有一百万双,你仍然在看10分钟x 250,000套运行。假设您无法使RNAup速度更快,那么您似乎需要使用Celery或其他一些分布式框架将此作品分发到多台计算机上。

+0

我刚刚意识到它实际上并不需要10-15分钟的时间,当你从命令行运行RNAup时,它只需要2到3分钟的时间。它可以并行运行它们,可能会降低它们的速度。 – Matt 2014-09-01 01:46:31

+0

如果'RNAup'已经被写入为多线程或内存密集型,同时运行的实例可能会显着降低它们的速度。否则,只要你一次没有运行超过'cpu_count'的'RNAup'实例,我就不会期望性能会有太大的下降。也许每个实例会稍微慢一点,但是通过在一个实例上运行四个实例可以提高速度,可以弥补它的不足。 – dano 2014-09-01 03:12:23