欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解如何在C/C++中測(cè)量一個(gè)函數(shù)或功能的運(yùn)行時(shí)間

 更新時(shí)間:2023年12月03日 09:31:34   作者:zhonguncle  
本文算是一個(gè)比較完整的關(guān)于在 C/C++ 中測(cè)量一個(gè)函數(shù)或者功能的總結(jié),最后會(huì)演示三種方法的對(duì)比,文章通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下

最常用的clock()

最常用的測(cè)量方法是使用clock()來記錄兩個(gè) CPU 時(shí)間點(diǎn)clock_t,然后做差。這個(gè)方法的好處在于非常簡(jiǎn)單易寫,如下(第一行是為說明需要導(dǎo)入哪個(gè)庫(kù)):

#include <time.h>
.....

	clock_t begin = clock();

    ...需要被測(cè)量的代碼
    
    clock_t end = clock();
    int duration = (end - begin)/CLOCKS_PER_SEC;

需要注意 3 點(diǎn):

  1. CLOCKS_PER_SEC在 macOS 上是 1000000,也就是說(end - begin)的單位是微秒,所以要除以CLOCKS_PER_SEC。
  2. 不同平臺(tái)的clock_t類型是不一樣的,有些平臺(tái)是整數(shù)型,有些是使用浮點(diǎn)型。如果是浮點(diǎn)型的話,CLOCKS_PER_SEC或許可以不用寫,還是要看time.h的相關(guān)內(nèi)容。
  3. 這個(gè)方法中的“clock”一詞表示的是時(shí)鐘頻率,而不是時(shí)間。早期的計(jì)算機(jī)是固定頻率的(現(xiàn)在的一些計(jì)算器或者單片機(jī)其實(shí)也是固定頻率的),這個(gè)方法就是誕生于那個(gè)時(shí)間的。

這種方法最大的弊端就是它測(cè)量是 CPU 運(yùn)行時(shí)間,準(zhǔn)確的說是該進(jìn)程使用 CPU 的時(shí)間。這就導(dǎo)致了對(duì)于非 CPU 密集型程序來說,這個(gè)結(jié)果可能不是那么精確。當(dāng)然導(dǎo)致的最大的問題是并行計(jì)算程序得到的時(shí)間完全不對(duì),而且不能簡(jiǎn)單地使用核心數(shù)計(jì)算得到正確的時(shí)間。

因?yàn)檫@個(gè)方法是將多個(gè) CPU 的運(yùn)行時(shí)間加在一起了,串行計(jì)算的程序完全沒有問題,但是并行計(jì)算的話,CPU 使用率一般不會(huì)達(dá)到或接近核心數(shù)*100%,因?yàn)橛?jì)算機(jī)上還有其他任務(wù)也需要 CPU。比如說如果串行計(jì)算的程序使用率一般在 99% 左右,獲取時(shí)間為 30 秒,但是對(duì)于 6 核的設(shè)備上運(yùn)行的并行計(jì)算程序的話,CPU 使用率達(dá)到 570% 就很不錯(cuò)了,獲取的時(shí)間可能為 27 秒,而實(shí)際上只用了 5 秒。

這是我在使用 ISPC 編寫并行計(jì)算程序的時(shí)候發(fā)現(xiàn)的,所以我想尋找到新的方案,于是我發(fā)現(xiàn)了下一個(gè)方法。

timespec

timespec是一個(gè)簡(jiǎn)單的日歷時(shí)間或者時(shí)間流逝。通過使用日歷時(shí)間可以解決上一節(jié)中無法測(cè)量并行程序的實(shí)際運(yùn)行時(shí)間的問題。但是“簡(jiǎn)單”這點(diǎn)的表現(xiàn)為整數(shù)時(shí)間,也就是說最小的時(shí)間精度是秒,而不是上一種方法中的微秒,不過這對(duì)于復(fù)雜函數(shù)或程序的測(cè)試來說沒啥問題,畢竟 30 分鐘和 31 分鐘的性能差距不過 3.22%。

