データのギグとギグを並べ替えるバッチスクリプトを書いています。すべてのデータはテキストですが、スクリプトの実行には長い時間がかかります。スクリプトが実行されていることを視覚的に示したいと思います。 pv
というプログラムを見つけました。これを使用すると、進行状況バーやその他の素敵なCLI
進行状況インジケーターを作成できます。
私の質問は、このようなことがパフォーマンスにどのような影響を与えるかということです。車輪の再発明をしなくても、他に選択肢はありますか。
私はそれをグーグルで殺しましたが、パフォーマンスが重要な長いタスクでのみ進行状況を示すと思うので、驚くべきことは何も見つかりませんでした。しかし、私はクロックサイクルを使用していると思います。また、進行状況の表示に数サイクルを使用しても問題がない場合に、ディスクI/Oまたはネットワークデータ転送を測定するために使用することもできます。
何か案は?
P.S. echo -ne
トリックを使用して独自のトリックを作成することも検討しましたが、それを実現するには、すべてのループで%
演算子を使用し、100番目程度のループでのみアクションを実行する必要があります。無駄な計算がたくさん...
通常、追加の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/FD
(pos:
フィールド)でファイル記述子のオフセットを追跡できます。これを示すおもちゃのスクリプトは次のとおりです。
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
(警告:小さなファイルでは正確ではありません。libcstdioバッファリングは結果を歪めます。)
今私に起こる他のオプション:
lsof
を使用して プロセスのfdオフセットを監視する 正確には軽量ではありませんが、マルチプラットフォームであり、pv
では実行できない長時間実行プロセスで開始できます(どちらもきれいではありません) 、lsof
はサイズとオフセットの両方を一度に与えることを拒否するため)
LD_PRELOAD
とデータの読み取り/書き込みを追跡するいくつかのスタブを使ったハックなもの、これもマルチプラットフォームですが、自分で作成する必要があると思います(これを正確に行うものはわかりませんが、ここにありますa 私の関連する答え )
更新:誰かがLinuxでcoreutilsコマンドで使用するための汎用転送モニターツールを書くのに苦労しました cv 。 /proc
fdinfo
アプローチと同様のロジックを使用します(上記のシェルハックで示されているように)。また、/ procをスキャンし、進行中の転送を検出すると報告するバックグラウンドモードもあります。関連する質問を参照してください cpの速度とコピーされた割合を確認することは可能ですか?
pv
コマンドを使用する場合(主にzfsの送信および受信アクションを使用)、CPUに大きなオーバーヘッドはありません。まだ処理中であることを知りたい場合は、pv
を使用してパイプで送られるデータをカウントできます。完了の推定時間を必要とする場合は、pv -s <SIZE>
で処理されるデータの合計をカウントするプリコマンドを追加することをお勧めします。このような事前計算により、オーバーヘッドが発生する可能性があります。