2012-07-09 5 views
2

Intel 칩 (2 페이지 http://www.intel.com/content/dam/doc/manual/64-ia-32-architectures-software-developer-vol-3b-part-2-manual.pdf)의 APERF/MPERF 카운터를 읽는 프로그램을 작성했습니다.하드웨어 프로세서 카운터가 잘못 재설정 됨

이 카운터는 readmsr/writemsr 명령을 통해 읽고 쓸 수 있으며 현재 Windows 7의 장치 드라이버를 통해 정기적으로 카운터를 읽는 중입니다. 카운터는 64 비트이며 각 프로세서 클럭마다 대략 증가합니다 , 그래서 당신은 그것들이 매우 오랜 시간에 오버플로 될 것이라고 기대할 것입니다. 그러나 카운터를 읽을 때, 다른 프로그램에 의해 리셋되는 것처럼 그 값은 뛰어납니다.

어떤 프로그램이 카운터를 재설정하는지 추적 할 수 있습니까? 뭔가 다른 값을 읽지 못하게 할 수 있습니까? 관련 어셈블리와 이에 상응하는 C 함수는 아래에 첨부되어 있습니다. rdmsr의 64 비트 결과는 eax : edx에 저장되므로 r_x 레지스터에 숫자가 누락되지 않았는지 확인하기 위해 명령을 여러 번 실행하여 모두 확인합니다.

C :

long long test1, test2, test3, test4; 
test1 = TST1(); 
test2 = TST2(); 
test3 = TST3(); 
test4 = TST4(); 
status = RtlStringCbPrintfA(buffer, sizeof(buffer), "Value: %llu %llu %llu %llu\n", test1, test2, test3, test4); 

어셈블리 :

;;;;;;;;;;;;;;;;;;; 
PUBLIC TST1 
TST1 proc 
    mov ecx, 231 ; 0xE7 
    rdmsr 
    ret ; returns rax 
TST1 endp 

;;;;;;;;;;;;;;;;;;; 
PUBLIC TST2 
TST2 proc 
    mov ecx, 231 ; 0xE7 
    rdmsr 
    mov rax, rbx 
    ret ; returns rax 
TST2 endp 

;;;;;;;;;;;;;;;;;;; 
PUBLIC TST3 
TST3 proc 
    mov ecx, 231 ; 0xE7 
    rdmsr 
    mov rax, rcx 
    ret ; returns rax 
TST3 endp 

;;;;;;;;;;;;;;;;;;; 
PUBLIC TST4 
TST4 proc 
    mov ecx, 231 ; 0xE7 
    rdmsr 
    mov rax, rdx 
    ret ; returns rax 
TST4 endp 

출력한다 그 결과는 다음과 같은 것입니다,하지만 지금 만 변경 레지스터는 RAX 레지스터이며,이 증가하지 않는다 단조롭게 (주위에 뛰어 넘을 수 있음) :

Value: 312664 37 231 0 
Value: 252576 37 231 0 
Value: 1051857 37 231 0 
+2

특정 CPU의 레지스터를 읽었습니까? 아니면 어느 것이 든 현재의 레지스터 중 무엇입니까? –

+0

좋은 지적입니다. 핵심 코드가 무엇이든지간에 코드를 실행하고 있습니다. (나는 i5와 i7 머신을 테스트 머신으로 사용하고있다.) 반면에, 나는 rdx 레지스터가 언제나 0이 아닌 CPU 중 하나에서 0 *에서부터 증가 할 것으로 기대합니다. – Shookit

+0

또한 하나의 특정 코어에서만 드라이버를 실행할 수 있습니까? – Shookit

답변

2

내 공동 작업을 재설정하는 것을 파악할 수 없었습니다. 그러나 나는 주파수를 결정할 수 있었다. Intel 카운터는 한 카운터가 오버플로되면 다른 카운터도 오버플로합니다. 따라서 카운터가 계속 재설정되는 경우에도 aperf와 mperf의 비율은 여전히 ​​프로세서의 빈도를 나타냅니다.

0

Windows 7 및 Windows 8은 AMD 프로세서에서 쓰기 가능한 APERF/MPERF 카운터를 읽고 재설정하는 것으로 보입니다. 따라서 0xc00000E7/E8 레지스터의 읽기 전용 APERF/MPERF 카운터에 액세스하려고합니다.

하지만 새로운 문제가 있습니다. 일부 최신 AMD 프로세서 (Family 0x16 프로세서)에서는 이러한 레지스터가 항상 지원되는 것은 아닙니다. 이러한 레지스터가 지원되는지 확인하려면 CPUID Fn8000_0007_EDX에서 EffFreqRO 비트를 읽어야합니다. 이전에 언급했듯이이 모든 것은 AMD 프로세서에만 적용됩니다.

관련 문제