2008-09-26 8 views
7

Win32에서는 고유 한 CPU 사이클 수 또는 여러 프로세스/언어/시스템/등의 유니폼이 비슷한 비슷한 방법이 있습니까?Win32에서 CPU주기 수를 얻으려면 어떻게해야합니까?

우리는 .NET 런타임을 호스팅하기 때문에 일부 로그 파일을 생성하지만 여러 로그 파일을 생성해야하므로 하나에서 다른 하나를 호출하여 호출하지 않도록하십시오. 따라서 필자는 두 개의 파일을 만들어서 결합한 다음 정렬하여 교차 - 외침 호출과 관련된 일관된 타임 라인을 얻는다고 생각했습니다.

그러나 GetTickCount는 모든 호출에 대해 증가하지 않으므로 신뢰할 수 없습니다. 더 좋은 전화 번호가 있습니까? 그러면 정렬 할 때 올바른 순서로 전화를받을 수 있습니까?


편집 : 속임수를 썼는지 QueryPerformanceCounter에에 트랙에 저를 넣어 @Greg 감사합니다.

답변

8

RDTSC CPU 명령어 (x86 가정)를 사용할 수 있습니다. 이 명령은 CPU주기 카운터를 제공하지만 최대 값까지 빠르게 증가한 다음 다시 0으로 리셋됩니다. Wikipedia 기사에서 언급 한 것처럼 QueryPerformanceCounter 함수를 사용하는 것이 좋습니다.

12

Heres an interesting article!은 RDTSC를 사용하지 말고 대신 QueryPerformanceCounter을 사용합니다.

결론 : 시스템 타이머의 입도가 10 ~ 15 밀리 초만큼 높을 수 있기 때문에 타이밍을 정기적 된 timeGetTime()를 사용

많은 Windows 기반 운영 체제 에 신뢰할 수 없습니다 즉, timeGetTime()은 10-15 밀리 초로 정확합니다. [ 높은 정밀도는 Windows NT, 2000 및 XP와 같은 NT 기반 운영 체제에서 발생합니다. Windows 95 및 98은 훨씬 더 세분화을 가지고 1-5 주위 밀리 을 경향이있다.]

그러나 ( 말과 timeEndPeriod(1)) 프로그램의 시작 부분에 timeBeginPeriod(1)를 호출하는 경우, timeGetTime() 보통 것 은 1-2 밀리 초까지 정확 해지고 이며 정확하게 정확한 타이밍 정보를 제공합니다.

Sleep()도 비슷하게 동작합니다. Sleep() 사실에 대한 을 자고있는 시간 는 timeGetTime()의 세분화과 손을 간다, 그래서 한 번 timeBeginPeriod(1)를 호출 한 후, Sleep(1) 실제로 1-2 밀리 초, 2-3 Sleep(2) 동안 잠, 그리고 것 따라서 을 켭니다 (자고있는 대신 부터 10-15 밀리 초).

높은 정밀 타이밍 (서브 밀리 초 정도)의 경우, 아마 하드 가를 보정 때문에 조립 니모닉 RDTSC를 사용하지 않도록 할 것; 대신 QueryPerformanceFrequencyQueryPerformanceCounter을 사용하십시오. 정확도는 이고 정확도는 10 마이크로 초 미만입니다 ( (0.00001 초)). 간단한 타이밍

, 모두 timeGetTime 와 QueryPerformanceCounter에는 잘 일을하고 QueryPerformanceCounter에 분명히 더 정확한 입니다. 그러나 경우 (예 : 프레임 속도를 제한하기 위해 필요한 것과 같은) "시간 제한 일시 정지"의 어떤 종류를 할 필요가, 당신은 특정 도달하는 기다리고 QueryPerformanceCounter에 전화 루프에 앉아 주의해야 값; 이 프로세서의 100 %를 먹을 것입니다. 는 대신, 다음 시간 이상 1 밀리 통과하고, 필요 ((1) 첫 번째! timeBeginPeriod을 잊지 마세요) 때마다에만 QueryPerformanceCounter에 입력하면 수면 (1)를 호출 하이브리드 방식을 고려 100 % -busy loop 마지막으로 끝내려면 < 초의 1/1000th 지연이 필요합니다. 이 은 매우 정확한 지연을 (정확도 10 마이크로 초), 매우 적은 CPU 사용량을 제공합니다. 위 코드 을 참조하십시오.

+3

timeBeginPeriod(); 시스템 전체 스케줄러에 영향을 미치고 에너지 절약 문제를 일으킬 수 있습니다. – MSalters

1

GetTickCount를 사용하고 로그 파일을 병합 할 때 다른 카운터를 추가하십시오. 서로 다른 로그 파일간에 완벽한 시퀀스를 제공하지는 않지만 적어도 각 파일의 모든 로그를 올바른 순서로 보관합니다.

+2

틱 수는 밀리 초 출력과 일치하여 증가하는 것 같습니다. 그래서 나는 좀 더 정확한 것을 필요로합니다. –

2

System.Diagnostics.Stopwatch.GetTimestamp()는 컴퓨터가 시작될 때 (아마도 컴퓨터가 시작되었을 때) (아마도 컴퓨터가 시작되었을 때) CPU주기의 수를 반환하며 2 회의 호출 사이에 증가하지 않는 것을 본 적이 없습니다.

CPU주기는 각 컴퓨터마다 다를 수 있으므로 두 대의 컴퓨터간에 로그 파일을 병합하는 데 사용할 수 없습니다.

+0

감사합니다. 같은 시간대에 동일한 컴퓨터에서 생성 된 파일 만 병합하기 때문에 작동합니다. 이제 그 메소드가 실제로 무엇을 호출하는지 알아야합니다 :) –

2

RDTSC 출력은 현재 코어의 클럭 주파수에 따라 달라질 수 있습니다. 이는 최신 CPU의 경우 일정하지 않으며 멀티 코어 컴퓨터에서 일정하지도 않습니다.

시스템 시간을 사용하고 여러 시스템의 피드를 처리하는 경우 NTP 시간 원본을 사용하십시오. 그렇게하면 신뢰할 수 있고 일관된 시간을 읽을 수 있습니다. 오버 헤드가 너무 많으면 HPET을 사용하여 HPET 만 사용하는 것보다 마지막으로 신뢰할 수있는 시간을 읽은 후 경과 된 시간을 처리하는 것이 좋습니다.