C言語計算時間関数&linux timeコマンドの出力における「real」「user」「sys」の本当の意味を理解する


コンパイル原理の実験が完了した場合、チェーンテーブルとハッシュテーブルでプログラムを共同で実行する時間に差があるかどうかを比較したい場合、最初に関数を使用するのは以下の通りです.
main()
{
  clock_t start = 0;   
  clock_t end = 0;   
  double time;
  int i;
  start = clock();   

  yylex();

  end = clock();   
  time = (double)(end - start)/CLOCKS_PER_SEC;/*#define CLOCKS_PER_SEC ((clock_t)1000)*/

  printf("
%fsecond
",time); }

でもプログラムが小さすぎて、時間が表示されるのは全部0.00000…Linuxで付けられる関数が調べられたので試してみましたが、
コマンドを使用:
time ./test.out

結果は次のとおりです.
real    0m0.026s
user    0m0.012s
sys    0m0.008s
以下に転載する記事では、timeに表示される「real」「user」「sys」の本当の意味を詳しく紹介します.
http://laiwei.net/2010/06/19/%E7%90%86%E8%A7%A3linux-time%E5%91%BD%E4%BB%A4%E7%9A%84%E8%BE%93%E5%87%BAwhat-do-real-user-and-sys-mean-2/
Linuxのtimeコマンドでは、あるプログラムの実行時間、ユーザー状態cpu時間、システム状態cpu時間を計算するためによく使用されます.
例:
$ time foo 
real        0m0.003s
user        0m0.000s
sys         0m0.004s$

では、この3つの時間は具体的にどういう意味ですか.
[1]real:fooプログラム全体の実行に時間がかかることを意味し、foo実行開始時刻に時計を見て、foo実行終了時に時計を見て、2回の時間の差が今回のrealが表す値であると理解できる
極端な例を挙げると、real timeはちょうど2秒であることがわかります.
# time sleep 2
real    0m2.003s user    0m0.000s
sys     0m0.000s
[2] user   0m0.000 s:この時間はfooがユーザー状態で実行されるcpu時間を表しています.どういう意味ですか.
まず、ユーザー・ステータスとコア・ステータスについて説明します.
コア状態(Kernel Mode):
カーネル状態では、コードは、下位ハードウェアにアクセスするための完全な制限を受けません.任意のCPUコマンドを実行し、任意のメモリアドレスにアクセスできます.カーネル状態は、通常、オペレーティングシステムによって提供される信頼性の高いコードの最下位レベルで実行されます.カーネル状態のコードクラッシュは、システム全体に影響を及ぼす災害的です.
       —– In Kernel mode, the executing code has complete and unrestricted access to the underlying hardware. It can execute any CPU instruction and reference any memory address. Kernel mode is generally reserved for the lowest-level, most trusted functions of the operating system. Crashes in kernel mode are catastrophic; they will halt the entire PC.
ユーザ状態(User Mode):
ユーザ状態では、コードはハードウェアまたはメモリに直接アクセスする能力を備えず、オペレーティングシステムが提供する信頼性の高い、最下位のAPIsを介してハードウェアまたはメモリにアクセスする必要がある.このような分離による保護作用により、ユーザー状態のコードがクラッシュし、システムが回復することができます.私たちのほとんどのコードはユーザー状態で実行されています.
      —– In User mode, the executing code has no ability to directly access hardware or reference memory. Code running in user mode must delegate to system APIs to access hardware or memory. Due to the protection afforded by this sort of isolation, crashes in user mode are always recoverable. Most of the code running on your computer will execute in user mode.
なぜKernel ModeとUser Modeを区別するのか:
分離保護により、システムがより安定します.
はい、ユーザー状態とコア状態を話した後、user timeを見てみましょう.これはプログラムfooがユーザー状態で実行されるcpu時間を指し、cpu時間は壁の時計が通った時間ではなく、CPUの動作時間を指します.
[3] sys   0m0.004 s:この時間はfooがコア状態で動作するcpu時間を表す.
 
はい、上記のことを話し終わったら、この3つの関係を見てみましょう.この3つの間には厳しい関係はありません.よくある誤解はあります.
エラー1:real_time = user_time + sys_time
我々の誤った理解は、real timeはuser time+sys timeに等しく、これは間違っている.real timeはクロックが通った時間であり、user timeはプログラムがユーザー状態のcpu時間であり、sys timeはプログラムがコア状態のcpu時間である.
この3つを用いて,プログラム実行中のcpu利用率を以下のように計算することができる.
%cpu_usage = (user_time + sys_time)/real_time * 100%
次のようになります.
# time sleep 2
real     0m2.003s user    0m0.000s
sys     0m0.000s
cpu利用率は0ですが、それ自体がそうなのでsleepは2秒、クロックは2秒経過しましたが、cpu時間はいずれも0なので利用率は0です
エラー2:real_time > user_time + sys_time
一般的には、上記は成立しており、上記の場合は単一cpuの場合、往々にして正しい.
しかし、マルチコアcpuの場合、しかもコードが書かれているのは確かにきれいで、マルチコアcpuをすべて利用することができるので、この場合上の関係は成立しません.例えば、次のような場合があるかもしれません.驚かないでください.
real 1m47.363s user 2m41.318s
sys 0m4.013s
エラー3:real_time < user_time + sys_time
一般的にこの落とし穴に侵入する人はいません^^
 
参考資料:timeの出力を理解する