是否有任何工具可以并行化具有不同CPU要求的bash命令?

ric*_*iaw 2 parallel-processing bash

我正在寻找一种工具,使我能够并行化多个核心列表,每个核心命令都有不同的CPU要求.

例如,如果我有一台3核的机器,我有以下工作列表:

  1. 运行x(使用1个核心)
  2. 运行y(使用2个核心)
  3. 运行z(使用3个核心)

我想要并行运行命令的工具,但尊重我只有3个内核的事实,所以工作量看起来像

(empty),              (empty), (empty)
Job 1 (using 1 core), (empty), (empty)
Job 1 (using 1 core), Job 2 (using 2 cores)
Job 1 done,           Job 2 (using 2 cores)
(empty),              Job 2 (using 2 cores)
(empty),              Job 2 done
Job 3 (using 3 cores)
Run Code Online (Sandbox Code Playgroud)

Tec*_*e01 5

我的感觉是把这个答案分成两部分.a)Shell b)Docker并提供序言.

NB.原始问题涉及运行并行docker容器.然后,问题的范围被扩展到并行shell脚本的主题.

序言/警告

在具有N个处理元件的并行计算机上运行时,理想情况下的并行编程提供N倍加速.如果您阅读了Amdahl定律,您会注意到由于并行化任务所需的努力,这并不总是正确的.并行任务之间的任何相互依赖性将很快产生复杂性,并可能否定对操作进行并列化的努力.

Shell Scripting

如果您真的希望通过shell创建一组并行作业,我的个人建议是使用GNU Parallel.它提供了对CPU和线程属性的极细粒度控制.

它还附带了许多详细的代码示例.

模板示例:

让我们假设一个网站存储如下图像:

http://www.example.com/path/to/YYYYMMDD_##.jpg
Run Code Online (Sandbox Code Playgroud)

其中YYYYMMDD是日期,##是数字01-24.这将下载过去30天的图像:

  getit() {
    date=$(date -d "today -$1 days" +%Y%m%d)
    num=$2
    echo wget http://www.example.com/path/to/${date}_${num}.jpg
  }
  export -f getit

  parallel getit ::: $(seq 30) ::: $(seq -w 24)
Run Code Online (Sandbox Code Playgroud)

问题: "上述并行任务方法有什么问题? "

答:嗯,任务的并行性看起来很好,但是,性能现在受到网站IO带宽的限制......因此,太多并行任务可能导致整体任务完成速度变慢.

搬运工人

在docker run命令中,您可以定义可以使用约束CPU资源

--cpu=n

https://docs.docker.com/config/containers/resource_constraints/#configure-the-default-cfs-scheduler

下面的例子只是通过shell for循环结构启动一组(假定的)非依赖的docker容器.这是以并行方式运行一组非依赖容器的典型方法.注意:程序是串行启动但是独立运行,任何相互依赖都可以构建到docker IO通信背板中(即它们可以通过TCP进行通信)虽然坦白地说你正在进行关于你实际尝试的非常技术性的讨论与并行性有关.(小心,龙......)

示例模板

  1 #!/bin/bash
  2
  3 n="$1"
  4 if [[ "$n" == "" ]]; then
  5     echo "You did not specify number of parallel runs to launch. Defaulting to 10."
  6     n="10"
  7 fi
  8
  9 mkdir $PWD/openjdks
 10
 11 for i in $(seq 1 $n); do
 12         mkdir $PWD/openjdks/$i
 13         docker run -d\
 14            --name=<name>$i \
 15            --cap-add=SYS_ADMIN \
 16            --cpu=<number of CPU required> \
 17            -v $PWD/openjdks/$i:/tmp \
 18            -e DISTRO=centos \
 19            -r mirror \
 20            -filename java-1.6.0-openjdk-1.6.0.41-1.13.13.1.el7_3.x86_64.rpm \
 21            -path /tmp/java-1.6.0-openjdk-1.6.0.41-1.13.13.1.el7_3.x86_64.rpm \
 22            -log /tmp/mylog.log
 23 done
Run Code Online (Sandbox Code Playgroud)

我希望以上指出你正确的方向.