Linux下的函数执行时间的统计方法
如何测试某个函数的执行时间是做实验时经常用到的功能,在此比较Linux下的测试函数,主要是其精确度。我们采用统一的测试标准程序(standard.c):
#include <stdio.h>
#define MAX 1000 /* the loop count */
/* function: do loop operation
* input: NULL
* output: counter->the counter result
*/
int do_work()
{
int counter = 0; /* the counter */
int i, j; /* the loop variable */
/* accumulate the counter */
for(i = 0; i < MAX; i++)
for(j = 0; j < MAX; j++)
counter++;
/* return the counter's value */
return counter;
}
int main()
{
printf("counter = %d/n", do_work());
}
通过命令gcc -o standard standard.c生成测试程序。
Linux下的方法:
(1) 使用命令time:
[root@localhost-120 xgf]# time ./standard
counter = 1000000
real 0m0.006s
user 0m0.000s
sys 0m0.000s
time命令对秒(s)级别的很精确,而对毫秒级的误差比价大。我们可以通过sleep/usleep函数来进行测试。sleep(0.1)或者usleep(100)都是表示休眠100ms,而测试结果都是:
real 0m0.002s
user 0m0.000s
sys 0m0.000s
(2) 通过difftime函数:
double difftime(time_t time1, time_t time0);计算time1和time0之间的秒数。测试程序如下:
#include <stdio.h>
#include <time.h>
#define MAX 1000
int do_work()
{
int counter = 0; /* the counter */
int i, j; /* the loop variable */
/* accumulate the counter */
for(i = 0; i < MAX; i++)
for(j = 0; j < MAX; j++)
counter++;
/* return the counter's value */
return counter;
}
int main()
{
time_t start, end;
int val;
start = time(NULL);
do_work();
end = time(NULL);
printf("val = %f/n", difftime(end, start));
return 0;
}
测试结果如下:
val = 0.000000
real 0m0.006s
user 0m0.000s
sys 0m0.000s
我们发现,difftime的精确度还没有time命令高。
(3) 通过gettimeofday函数:
int gettimeofday(struct timeval *tv, struct timezone *tz); 其中timeval结构定义如下:
struct timeval
{
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
获取当前时刻,可以精确到微妙级别。
#include <stdio.h>
#include <sys/time.h>
#define MAX 1000 /* the loop count */
/* function: do loop operation
* input: NULL
* output: counter->the counter result
*/
int do_work()
{
int counter = 0; /* the counter */
int i, j; /* the loop variable */
/* accumulate the counter */
for(i = 0; i < MAX; i++)
for(j = 0; j < MAX; j++)
counter++;
/* return the counter's value */
return counter;
}
int main()
{
struct timeval start, end;
int interval;
gettimeofday(&start, NULL);
do_work();
gettimeofday(&end, NULL);
interval = 1000000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);
printf("interval = %f/n", interval/1000.0);
}
输出结果如下:
interval = 3.527000
real 0m0.006s
user 0m0.000s
sys 0m0.000s
也就是3.527ms。
(4) 利用rdtsc汇编指令,这是硬件计数器提供的功能,可以精确到1/f(f为处理器频率)。
#include <stdio.h>
#include <time.h>
#define MAX 1000
#define FREQUENCE 1595984000.00 /* the frequence of CPU */
int do_work()
{
int counter = 0; /* the counter */
int i, j; /* the loop variable */
/* accumulate the counter */
for(i = 0; i < MAX; i++)
for(j = 0; j < MAX; j++)
counter++;
/* return the counter's value */
return counter;
}
int main()
{
unsigned int start_high, start_low;
unsigned int end_high, end_low;
long long interval, start, end;
/* get the start time */
asm("rdtsc /n/t");
asm("movl %%eax, %0/n/t":"=g"(start_low));
asm("movl %%edx, %0/n/t":"=g"(start_high));
printf("start_high:/t%08X start_low:/t%08X/n", start_high, start_low);
start = start_high;
start = (start << 32) | start_low;
/* invoke the target function */
do_work();
/* get the end time */
asm("rdtsc /n/t");
asm("movl %%eax, %0/n/t":"=g"(end_low));
asm("movl %%edx, %0/n/t":"=g"(end_high));
printf("end_high:/t%08X end_low:/t%08X/n", end_high, end_low);
end = end_high;
end = (end << 32) | end_low;
/* count the interval time */
interval = end - start;
printf("lost time is:/t%llX %f/n", interval, (interval * 1000)/FREQUENCE);
return 0;
}
输出结果如下:
start_high: 00013272 start_low: A1081568
end_high: 00013272 end_low: A1600586
lost time is: 57F01E 3.611002
real 0m0.006s
user 0m0.000s
sys 0m0.000s
综上所述,time命令和difftime函数基本都是秒级别的,根本达不到毫秒级别的计数。而gettimeofday和rdtsc是很精确的方式,建议如果大家以后需要毫秒级别的计数采用gettimeofday或者rdtsc。
Linux下的函数执行时间的统计方法相关推荐
- linux下system函数的深入理解
这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...
- Linux下进程通信的八种方法
Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...
- linux系统调用劫持隐藏进程,linux 下隐藏进程的一种方法及遇到的坑
前言 1.本文所用到的工具在 https://github.com/gianlucaborello/libprocesshider 可以下载 2.思路就是利用 LD_PRELOAD 来实现系统函数的劫 ...
- Linux下curses函数库的详细介绍
Linux下curses函数库的详细介绍 curses库介绍 安装 curses库函数介绍 初始化和重置函数 管理屏幕的函数 输出到屏幕 从屏幕读取 清除屏幕 移动光标 字符属性 管理键盘的函数 键盘 ...
- Linux下connect函数 阻塞 与 非阻塞 问题
一.概述 linux系统下,connect函数是阻塞的,阻塞时间的长度与系统相关.而如果把套接字设置成非阻塞,调用connect函数时会报错Operation now in progress,且err ...
- Linux下分割与合并文件的方法
Linux下分割与合并文件的方法 切割合并文件在linux下用split和cat就可以完成.下面举些实例进行说明. 1.文件切割 文件切割模式分为两种: 文本文件 二进制模式. 1.1文本模式 文本模 ...
- [转]Linux下pppoe配合Drcom插件上网方法介绍......
Linux下pppoe配合Drcom插件上网方法介绍 近几天在西邮bbs上闲逛,无意间注意到很多人纠结于同一个问题---linux上网,众所周知,linux系统在宿舍上网时比较烦人的一件事,虽然bbs ...
- linux看php安装路径,linux下查找php安装路径的方法是什么
linux下查找php安装路径的方法是什么 发布时间:2020-09-01 16:06:19 来源:亿速云 阅读:72 作者:小新 这篇文章主要介绍了linux下查找php安装路径的方法是什么,具有一 ...
- linux下syscall函数,SYS_gettid,SYS_tgkill
出处:http://blog.chinaunix.net/uid-28458801-id-4630215.html linux下syscall函数,SYS_gettid,SYS_tgkill 2014 ...
最新文章
- 【深度学习】解析神经网络中的数值稳定性、模型初始化和分布偏移(Pytorch)
- QT的QGLFormat类的使用
- c语言结构体赋值,并输出各种类型变量的值
- java test使用手册,啄木鸟(woodpecker)自动化测试工具使用手册
- ACS——网管的九阳神功
- EPLAN导入EDZ文件
- STM8 GPIO输入输出模式
- ISBN 国际标准书号
- 如何画一块标准的PCB板?SMT工艺PCB要求
- 淘宝天猫价格监控接入方案
- 实现图片染色效果的三种方式
- 网站如何锁定用户,超级浏览器有办法解决吗?
- stm32 串口2空闲中断死机_STM32串口空闲中断问题
- 简单的模拟京东商城购买过程-pymysql
- 使用vue+electron创建桌面软件(二)
- 微信服务号自定义菜单添加扫码功能
- Browser --- 更换bookmark、homepage及常见问题
- 鸿蒙os官网2.0,鸿蒙 OS 2.0正式发布,看看用户体验评价,内附可升级型号名单!...
- 不让苹果开发者账号折磨我
- Python实战案例:高血压项目详解(上)