前言
在做視頻編碼的時(shí)候纵刘,之前有一個(gè)求圖像二維熵的函數(shù)是簡(jiǎn)單粗暴的利用數(shù)組來(lái)統(tǒng)計(jì)頻率的腻豌,感覺(jué)遍歷一個(gè)256*256的數(shù)組時(shí)間蠻長(zhǎng)的引谜,后面用map重寫了下,發(fā)現(xiàn)沒(méi)有減少什么時(shí)間疮茄,所以想精確的看看兩次代碼時(shí)間的差異滥朱,故學(xué)習(xí)下C++計(jì)時(shí)。
常規(guī)計(jì)時(shí)
- time()
函數(shù)名:time
頭文件:time.h
函數(shù)原型:time_t time(time_t *timer)
功能:獲取當(dāng)前的時(shí)間力试,返回的是一個(gè)time_t類型焚虱,即一個(gè)long int ,實(shí)際上懂版,再time.h里定義了time_t是這樣的:
typedef long time_t
返回的整數(shù)表示從CUT時(shí)間到當(dāng)前的秒數(shù)鹃栽,然后可以計(jì)時(shí),但是這個(gè)太不準(zhǔn)確躯畴,精度太低民鼓,故跳過(guò)。
- GetTickCount()
函數(shù)原型: DWORD GetTickCount(void)
功能:它返回一個(gè)DWORD類型的數(shù)據(jù)蓬抄,32位丰嘉,是操作系統(tǒng)啟動(dòng)到當(dāng)前的毫秒數(shù),值得注意的是嚷缭,它不是實(shí)時(shí)的發(fā)送饮亏,而是由系統(tǒng)每18ms發(fā)送一次耍贾,因此精度為18ms,故不滿足需求(實(shí)際上再測(cè)試的時(shí)候也發(fā)現(xiàn)這一點(diǎn)了路幸,精度為18ms,實(shí)際上操作一個(gè)10000的數(shù)組時(shí)間很短荐开,18ms精度毫無(wú)意義)
#include "stdafx.h"
#include<Windows.h>
#include<iostream>
using namespace std;
#define LEN 100000
int _tmain(int argc, _TCHAR* argv[])
{
DWORD tick = ::GetTickCount();
int tick1 = tick;
int data[LEN];
int i = 0;
for(i = 0;i<LEN;i++)
{
data[i] = i*i;
}
for(i = 0;i<LEN;i++)
{
data[i] = i*i;
}
for(i = 0;i<LEN;i++)
{
data[i] = i*i;
}
for(i = 0;i<LEN;i++)
{
data[i] = i*i;
}
for(i = 0;i<LEN;i++)
{
data[i] = i*i;
}
//這些循環(huán)基本上不會(huì)耗時(shí)18ms,故加入打印函數(shù)兩個(gè)tick才有顯示出差異
for(i = 0;i<50;i++)
{
cout<<data[i]<<" ";
}
DWORD tick2 = ::GetTickCount();
cout<<"tick1 is : "<<tick<<endl;
cout<<"tick2 is : "<<tick2<<endl;
return 0;
}
還有clock()函數(shù)等,但是精度較低就不考慮了
#include "stdafx.h"
#include<stdlib.h>
#include<time.h>
#include<iostream>
using namespace std;
#define LEN 100000
int main()
{
long j = 1000000L;
clock_t st,end;
st = clock();
//while(j--);
int data[LEN];
int i = 0;
for(i = 0;i<LEN;i++)
{
data[i] = i*i;
}
end = clock();
cout<<st<<" "<<end;
return 0;
}
//實(shí)際上简肴,在我的測(cè)試中晃听,操作一個(gè)100000的數(shù)組用時(shí)不需要1ms
//C++的效率比python高太多了,clock()函數(shù)的精度為1ms
使用CPU時(shí)間戳
在Intel Pentium以上級(jí)別的CPU中,提供了一條機(jī)器指令RDTSC(read time stamp counter)來(lái)讀取這個(gè)時(shí)間戳的數(shù)字砰识,記錄的是CPU上電以來(lái)經(jīng)過(guò)的時(shí)鐘周期數(shù)能扒,這個(gè)數(shù)字是保存在EDX:EAX寄存器中,可通過(guò)GetCycleCount()函數(shù)來(lái)獲取辫狼,實(shí)際上GetCycleCount函數(shù)是在KTimer.h封裝好的初斑,應(yīng)該是《Windows圖形編程》,否則很難直接操作膨处,但是我沒(méi)有找到這個(gè)庫(kù)越平,故另尋他法。
后面找到了一個(gè)計(jì)時(shí)的QueryPerformanceCounter灵迫,它也可以實(shí)現(xiàn)高精度的計(jì)時(shí)。
QueryPerformanceCounter返回的是計(jì)數(shù)值
QueryPerformanceFrequency返回的是計(jì)時(shí)的頻率
那么我們可以通過(guò)時(shí)間差除以頻率來(lái)獲得高精度的時(shí)間晦溪,精度取決于計(jì)時(shí)器的頻率瀑粥,
#include <windows.h>;
#include <stdio.h>;
int main()
{
int i =10000;
LARGE_INTEGER t1, t2, tc;
//獲取當(dāng)前計(jì)時(shí)器的頻率
QueryPerformanceFrequency(&tc);
printf("Frequency: %u\n", tc.QuadPart);
QueryPerformanceCounter(&t1);
while(i--);
QueryPerformanceCounter(&t2);
printf("Begin Time: %u\n", t1.QuadPart);
printf("End Time: %u\n", t2.QuadPart);
printf("Lasting Time: %u\n",( t2.QuadPart- t1.QuadPart));
return 0;
}
result:
Frequency: 10000000
Begin Time: 2586876488
End Time: 2586876632
Lasting Time: 144
//14.4us微秒