web-dev-qa-db-ja.com

パイプビューア-進行状況モニターのパフォーマンスへの影響

データのギグとギグを並べ替えるバッチスクリプトを書いています。すべてのデータはテキストですが、スクリプトの実行には長い時間がかかります。スクリプトが実行されていることを視覚的に示したいと思います。 pvというプログラムを見つけました。これを使用すると、進行状況バーやその他の素敵なCLI進行状況インジケーターを作成できます。

私の質問は、このようなことがパフォーマンスにどのような影響を与えるかということです。車輪の再発明をしなくても、他に選択肢はありますか。

私はそれをグーグルで殺しましたが、パフォーマンスが重要な長いタスクでのみ進行状況を示すと思うので、驚くべきことは何も見つかりませんでした。しかし、私はクロックサイクルを使用していると思います。また、進行状況の表示に数サイクルを使用しても問題がない場合に、ディスクI/Oまたはネットワークデータ転送を測定するために使用することもできます。

何か案は?

P.S. echo -neトリックを使用して独自のトリックを作成することも検討しましたが、それを実現するには、すべてのループで%演算子を使用し、100番目程度のループでのみアクションを実行する必要があります。無駄な計算がたくさん...

3
Dylan

通常、追加のIPC(ファイルを直接読み取る「主力」プロセスではなく、あるプロセスから別のプロセスにデータをコピーする)により、測定可能なオーバーヘッドが発生します(不足している ゼロコピー トリック)。パイプを使用すると、パフォーマンス(または機能)が失われる可能性があります その他の理由 :パイプ入力では、プロセスは入力でseek()できず、mmap()もできません。それ。

ただし、一般的に、パフォーマンスの主なボトルネックは、おそらくディスクI/OとCPUの計算時間です(これはおそらくあなたの場合は集中的です)。これらはIPCオーバーヘッドよりもはるかに大きい場合がありますが、ここには多く変数があります(CPUタイプ、ディスクタイプおよびファイルシステムタイプ、利用可能な物理RAM、OSとバージョン、libcとバージョン—少なくとも)。

いくつかの簡単なテストでパフォーマンスの大まかなアイデアを得ることができます。各テストの間に各テストの前にディスクキャッシュをフラッシュするように注意してください(私はLinuxを使用しています。 このメソッド を使用します)。

# time ( pv -pt somethinglarge.iso | sha256sum )
[...]
real    0m8.066s
user    0m5.146s 
sys     0m1.075s

# time ( sha256sum somethinglarge.iso )
[...]
real    0m7.913s
user    0m5.064s
sys     0m0.309s

同様の実時間とユーザー時間、および余分なコピーによるパイプケースのsystem時間の著しい増加に注意してください。

一部のOS、特にLinuxでは、次のように読み取ることができる場合があります /procからのプロセスごとのI/O統計(3.3を参照)CONFIG_TASKSTATSを有効にする必要がありますこのためのカーネル)。これはpvほど簡単でも巧妙でもありませんが、オーバーヘッドは少なくなります。 pidstatはこれを使用し、PIDのリアルタイムスループット(レート)を表示するために使用できますが、完了インジケーターとしてはあまり役に立ちません。

同様のLinuxオプション(これはCONFIG_TASKSTATSを必要としません)で、プロセスとファイル記述子が与えられると、/proc/PID/fdinfo/FDpos:フィールド)でファイル記述子のオフセットを追跡できます。これを示すおもちゃのスクリプトは次のとおりです。

FILE=/tmp/some-large-input
SZ=$(stat -c "%s" "$FILE")

# start slow process in background
( some-slow-command $FILE ) &
PID=$!
FD=/proc/$PID/fdinfo/3       # some experimentation required
# or iterate over /proc/$PID/fd/* with readlink 

# start %-ometer in background, exits when FD disappears
(
while nawk '/^pos:/{printf("%i\n",$2*100/'$SZ')}' $FD 2>/dev/null ; do
    sleep 5  # adjust
done | dialog --gauge "$PID: processing $FILE ($SZ bytes)" 10 60
) &

wait $PID
if [ $? -eq 0 ]; then
    echo 100 | dialog --gauge "$PID: completed $FILE ($SZ bytes)" 10 60
else 
    echo ...
fi

(警告:小さなファイルでは正確ではありません。libcs​​tdioバッファリングは結果を歪めます。)

今私に起こる他のオプション:

  • lsofを使用して プロセスのfdオフセットを監視する 正確には軽量ではありませんが、マルチプラットフォームであり、pvでは実行できない長時間実行プロセスで開始できます(どちらもきれいではありません) 、lsofはサイズとオフセットの両方を一度に与えることを拒否するため)

  • LD_PRELOADとデータの読み取り/書き込みを追跡するいくつかのスタブを使ったハックなもの、これもマルチプラットフォームですが、自分で作成する必要があると思います(これを正確に行うものはわかりませんが、ここにありますa 私の関連する答え

  • 更新:誰かがLinuxでcoreutilsコマンドで使用するための汎用転送モニターツールを書くのに苦労しました cv/procfdinfoアプローチと同様のロジックを使用します(上記のシェルハックで示されているように)。また、/ procをスキャンし、進行中の転送を検出すると報告するバックグラウンドモードもあります。関連する質問を参照してください cpの速度とコピーされた割合を確認することは可能ですか?

3
mr.spuratic

pvコマンドを使用する場合(主にzfsの送信および受信アクションを使用)、CPUに大きなオーバーヘッドはありません。まだ処理中であることを知りたい場合は、pvを使用してパイプで送られるデータをカウントできます。完了の推定時間を必要とする場合は、pv -s <SIZE>で処理されるデータの合計をカウントするプリコマンドを追加することをお勧めします。このような事前計算により、オーバーヘッドが発生する可能性があります。

1
Lambert