C语言计算时间函数 & 理解linux time命令的输出中“real”“user”“sys”的真正含义

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuqingsongmsdn2014/article/details/87828797

#include <stdio.h>

int main()
{
    //int nums[10] = {4, 5, 2, 10, 7, 1, 8, 3, 6, 9};
    int nums[10] = {1, 2, 3, 10, 11, 12, 18, 23, 36, 49};
    int i, j, temp, isSorted;

    //优化算法:最多进行 n-1 轮比较
    for(i=0; i<10-1; i++)
    {
        //isSorted = 1; //假设剩下的元素已经排序好了
        for(j=0; j<10-1-i; j++)
        {
            if(nums[j] > nums[j+1])
            {
                temp = nums[j];
                nums[j] = nums[j+1];
                nums[j+1] = temp;
                isSorted = 0; //一旦需要交换数组元素,就说明剩下的元素没有排序好
            }
        }
        //if(isSorted) break; //如果没有发生交换,说明剩下的元素已经排序好了
    }

    for(i=0; i<10; i++)
    {
        printf("%d ", nums[i]);
    }

    printf("\n");

    return 0;
}

time maopao

real    0m0.026s
user    0m0.012s
sys    0m0.008s

Linux中time命令,我们经常用来计算某个程序的运行耗时,用户态cpu耗时,系统态cpu耗时。

例如:

 
  1. $ time foo

  2. real        0m0.003s

  3. user        0m0.000s

  4. sys         0m0.004s$

那么这三个时间都具体代表什么意思呢?

[1] real : 表示foo程序整个的运行耗时,可以理解为foo运行开始时刻你看了一下手表,foo运行结束时,你又看了一下手表,两次时间的差值就是本次real 代表的值

举个极端的例子如下:可以看到real time恰好为2秒。

# time sleep 2

real    0m2.003s

user    0m0.000s

sys     0m0.000s

[2] user   0m0.000s:这个时间代表的是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来访问硬件或者内存。由于这种隔离带来的保护作用,用户态的代码崩溃(Crash),系统是可以恢复的。我们大多数的代码都是运行在用户态的。

      —– 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.004s : 这个时间代表的是foo运行在核心态的cpu时间。

好,讲完上面的这些,我们来看看这三个的关系,这三者之间没有严格的关系,常见的误区有:

误区一: real_time = user_time + sys_time

       我们错误的理解为,real time 就等于 user time + sys time,这是不对的,real time是时钟走过的时间,user time 是程序在用户态的cpu时间,sys time 为程序在核心态的cpu时间。

利用这三者,我们可以计算程序运行期间的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

误区二:real_time > user_time + sys_time

一般来说,上面是成立的,上面的情况在单cpu的情况下,往往都是对的。

但是在多核cpu情况下,而且代码写的确实很漂亮,能把多核cpu都利用起来,那么这时候上面的关系就不成立了,例如可能出现下面的情况,请不要惊奇。

real 1m47.363s

user 2m41.318s

sys 0m4.013s

误区三:real_time < user_time + sys_time

一般来讲不会有人闯入这个误区^^

猜你喜欢

转载自blog.csdn.net/liuqingsongmsdn2014/article/details/87828797