2014-09-01 90 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