Linux下的函式執行時間的統計方法(測試某個函式的執行時間)
重點:一般用 通過gettimeofday函式:
如何測試某個函式的執行時間是做實驗時經常用到的功能,在此比較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:
[[email protected] 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下的函式執行時間的統計方法(測試某個函式的執行時間)
重點:一般用 通過gettimeofday函式:如何測試某個函式的執行時間是做實驗時經常用到的功能,在此比較Linux下的測試函式,主要是其精確度。我們採用統一的測試標準程式(standard.c): #include <stdio.h>#define MA
Linux下安裝redis的安裝與測試執行詳細解析
redis中的安裝 生產環境一定在Linux下安裝 redis是c語言開發的,Linux有很多發行版,centos是紅帽的社群版,不收費 2:安裝包需要重新編譯 在Linux拿的安裝包就是原始碼,進行編譯,必須使用c語言的編譯環境,需要gcc線上安裝 如果是帶圖形介
32位的fortran函式庫在64位Linux下編譯及使用的方法
最近一直在使用一個數值函式庫。為了嘗試64位的精度,花了整夜折騰出些東西。 函式庫在32位Fedora下使用時,文件提供的例程的呼叫的都是以靜態庫方式呼叫的,使用g95編譯後,用ar 工具整理到了一個.a檔案。在64位的Fedora 13中,使用64位
linux下perforce(p4)的使用方法和命令
使用方法 open log bcd mman port 當前 包含 label 環境變量: export P4PASSWD=abcdefg export P4CLIENT=dyoldfish.com export P4USER=dyoldfish expor
Linux下批量重命名的方法
rename name 文件 -a 舉例 創建 doc tex 正則 rename 1.不過它要用 perl 正則表達式來作為參數, 2.舉例如下: touch test{1..5}.txt ##使用通配符創建5個文件 rename ‘s/\.txt/\.doc/‘
linux下can總線移植及測試總結
哪裏 ips sub 開關 switch 發現 開發 主機 編譯工具 Can移植及測試總結 Adding Flexcan driver support on Kernel 一.On kernel menuconfig, add the following items: [*
轉:Linux下用Jmeter做接口測試
接口 保存 ora cor tac 測試報告 cron 分享 添加 本地設計 首先在本地設計 Apache JMeter 測試計劃,大家可以參考《接口測試之 JMeter 初探》 ,這裏不再重復。 服務器配置 確保服務器已經安裝了JDK和Python。 在服
linux下的vi的使用方法
wid 當前 -s border 文件 設置 字符串 apple stripe vi的使用: 一般指令模式: vi打開一個文件就直接進入一般指令模式,可以進行刪除、復制、粘貼。但是不可以對文件的內容進行修改。 常用命令: ctrl + f向下移動一頁 ct
linux 下音訊的錄製與播放測試例子
main.c檔案 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "sndtools.h" int main(int argc, char const *argv[
Linux下強制殺死程序的方法
常規篇: 首先,用ps檢視程序,方法如下: $ ps -ef …… smx 1822 1 0 11:38 ? 00:00:49 gnome-terminal smx 1823 1822 0 11:38 ? 00:00:00 gnome-pty-helper smx 1824 1822
Linux下的crontab的使用方法
如果提示:-bash: crontab: command not found,表示沒有安裝crontab,需要手動安裝。 安裝crontab: 1. 確認crontab是否安裝: 執行 crontab 命令如果報 command not found,就表明沒有安裝 2.
linux下掛接NFS的方法
掛載NFS: 一.單板啟動完成後進行掛載NFS 設定方法: 1.sudo vim /etc/exports開啟配置檔案,在檔案末尾加上目標資料夾例如:/home/work/nfs_root/nano_root *(rw,sync,no_root_squash)
linux下修改IP地址的方法
1. 網絡卡的命名規則 在centos7中,en表示著:ethernet乙太網,即現在所用的區域網,enX(X常見有以下3種類型) 型別 說明 o 主機板板載網絡卡,整合裝置的裝置索引
Linux下搭建Redis叢集環境及測試叢集 關閉redis
Redis叢集環境 Redis叢集相關概念 各redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬,無主機,客戶端隨意連線一個節點都可以 節點的fail是通過叢集中超過半數的節點檢測失效才生效 (1)領
linux下掛載iso映象的方法
新建目錄/mnt/cdrom 執行命令 mount /dev/cdrom /mnt/cdrom 1.[[email protected] cdrom]# mount /dev/cdrom /mnt/cdrom 2.mount: /dev/sr
和 的區別 及 Linux下編譯iostream.h的方法
# g++34example.cpp In file included from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/backward/iostream.h:31, from main.cpp:8: /us
Linux下使用Jmeter進行分散式壓力測試
安裝JDK並配置環境變數 下載jmeter:http://jmeter.apache.org/download_jmeter.cgi linux下下載.tgz包 安裝配置jmeter:
Linux下安裝ROHC協議庫並測試
引言 關於ROHC協議的介紹我就不說了,詳見我的另一篇部落格《ROHC協議簡介》,地址如下: http://blog.csdn.net/u013793399/article/details/51425161 本來我是想在同一片文章裡先寫協議簡介,然後寫
Linux下wineQQ國際版安裝方法
winQQ國際版是UbuntuKylin給出的Linux下QQ替代方案,我比較推薦這種方法,簡單不折騰。 首先,到UbuntuKylin官網去下載winqq的安裝包,下載地址如下: winQQ國際版下載地址:http://www.ubuntukylin.com/applic
linux下新增新驅動的方法
下面以UCLINUX為例,介紹在一個以模組方式出現的驅動程式test.c基礎之上,將其編譯進核心的一系列步驟: (1) 改動test.c源帶程式碼 第一步,將原來的: #include #include char kernel_version[]=UTS_RELE