方法如下(第一行是為說明需要導(dǎo)入哪個(gè)庫(kù)):

#include <time.h>
	time_t begin = time(NULL);
	
	...需要被測(cè)量的代碼
    
    time_t end = time(NULL);
    int duration = (end - begin);

可以看到比上一種還要簡(jiǎn)單。

但是對(duì)于一些小型的測(cè)試來說,這個(gè)方法又不太行,因?yàn)檎麛?shù)帶來的誤差太大了,比如說 0.6 秒是 1.8 秒性能的三倍,但是在整數(shù)上只為 2 倍甚至是 1 倍(為什么有這個(gè)“甚至”等會(huì)演示可以看到),所以還是需要一個(gè)更精確時(shí)間測(cè)量方法,這個(gè)方法不光要適應(yīng)并行計(jì)算,還要有一定的精度。

clock_gettime()

clock_gettime()可以完美的符合要求,但是使用上有點(diǎn)復(fù)雜。

clock_gettime()是我從文檔的下面發(fā)現(xiàn)的。一開始我找到的是gettimeofday(),然后我去看了一下 IEEE 標(biāo)準(zhǔn)的文檔gettimeofday (opengroup.org),發(fā)現(xiàn)在“FUTURE DIRECTIONS(未來方向)”這一欄表示gettimeofday()可能未來會(huì)被廢棄;在“APPLICATION USAGE(應(yīng)用使用)”這一欄表示應(yīng)用應(yīng)該使用clock_gettime()而不是gettimeofday。這必須得使用clock_gettime()了。

clock_gettime()的復(fù)雜之處在于太精確了。先來看看使用方法(第一行是為說明需要導(dǎo)入哪個(gè)庫(kù)):

#include <time.h>
	struct timespec start;
    clock_gettime(CLOCK_REALTIME, &start);
	
	...需要被測(cè)量的代碼
    
    struct timespec end;
    clock_gettime(CLOCK_REALTIME, &end);
    
	double duration = (double)(end.tv_nsec-start.tv_nsec)/((double) 1e9) + (double)(end.tv_sec-start.tv_sec);

clock_gettime()的參數(shù)CLOCK_REALTIME表示系統(tǒng)層面的實(shí)時(shí)時(shí)間;這個(gè)地方還可以用CLOCK_MONOTONIC,這個(gè)值是從系統(tǒng)啟動(dòng)開始一直運(yùn)行的,一直連續(xù)的不跳躍的(除非手動(dòng)改了),這個(gè)要比CLOCK_REALTIME精度小一些,所以更快一些。

可以看到計(jì)算運(yùn)行時(shí)間的代碼,也就是時(shí)間差的表達(dá)式長(zhǎng)了很多,是因?yàn)閏lock_gettime()獲取的時(shí)間分為兩部分:秒和納秒(在某論壇上有人指出在曾經(jīng)的 Mac OS X 上這里是微秒,不確定,不過現(xiàn)在也是納秒了)。秒是int很簡(jiǎn)單的,但是納秒用的是long int,這就涉及到轉(zhuǎn)換的問題了。所以就需要分別計(jì)算兩個(gè)部分,轉(zhuǎn)換合成。

實(shí)際演示(三種方法的對(duì)比)

這里展示一段并行計(jì)算程序在三種測(cè)量時(shí)間方法下的對(duì)比,各位可以看看差別(可以推測(cè)出測(cè)試設(shè)備是 6C6T 的 CPU 哦):

可以看到有時(shí)差別還是挺大的。

以上就是詳解如何在C/C++中測(cè)量一個(gè)函數(shù)或者功能的運(yùn)行時(shí)間的詳細(xì)內(nèi)容,更多關(guān)于在C/C++中測(cè)量函數(shù)運(yùn)行時(shí)間的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論