【问题标题】:Multiprocessing with external programs - speed of execution使用外部程序进行多处理 - 执行速度
【发布时间】:2014-10-25 04:25:17
【问题描述】:

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

【问题讨论】:

  • PROCESS_COUNT = mult.cpu_count() * 20 这是一个非常糟糕的主意。您的计算机一次只能执行cpu_count() CPU 密集型任务,因此启动 80 个进程仅意味着浪费大量内存并迫使您的操作系统进行上下文切换,以便为所有 80 个进程提供 CPU 时间。跨度>
  • 我知道,但不幸的是我没有看到还有什么可以做的,并希望它会以某种方式让它更快。当你只并行运行四个时,它也太慢了。
  • " 只并行运行四个也太慢了。" - 启动超过合理数量的任务不会神奇地让它更快。

标签: python c multiprocessing


【解决方案1】:

如果RNAup 真的要为输入文件中的每一行花费 10 到 15 分钟,那么您在这里无能为力。 是瓶颈,而不是 Python 代码。将RNAup 的工作分散到所有可用内核上是您可以做的最好的事情,以仅使用一台机器来加快速度,并且充其量意味着您将快 4 倍(假设有 4 个 CPU 内核)。但是如果你有 100 万双,你仍然在看 10 分钟 x 250,000 组跑步。假设您不能让RNAup 更快,听起来您需要使用Celery 或其他一些分布式框架将这项工作分布在多台机器上。

【讨论】:

  • 我刚刚意识到它实际上并不需要 10-15 分钟,从命令行运行 RNAup 只需要 2 到 3 分钟。并行运行它们可能会减慢它们的速度。
  • 如果RNAup 已经被编写为多线程或非常占用内存,并发运行实例可能会显着减慢它们的速度。否则,只要您一次运行的cpu_count 实例不超过RNAup,我就不会期望性能下降太多。也许每个实例会稍微慢一些,但同时运行四个实例所获得的速度会弥补这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
相关资源
最近更新 更多