19

64ビットのCentOS6を使用して、あるアプリケーションから別のアプリケーションに非常に高速なデータをパイプしようとしています。次のベンチマークを使用ddして、プログラムのアルゴリズムではなく、パイプが私を妨げていることを発見しました。私の目標は、約1.5 GB/sを達成することです。

まず、パイプなし:

dd if=/dev/zero of=/dev/null bs=8M count=1000
1000+0 records in
1000+0 records out
8388608000 bytes (8.4 GB) copied, 0.41925 s, 20.0 GB/s

次に、2つのddプロセス間のパイプ:

dd if=/dev/zero bs=8M count=1000 | dd of=/dev/null bs=8M
1000+0 records in
1000+0 records out
8388608000 bytes (8.4 GB) copied, 9.39205 s, 893 MB/s

カーネルや、パイプを介してデータを実行するパフォーマンスを向上させるその他の調整を行うことができますか?名前付きパイプも試してみましたが、同様の結果が得られました。

4

2 に答える 2

6

小さいブロックで試しましたか?

自分のワークステーションで試してみると、ブロックサイズを小さくすると改善が続くことに気付きます。私のテストでは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なので、これはかなりの要因です。

于 2012-09-27T19:58:49.073 に答える
3

Linuxパイプは、ライターの書き込みの大きさに関係なく、リーダーに対して一度に4096バイトしか生成しないようです。

したがって、write(2)システムコールごとにすでに詰め込まれたパイプに4096バイト以上を詰め込もうとすると、リーダーがパイプからその量のデータを引き出して処理を行うために必要な複数の読み取りを呼び出すことができるまで、ライターは停止します。それはすることを念頭に置いています。

これは、マルチコアまたはマルチスレッドCPU(まだシングルコア、シングルスレッド、CPUを作成している人はいますか?)では、パイプラインの各ライターに4096のみを書き込むことで、並列処理を増やし、経過クロック時間を短縮できることを示しています。次の4096ブロックの作成に向けて実行できるデータ処理または本番環境に戻る前に、一度に1バイトずつ実行します。

于 2019-11-15T00:17:43.597 に答える