#cpu #负载均衡器 #负载 #均衡器 #命令行界面

已删除 parallel

命令行CPU负载均衡器,用于并行执行作业

使用旧的Rust 2015

0.11.3 2017年6月9日
0.11.1 2017年1月31日
0.8.0 2016年12月30日
0.6.2 2016年11月12日

#8 in #均衡器

每月下载量 43次

MIT 许可证

155KB
3K SLoC

MIT/Rust 并行:用 Rust 编写的命令行 CPU 负载均衡器

Crates.io Tokei SLoC Count AUR OpenHub Statistics

这是在 Rust 和 MIT 许可证下重现 GNU Parallel(命令行的工作窃取器)功能的一种尝试。最终目标是支持 GNU Parallel 的大部分功能,然后扩展功能以用于 Rust 编写的下一代命令行工具。虽然功能很重要,但随着应用程序在 Rust 中开发,目标也是尽可能快和高效。

注意

请参阅 待办事项列表,以了解尚未完成的特性和改进。如果您想贡献,欢迎提交拉取请求。如果您有一个不在待办事项列表中的改进想法,请随时 给我发电子邮件,我会考虑实现该想法。

与 GNU Parallel 的基准比较

GNU Parallel

并行打印 1 到 10,000

~/D/parallel (master) $ seq 1 10000 | time -v /usr/bin/parallel echo > /dev/null
    User time (seconds): 194.73
    System time (seconds): 66.49
    Percent of CPU this job got: 230%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 1:53.08
    Maximum resident set size (kbytes): 16140

将 /usr/bin 中每个二进制文件的 内容连接起来

