ランダムゴミを生成し、pv
次のように出力をパイピングして速度を比較するさまざまな方法をテストしています。
$ cmd | pv -s "$size" -S > /dev/null
私はまた、「リファレンスリファレンス」が欲しかったので、cat
最速のソースで最速の「ジェネレータ」を測定しました/dev/zero
。
$ cat /dev/zero | pv -s 100G -S > /dev/null
100GiB 0:00:33 [2,98GiB/s] [=============================>] 100%
3GB/秒、特に次のような場合は非常に印象的です。~70MB私はから来ました/dev/urandom
。
/dev/zero
しかし、特別な場合には必要ありませんcat
!ただ楽しんでこの教科書を消しました。ウルムチ大学:
$ < /dev/zero pv -s 100G -S > /dev/null
100GiB 0:00:10 [9,98GiB/s] [=============================>] 100%
何? ? ?ほぼ10GB/秒?解体cat
とパイプラインはどのように比較されますか?三回スピード?たとえば、遅いソースを使用している場合、/dev/urandom
違いは無視できます。魔法を呼ぶのでしょうかpv
?だからテストしました:
$ dd if=/dev/zero iflag=count_bytes count=200G of=/dev/null status=progress
205392969728 bytes (205 GB, 191 GiB) copied, 16 s, 12,8 GB/s
12.8GB/秒!パイプを使うのとほぼ同じでpv
、パイプを使うよりも4倍速いです。
あなた自身のせいですかcat
?パイプはリダイレクトとは大きく異なりますか?最後に、両方ともpv
asに移動しますstdin
。そうですか?この大きな違いを何で説明できますか?
答え1
秘訣は、2つのプロセスを使用することです。
同じcat | pv
、cat
読み取りと書き込み、pv
読み取りと書き込み、両方のプロセスを実行する必要があります。
$ perf stat sh -c 'cat /dev/zero | pv -s 100G -S > /dev/null'
100GiB 0:00:26 [3.72GiB/s] [====================================================================================>] 100%
Performance counter stats for 'sh -c cat /dev/zero | pv -s 100G -S > /dev/null':
34,048.63 msec task-clock # 1.267 CPUs utilized
1,676,706 context-switches # 0.049 M/sec
3,678 cpu-migrations # 0.108 K/sec
304 page-faults # 0.009 K/sec
119,270,941,758 cycles # 3.503 GHz (74.89%)
137,822,862,590 instructions # 1.16 insn per cycle (74.94%)
32,379,369,104 branches # 950.974 M/sec (75.14%)
216,658,446 branch-misses # 0.67% of all branches (75.04%)
26.865741948 seconds time elapsed
1.257950000 seconds user
38.893870000 seconds sys
専用pv
、pv
読み取り、書き込みのみ可能、コンテキスト切り替えは不要(またはほとんどありません):
$ perf stat sh -c '< /dev/zero pv -s 100G -S > /dev/null'
100GiB 0:00:07 [13.3GiB/s] [====================================================================================>] 100%
Performance counter stats for 'sh -c < /dev/zero pv -s 100G -S > /dev/null':
7,501.68 msec task-clock # 1.000 CPUs utilized
37 context-switches # 0.005 K/sec
0 cpu-migrations # 0.000 K/sec
198 page-faults # 0.026 K/sec
27,916,420,023 cycles # 3.721 GHz (75.00%)
62,787,377,126 instructions # 2.25 insn per cycle (74.99%)
15,361,951,954 branches # 2047.801 M/sec (75.03%)
51,741,595 branch-misses # 0.34% of all branches (74.98%)
7.505304560 seconds time elapsed
1.768600000 seconds user
5.733786000 seconds sys
いくつかの並列処理(「1.267 CPUを使用」)がありますが、コンテキスト切り替え数の大きな違いを補償するものではありません。
データパスを考慮すると、状況はおそらくはるかに悪いでしょう。最初の場合、データは/dev/zero
カーネル()からcat
カーネル(パイプの場合)に戻り、その後pv
カーネル(/dev/null
)に流れるように見えます。 2番目のケースでは、データはコアからコアに流れ、pv
再びコアに流れます。しかし、pv
最初のケースではsplice
カーネル所有メモリを通過しないようにパイプからデータをコピーします。