大量のデータをソートするためにバッチスクリプトを作成しています。すべてのデータはテキストですが、スクリプトの実行には時間がかかります。スクリプトが実行中であるという視覚的な表示を提供したいと思います。進行状況バーやその他の素晴らしい進捗状況インジケーターを pv
作成できるプログラムが見つかりました。CLI
私の質問は、このようなものがパフォーマンスにどのような影響を与えるのか、そして車輪を再発明する必要がない他の選択肢があるかどうかです。
私はそれを検索しましたが、パフォーマンスが重要な長期作業の進行状況のみを表示すると思ったので、驚くべきことが見つかりませんでした。しかし、私はクロックサイクルを使用していると思います。進行状況を表示するために使用されるサイクル数に関係なく、ディスクI / Oまたはネットワークデータ転送を測定するためにも使用できます。
どんなアイデアがありますか?
PS:私はこのecho -ne
トリックを使って独自のものを作成することを考えましたが、実現可能にするにはすべてのループで%
演算子を使用し、100番目のループでのみ作業を実行する必要がありますが、これは多くの作業になります。廃棄物の計算......
答え1
一般的に(不足)ゼロコピーファイルを直接読み取る「ワーカー」プロセス以外のプロセスから別のプロセスにデータをコピーすることは、追加のIPCのために測定可能なオーバーヘッドです。パイプラインはパフォーマンス(または機能)の損失を引き起こす可能性があります。その他の理由:パイプ入力の場合、プロセスはそのseek()
入力を使用したり使用したりすることはできませんmmap()
。
一般に、主なパフォーマンスボトルネックはおそらくディスクI / OとCPU計算時間(あなたの場合は集中的かもしれません)です。これはIPCよりもはるかに高価ですが、たくさんここにある変数(CPUタイプ、ディスクタイプそしてファイルシステムの種類、利用可能な物理RAM、オペレーティングシステムとバージョン、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
実際のユーザーと時間が似ており、大幅に増加した点をご覧ください。システム追加のコピーがパイプラインケースに費やされる時間。
一部のオペレーティングシステム、特にLinuxでは、以下を読むことができます。各プロセスの I/O 統計/proc
(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
(警告:小さなファイルの場合は正確ではありません。libc stdioバッファリングによって結果が歪む可能性があります。)
今念頭に置いている他のオプションは次のとおりです。
lsof
使用されるプロセスのfdオフセットを監視します。 まったく軽量ではありませんが、マルチプラットフォームであり、後に長期実行プロセスから始めることができますが、そうすることはできません(一度にサイズとバイアスを提供することを拒否するので、きれいpv
ではありません)。lsof
量)データの読み取り/書き込みを追跡するためのいくつかのハッキング項目と
LD_PRELOAD
いくつかのスタブ、これもマルチプラットフォームですが、自分で書く必要があるようです(正確にこれを行う項目はありませんが、ここに1つあります)。私の関連答え)修正する:誰かがユニバーサルトランスポート監視ツールを書くのに苦労しました。履歴書そして使用コアツールLinuxのコマンド。これは
/proc
fdinfo
この方法に似たロジックを使用します(上記のシェルハックに示されています)。また、/proc を検索して転送が見つかった場合、進行中の転送を報告するバックグラウンドモードもあります。関連質問を見るCPスピードとコピー率を見ることができますか?
答え2
このコマンドを使用した状況では、(主にzfsの送受信操作と共に)pv
CPUに多くのオーバーヘッドは発生しません。まだ処理中であるかどうかを知りたい場合は、pv
送信されたデータの数を計算できます。完了時間を見積もるには、処理するデータの合計を計算する辞書コマンドを追加できますpv -s <SIZE>
。この事前計算により、多少のオーバーヘッドが発生する可能性があります。