~/D/parallel (master) $ time -v /usr/bin/parallel cat ::: /usr/bin/* > /dev/null
    User time (seconds): 71.71
    System time (seconds): 27.67
    Percent of CPU this job got: 222%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:44.62
    Maximum resident set size (kbytes): 17576

记录 echo ::: $(seq 1 1000)

~/D/parallel (master) $ time -v /usr/bin/parallel --joblog log echo ::: $(seq 1 1000) > /dev/null
    User time (seconds): 21.27
    System time (seconds): 7.44
    Percent of CPU this job got: 238%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:12.05
    Maximum resident set size (kbytes): 16624

Rust Parallel(使用 MUSL 目标构建)

强烈建议使用 MUSL 编译 Parallel 而不是 glibc,因为这样可以将内存消耗减半并提高性能一倍。

并行打印 1 到 10,000

~/D/parallel (master) $ seq 1 10000 | time -v target/release/x86_64-unknown-linux-musl/parallel echo > /dev/null
    User time (seconds): 0.40
	System time (seconds): 2.53
	Percent of CPU this job got: 97%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:03.01
    Maximum resident set size (kbytes): 1768

将 /usr/bin 中每个二进制文件的 内容连接起来

~/D/parallel (master) $ time -v target/release/x86_64-unknown-linux-musl/release/parallel cat ::: /usr/bin/* > /dev/null
    User time (seconds): 1.07
	System time (seconds): 4.40
	Percent of CPU this job got: 191%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.86
    Maximum resident set size (kbytes): 1844

记录 echo ::: $(seq 1 1000)

~/D/parallel (master) $ time -v target/x86_64-unknown-linux-musl/release/parallel --joblog log echo ::: $(seq 1 1000) > /dev/null
    User time (seconds): 0.02
    System time (seconds): 0.28
    Percent of CPU this job got: 85%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.36
    Maximum resident set size (kbytes): 1768

语法示例

以下语法受支持

parallel 'echo {}' ::: *                          // {} will be replaced with each input found.
parallel echo ::: *                               // If no placeholders are used, it is automatically assumed.
parallel echo :::: list1 list2 list3              // Read newline-delimited arguments stored in files.
parallel echo ::: arg1 ::::+ list :::+ arg2       // Interchangeably read arguments from the command line and files.
parallel echo ::: 1 2 3 ::: A B C ::: D E F       // Permutate the inputs.
parallel echo '{} {1} {2} {3.}' ::: 1 2 file.mkv  // {N} tokens are replaced by the Nth input argument
parallel ::: "echo 1" "echo 2" "echo 3"           // If no command is supplied, the input arguments become commands.
parallel 'cd {}; echo Directory: {}; echo - {}'   // Commands may be chained in the platform\'s shell.
seq 1 10 | parallel 'echo {}'                     // If no input arguments are supplied, stdin will be read.
seq 1 10 | parallel --pipe cat                    // Piping arguments to the standard input of the given command.
#!/usr/bin/parallel --shebang echo                // Ability to use within a shebang line.

手册

Parallel 将非并行命令行任务并行化。当有多个需要执行且可能并行执行的命令时,Parallel 应用程序将均匀地将任务分配到所有可用的 CPU 内核。命令的提供有三种基本方法:

  1. 可以定义一个 A COMMAND,后跟一个 which,表示所有后续参数都将作为该命令的 INPUTS

  2. 如果没有提供 COMMAND,则将 INPUTS 解释为 COMMANDS

  3. 如果没有提供 INPUTS,则读取标准输入作为 INPUTS

Parallel 将每个子进程的标准输出和错误进行分组,以便按顺序打印输出,就像任务像传统 for 循环那样按顺序串行执行一样。此外,默认情况下,通过平台的默认 shell 执行命令,在 Unix 系统上是 sh -c,在 Windows 系统上是 cmd /C。这会带来性能成本,因此可以使用 --no-shell 选项禁用它。

输入模式

输入模式用于确定以下输入是包含输入的文件还是输入本身。包含输入的文件将每个输入存储在不同的行上,每行被视为一个完整的输入。当有多个收集到的输入列表时,每个单独的输入列表将一起排列成一个单独的列表。

  • :::

表示以下输入参数是输入参数。此外,这些参数将被收集到一个新的列表中。

  • :::+

表示以下输入参数是输入参数。此外,这些参数将被添加到当前列表中。

  • ::::

表示以下输入参数是包含输入的文件。此外,这些参数将被收集到一个新的列表中。

  • ::::+

表示以下输入参数是包含输入的文件。此外,这些参数将被添加到当前列表中。

输入令牌

命令通常以你在 shell 中通常的方式形成,只是用大括号中的占位符令牌(如 {}、{.}、{/}、{//} 和 {/}.)替换你的输入参数。如果没有提供令牌,则假定命令的最后一个参数将是 {}。这些令牌将对输入执行文本操作,以按照您喜欢的样式对其进行破坏。欢迎提供更多令牌的想法。

  • {}:每次出现都将被替换为输入的名称。
  • {.}:每次出现都将被替换为不带扩展名的输入。
  • {^abc...}:每次出现都将被替换为要删除的自定义后缀。
  • {/}:每次出现都将被替换为输入的基本名称。
  • {/.}:每次出现都将被替换为不带扩展名的基本名称。
  • {/^abc...}:每次出现都将被替换为删除自定义后缀的基本名称。
  • {//}:每次出现都将被替换为输入的目录名称。
  • {%}:每次出现都将被替换为槽位号。
  • {#}:每次出现都将被替换为作业号。
  • {##}:每次出现都将被替换为作业总数。
  • {N}:其中 N 是一个数字,显示关联的作业号。
  • {N.}:将从第 N 个作业中删除扩展名。
  • {N^abc...}:如果找到,则定义从第 N 个作业中删除的自定义后缀。
  • {N/}:显示第 N 个作业的基本名称(文件名)。
  • {N//}:显示第 N 个作业的目录名称。
  • {N/.}:显示不带扩展名的第 N 个作业的基本名称。
  • {N/^abc...}:显示删除自定义后缀的第 N 个作业的基本名称。

选项

还可以向程序提供选项以更改程序的操作方式

  • --delay:延迟 N 秒开始下一个作业,其中秒可以是分数。
  • --dry-run:将运行作业打印到标准输出,而不运行它们。
  • --eta:根据运行进程的平均运行时间打印估计完成时间。
  • -h--help:打印应用程序的手册(建议将其管道传输到 less)。
  • -j--jobs:定义并行运行的作业/线程数。
  • --joblog:将作业统计信息记录到指定的文件中,当它们完成时。
  • --joblog-8601:以 ISO 8601 格式写入开始时间:YYYY-MM-DD hh:mm:ss
  • --memfree:定义在开始下一个作业之前可用的最小内存量。
  • -n--max-args:将一定数量的参数组合在同一命令行中。
  • --num-cpu-cores:打印系统中的CPU核心数并退出。
  • -p--pipe:不是将参数作为子进程的参数提供,而是直接将参数提供给每个子进程的标准输入。
  • -q--quote:转义命令参数,以便保留空格、引号和斜杠。
  • -s--silent--quiet:禁用打印运行进程的标准输出。
  • --shebang:允许通过在shebang行中调用它,将并行命令作为解释器使用。
  • --shellquote:打印将要执行的命令,命令带有引号。
  • --tmpdir:定义用于临时文件的目录。
  • --timeout:如果命令运行时间超过指定的秒数,则使用SIGKILL将其终止。
  • -v--verbose:打印有关运行进程的信息。
  • --version:打印应用程序及其依赖项的当前版本。

实用示例

将FLAC音乐转码为Opus

ffmpeg是一个非常有用的应用程序,用于转换音乐和视频。然而,音频转码仅限于单核。如果您有一个大的FLAC存档,并且想要将其压缩为高效的Opus编解码器,即使使用最快的处理器也需要很长时间,除非您利用CPU的所有核心。

parallel 'ffmpeg -v 0 -i "{}" -c:a libopus -b:a 128k "{.}.opus"' ::: $(find -type f -name '*.flac')

将视频转码为VP9

VP9在编码方面有一个明显的缺陷:在任何给定时间点它只能使用大约三个核心。如果您有一个八核处理器和一打或更多的电视剧集要转码,您可以使用并行程序同时运行三个任务,前提是您也有足够的内存。

vp9_params="-c:v libvpx-vp9 -tile-columns 6 -frame-parallel 1 -rc_lookahead 25 -threads 4 -speed 1 -b:v 0 -crf 18"
opus_params="-c:a libopus -b:a 128k"
parallel -j 3 'ffmpeg -v 0 -i "{}" $vp9_params $opus_params -f webm "{.}.webm"' ::: $(find -type f -name '*.mkv')

安装说明

您可以使用多种方法安装应用程序。我提供了AMD64系统的二进制包,可供下载。

Gentoo

我有一个个人Gentoo layman overlay,它提供此应用程序以供安装。

Arch Linux

Arch Linux用户可以从AUR获取PKGBUILD。

其他所有人

rustup component add x86_64-unknown-linux-musl
wget https://github.com/mmstick/parallel/archive/master.zip
unzip master.zip
cd parallel-master
cargo build --release --target x86_64-unknown-linux-musl
sudo install target/x86_64-unknown-linux-musl/release/parallel /usr/local/bin/parallel

依赖关系

~1–1.4MB
~25K SLoC