我很高兴得知xz
现在支持多线程:
xz --threads=0
但现在我想尽可能地利用它。例如,要将 gzip 重新压缩为 xz:
gzip -d -k -c myfile.gz | pv | xz -z --threads=0 - > myfile.xz
这导致我的处理器使用率更高(大约 260% CPU 到 xz,耶!)。
然而:
- 我意识到这
gzip
还不是多线程, - 我认为管道
pv
或管道可能限制(IO?)线程的数量。
这是真的吗?如果是的话,有没有办法提高效率(除了删除pv
)?
答案1
随着-T0
多线程选项,您可以一次告诉 xz 两件事。使用 MT 还意味着:等待直到所有输入(数据)被读入内存,然后开始“并行”压缩。
在纳入我的测试后,pigz
我会逐步分析性能;我有一个100M的文件f100
。
$ time xz -c f100 >/dev/null
real 0m2.658s
user 0m2.573s
sys 0m0.083s
99% 的时间都花在一个核心上的压缩上。使用-T4
(或-T0
)激活所有四个核心
$ time xz -c -T4 f100 >/dev/null
real 0m0.825s
user 0m2.714s
sys 0m0.284s
总体结果:速度提高 300%,每个核心几乎呈线性。 “用户”值必须除以 4,这是报告/定义的方式。 “sys”现在显示了一些开销——实际是 1/4 用户加上 sys 的总和。
$ time gzip -dc f100.gz >/dev/null
$ time pigz -p4 -dc f100.gz >/dev/null
这是 0.5 秒与 0.2 秒;当我把所有的放在一起时:
$ time pigz -dc -p4 f100.gz | xz -c -T4 >out.xz
real 0m0.902s
user 0m3.237s
sys 0m0.363s
...减少了 0.8 + 0.2 = 0.9。
和多个文件,但不要太多,您可以通过 4 个 shell 后台进程获得最高的总体并行度。这里我用四个25M的文件代替:
for f in f25-?.gz; do time pigz -p4 -dc "$f" | xz -c -T0 >"$f".xz & done
这看起来甚至更快了 0.7 秒。即使没有多线程,即使对于xz
:
for f in f25-?.gz; do time gzip -dc "$f" | xz -c >"$f".xz & done
只需使用 来设置四个简单的四分之一管道&
,您就可以获得 0.8 秒,与使用 . 来设置 100M 文件相同xz -T4
。
xz
在我的场景中,激活多线程与并行整个管道同样重要;如果你可以将它与 Pigz 和/或多个文件结合起来,你甚至可以比单个步骤总和的四分之一快一点。