최근에 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
답변
Windows (질문에 태그를 지정해야하는 경우)를 사용한다고 가정하면 이 MSDN 페이지HRTimer
에서 필요한 시스템 호출을 래핑 하는 간단하고 유용한 C ++ 클래스 의 소스를 찾을 수 있습니다. ( GetTicks()
특히 필요한 작업을 정확히 수행 하기 위해 메서드 를 추가하는 것은 쉽습니다 ).
비 Windows 플랫폼에는 QueryPerformanceCounter 함수가 없으므로 솔루션을 직접 이식 할 수 없습니다. 그러나 위에서 언급 한 것과 같은 클래스로 래핑 HRTimer
하면 현재 플랫폼이 실제로 제공 할 수있는 것을 사용하도록 클래스의 구현을 변경하는 것이 더 쉬울 것입니다 (아마도 Boost 등을 통해!).
답변
나는 시간을 얻는 것에 대한 NDIS 드라이버 예제로이 질문을 확장 할 것입니다. 아시다시피, KeQuerySystemTime (NdisGetCurrentSystemTime에서 모방)은 밀리 초 이상의 저해상도를 가지며 네트워크 패킷이나 더 나은 타임 스탬프가 필요할 수있는 기타 IRP와 같은 일부 프로세스가 있습니다.
예제는 다음과 같이 간단합니다.
LONG_INTEGER data, frequency;
LONGLONG diff;
data = KeQueryPerformanceCounter((LARGE_INTEGER *)&frequency)
diff = data.QuadPart / (Frequency.QuadPart/$divisor)
여기서 제수는 필요한 해상도에 따라 10 ^ 3 또는 10 ^ 6입니다.