小さいブロックで試してみましたか?
自分のワークステーションで試してみると、ブロック サイズを下げると改善が見られることがわかりました。私のテストでは 10% の領域にすぎませんが、それでも改善されています。 100% を探しています。
さらにテストすると、本当に小さいブロックサイズでうまくいくようです:
やってみた
dd if=/dev/zero bs=32k count=256000 | dd of=/dev/null bs=32k
256000+0 records in
256000+0 records out
256000+0 records in
256000+0 records out
8388608000 bytes (8.4 GB) copied8388608000 bytes (8.4 GB) copied, 1.67965 s, 5.0 GB/s
, 1.68052 s, 5.0 GB/s
そしてあなたのオリジナルで
dd if=/dev/zero bs=8M count=1000 | dd of=/dev/null bs=8M
1000+0 records in
1000+0 records out
1000+0 records in
1000+0 records out
8388608000 bytes (8.4 GB) copied8388608000 bytes (8.4 GB) copied, 6.25782 s, 1.3 GB/s
, 6.25203 s, 1.3 GB/s
5.0/1.3 =3.8 なので、かなり大きな要因です。
Linux パイプは、ライターの書き込みの大きさに関係なく、一度に 4096 バイトしかリーダーに渡さないようです。
そのため、write(2) システム コールごとに 4096 バイト以上を既に詰め込まれたパイプに詰め込もうとすると、リーダーが必要な複数の読み取りを呼び出してパイプからその量のデータを引き出し、あらゆる処理を実行できるようになるまで、ライターが停止するだけです。
これは、マルチコアまたはマルチスレッド CPU (まだシングル コア、シングル スレッド、CPU を作っている人はいますか?) では、パイプライン内の各ライターに 4096 のみを書き込むことで、より多くの並列性を実現し、したがって経過クロック時間を短縮できることを示しています。一度にバイトずつ、次の 4096 ブロックを作成するために実行できるデータ処理または生成に戻る前に。