QueryPerformanceCounter를 사용하는 방법?
최근에 Timer 클래스를 밀리 초에서 마이크로 초로 변경해야한다고 결정했고, 몇 가지 조사 끝에 QueryPerformanceCounter가 아마도 가장 안전한 방법이라고 결정했습니다. ( Boost::Posix
Win32 API에서 작동하지 않을 수 있다는 경고 는 나를 약간 실망 시켰습니다.) 그러나 구현 방법을 잘 모르겠습니다.
내가하는 일은 GetTicks()
내가 사용 하는 esque 함수를 호출 하고 Timer의 startingTicks
변수에 할당하는 것 입니다. 그런 다음 경과 된 시간을 확인하기 위해에서 함수의 반환 값을 빼고 startingTicks
타이머를 재설정 할 때 함수를 다시 호출하고 startingTicks를 할당합니다. 불행히도 코드에서를 호출하는 것만 큼 간단 QueryPerformanceCounter()
하지 않으며 인수로 전달해야 할 내용이 확실하지 않습니다.
#include <windows.h>
double PCFreq = 0.0;
__int64 CounterStart = 0;
void StartCounter()
{
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li))
cout << "QueryPerformanceFrequency failed!\n";
PCFreq = double(li.QuadPart)/1000.0;
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
double GetCounter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart-CounterStart)/PCFreq;
}
int main()
{
StartCounter();
Sleep(1000);
cout << GetCounter() <<"\n";
return 0;
}
이 프로그램은 1000에 가까운 숫자를 출력해야합니다 (창 절전은 정확하지는 않지만 999와 같아야합니다).
이 StartCounter()
함수는 성능 카운터가 CounterStart
변수 에있는 틱 수를 기록합니다 . 이 GetCounter()
함수 StartCounter()
는 마지막으로 double로 호출 된 이후의 밀리 초 수를 GetCounter()
반환 하므로 0.001을 반환 하면 StartCounter()
호출 된 이후 약 1 마이크로 초 입니다.
타이머가 초를 대신 사용하도록하려면
PCFreq = double(li.QuadPart)/1000.0;
에
PCFreq = double(li.QuadPart);
또는 마이크로 초를 원한다면
PCFreq = double(li.QuadPart)/1000000.0;
그러나 실제로는 double을 반환하기 때문에 편리합니다.
이 정의를 사용합니다.
/** Use to init the clock */
#define TIMER_INIT \
LARGE_INTEGER frequency; \
LARGE_INTEGER t1,t2; \
double elapsedTime; \
QueryPerformanceFrequency(&frequency);
/** Use to start the performance timer */
#define TIMER_START QueryPerformanceCounter(&t1);
/** Use to stop the performance timer and output the result to the standard stream. Less verbose than \c TIMER_STOP_VERBOSE */
#define TIMER_STOP \
QueryPerformanceCounter(&t2); \
elapsedTime=(float)(t2.QuadPart-t1.QuadPart)/frequency.QuadPart; \
std::wcout<<elapsedTime<<L" sec"<<endl;
사용법 (재정의를 방지하는 대괄호) :
TIMER_INIT
{
TIMER_START
Sleep(1000);
TIMER_STOP
}
{
TIMER_START
Sleep(1234);
TIMER_STOP
}
사용 예의 출력 :
1.00003 sec
1.23407 sec
Assuming you're on Windows (if so you should tag your question as such!), on this MSDN page you can find the source for a simple, useful HRTimer
C++ class that wraps the needed system calls to do something very close to what you require (it would be easy to add a GetTicks()
method to it, in particular, to do exactly what you require).
On non-Windows platforms, there's no QueryPerformanceCounter function, so the solution won't be directly portable. However, if you do wrap it in a class such as the above-mentioned HRTimer
, it will be easier to change the class's implementation to use what the current platform is indeed able to offer (maybe via Boost or whatever!).
I would extend this question with a NDIS driver example on getting time. As one knows, KeQuerySystemTime (mimicked under NdisGetCurrentSystemTime) has a low resolution above milliseconds, and there are some processes like network packets or other IRPs which may need a better timestamp;
The example is just as simple:
LONG_INTEGER data, frequency;
LONGLONG diff;
data = KeQueryPerformanceCounter((LARGE_INTEGER *)&frequency)
diff = data.QuadPart / (Frequency.QuadPart/$divisor)
where divisor is 10^3, or 10^6 depending on required resolution.
참고URL : https://stackoverflow.com/questions/1739259/how-to-use-queryperformancecounter
'code' 카테고리의 다른 글
데몬의 Docker 오류 응답 : "충돌… 컨테이너에서 이미 사용 중" (0) | 2020.09.01 |
---|---|
열의 버튼, Click 이벤트 핸들러에서 가져온 행 가져 오기 (0) | 2020.09.01 |
C # 확장 메서드로 클래스를 확장하려면 어떻게해야합니까? (0) | 2020.08.31 |
TCP : 두 개의 다른 소켓이 포트를 공유 할 수 있습니까? (0) | 2020.08.31 |
루비, !! (0) | 2020.08.31 |