1. 程式人生 > >Linux下的函式執行時間的統計方法(測試某個函式的執行時間)

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位

linuxperforce(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/‘

linuxcan總線移植及測試總結

哪裏 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 本來我是想在同一片文章裡先寫協議簡介,然後寫

LinuxwineQQ國際版安裝方法

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