无法并行运行的程序

huangapple go评论76阅读模式
英文:

programs that can't run parallely

问题

I am building a python program to initiates the same program (benchmark_program in this example) with different parameters and then examine the results.

为了提高效率,我使用multiprocessing.Pool从多个子进程中调用多个命令以并行运行每个命令。然后奇怪的是:不管核心数(并行子进程数)增加到多少(仍然低于物理核心数,且所有核心都可用),总的测试时间保持不变,从htop中我发现每次脚本执行时只有1个核心实际上被使用(IO 也没有繁忙)。

起初我以为这是一个Python的问题,所以我写了一个简单的程序compute_primes来在一个单独的核心上进行一些重型计算,并行确实提高了性能。

所以我猜想在benchmark_program中可能有一些库,或许是一些只能被一个CPU调用的东西。现在我的问题是:是什么导致一个程序无法并行运行?是一些共享库或依赖关系吗?

测试脚本:

from multiprocessing import Pool
import subprocess
import time


def invoke_subprocess(arg):
    #command = "benchmark_program {}".format(arg)
    #command = "compute_primes {}".format(arg)

    command = "sleep 0.5"

    return subprocess.run(command,
                          shell=True,
                          check=True,
                          stdout=subprocess.DEVNULL,
                          stderr=subprocess.STDOUT).returncode


if __name__ == '__main__':
    for num_core in [2, 4, 8, 16]:
        start = time.time()
        with Pool(num_core) as p:
            collected_result = p.map(invoke_subprocess, range(16))
        print("core-{} took {:.2f} second".format(num_core,
                                                  time.time() - start))

这基本上是并行脚本。取消注释command = "sleep 0.5"并取消注释#command = "benchmark_program {}".format(arg),您将得到原始程序。

英文:

I am building a python program to initiates the same program (benchmark_program in this example) with different parameters and then examine the results.

To improve efficiency I invoke several subprocess from multiprocessing.Pool to run each command in parallel. Then the weird thing is: however core number (number of parallel subprocess) increase (still below the physical core number and all cores are available), the total test time remians constant and from htop I found that everytime the script executes, only 1 core is actually engaged (IO is not busy either).

At first I thought it's a python problem so I wrote a simple program compute_primes to do some heavy computation on 1 single cores, and parallelizing does improve performance.

So I guess there is something in benchmark_program, perhaps some libraries, that can be invoked/called by only 1 cpu at a time. Now my question is: what makes a program that can't be run parallely? Is it some shared libraries or dependences?

the test script:

from multiprocessing import Pool
import subprocess
import time


def invoke_subprocess(arg):
    #command = "benchmark_program {}".format(arg)
    #command = "compute_primes {}".format(arg)

    command = "sleep 0.5"

    return subprocess.run(command,
                          shell=True,
                          check=True,
                          stdout=subprocess.DEVNULL,
                          stderr=subprocess.STDOUT).returncode


if __name__ == '__main__':
    for num_core in [2, 4, 8, 16]:
        start = time.time()
        with Pool(num_core) as p:
            collected_result = p.map(invoke_subprocess, range(16))
        print("core-{} took {:.2f} second".format(num_core,
                                                  time.time() - start))

This is basically the parallel script. You get the original program when commenting command = "sleep 0.5" and uncomment #command = "benchmark_program {}".format(arg)

答案1

得分: 1

> 现在我的问题是:是什么使得一个程序无法并行运行?

有许多原因:

  • 该程序可以使用sched_setaffinity将自身绑定到单个CPU
  • 该程序可以使用flock锁定文件,阻止其他执行
  • 该程序可以创建一个信号量以实现相同的效果
  • 该程序可以创建一个“锁定文件”,第二次执行将等待直到该文件被移除。该文件也可以是Unix域套接字或命名管道。

可能有数十种不同的机制可用于防止并发执行。您可以使用strace来了解程序实际上是如何运行的,然后从那里开始。

英文:

> Now my question is: what makes a program that can't be run parallely?

Any number of things:

  • the program can bind itself to a single CPU using sched_setaffinity
  • the program can use flock to lock a file and prevent other executions of itself
  • the program can create a semaphore to achieve the same
  • the program can create a "lock file", and the second execution could wait until that file is removed. The file could also be a unix domain socket, or a named pipe.

There are probably tens of different mechanisms which could be used to prevent concurrent execution. You can use strace to figure out what the program actually does, and go from there.

huangapple
  • 本文由 发表于 2023年6月29日 11:48:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定