私は、bashプログラムのさまざまな部分の処理を30秒から1秒未満に減らすためにコードを微調整しました。 time
、real
、およびuser
変数を報告するときにsys
コマンドがどのように機能するかについて、頭を悩ませています。
echo " "
echo "Time to build DirsNdxArr from DirsArr $DirsArrCnt elements:"
DirsArrCnt=${#DirsArr[@]}
time for (( i=1; i<$DirsArrCnt; i=i+$DaElementCnt )); do
DirsNdxArr["${DirsArr[$i]}"]=$i
AllItemSizes=$(( $AllItemSizes + ${DirsArr[$(( $i + $ColFileSizes - 1 ))]} ))
done
echo " "
echo "Time to build FilesNdxArr from FilesArr $FilesArrCnt elements:"
FilesArrCnt=${#FilesArr[@]}
time for (( i=0; i<$FilesArrCnt; i=i+$FaElementCnt )); do
FilesNdxArr["${FilesArr[$i]}"]=$i
AllTagSizes=$(( $AllTagSizes + ${FilesArr[$(( $i + $FaColFileSizes ))]} ))
done
Time to build DirsNdxArr from DirsArr 56700 elements:
real 0m0.149s
user 0m0.149s
sys 0m0.000s
Time to build FilesNdxArr from FilesArr 390 elements:
real 0m0.002s
user 0m0.002s
sys 0m0.000s
sys
時間はゼロを報告するのですか?time
ビルトインコマンドの出力を解釈すると、システムは何もしていないと想定されますが、これは実際には何も起きていません。
ps\n
は、-e
パラメーターを使用してecho
への改行として使用できることを知っています。私の習慣は、読みやすさを優先して、1つのライナーキュートさとフリンジ引数を犠牲にすることです。
要するに、プログラムが特権タスクの実行を要求しなかったことを意味します。したがって、CPUは特権(カーネル)モードで時間を費やしていません。
まず、time
の出力を適切に解釈するために理解する必要があるいくつかのことがあります。
time
コマンド(複数あるため)time
コマンドには2つのタイプがあります。 Shellビルトインと/usr/bin/time
があります。組み込みのシェルは、使用しているものであり、デフォルトで3行、real
、user
、およびsys
が表示されます。 time
のマニュアルにも、この同じ形式の出力が記載されています。
-p, --portability Use the following format string, for conformance with POSIX standard 1003.2: real %e user %U sys %S
また、「出力のフォーマット」セクションを確認すると、次のことがわかります。
E Elapsed real (wall clock) time used by the process, in [hours:]minutes:seconds. U Total number of CPU-seconds that the process used directly (in user mode), in seconds. S Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds.
このすべての情報から、CPUを実行できる2つのモード(ユーザーモードとカーネルモード)があり、time
コマンドは、プログラム/アプリがCPUに要求したことを実行するためにCPUが特定のモードに留まる時間を表示しますする。
それでは、違いは、コードを実行できるユーザーモードとカーネルモードがあるということです。これは、基本的に、プログラムがいくつかのタスクを実行するためにカーネルモードを使用しなかったことを意味することがわかります。それは実際にはどういう意味ですか?
この投稿 を参照してください:
カーネルモードでは、実行中のコードは、基盤となるハードウェアに完全かつ無制限にアクセスできます。任意のCPU命令を実行し、任意のメモリアドレスを参照できます。
そして、同じ投稿の別の回答から:
ユーザーモードからカーネルモードへの切り替えは、CPUによって自動的に行われません。 CPUが割り込み(タイマー、キーボード、I/O)によって割り込まれています。割り込みが発生すると、CPUは現在実行中のプログラムの実行を停止し、カーネルモードに切り替え、割り込みハンドラーを実行します。このハンドラーは、CPUの状態を保存し、その操作を実行して、状態を復元し、ユーザーモードに戻ります。
これが出力の意味です-カーネルモードへの切り替えはなく、CPUはプログラムから割り込みを受信しませんでした。これは、CPUからの昇格された特権を必要とするものがコードにないことも意味します
注:これはおそらく、malloc()
のようなものでメモリを割り当てるため、「カーネルモードへの長い/注目すべき切り替えはなかった」と言い換えるべきですCの関数はカーネルモードに切り替える必要がありますが、これらは微視的なスイッチであり、デバッガーまたはstrace
コマンドで実際に調査する必要があります。