c# - Need some help in getting the CPU Frequency -


i'm trying make c# software reads information cpu , displays them user (just cpu-z). current problem i've failed find way display cpu frequency.

at first tried easy way using win32_processor class. proved efficient, except if cpu overclocked (or underclocked).

then, discovered registry contain @ hklm\hardware\description\system\centralprocessor\0 "standard" clock of cpu (even if overclocked). problem in modern cpus, core multiplier decreasing when cpu not need it's full power, cpu frequency changing, value in registry remains same.

my next step trying use rdtsc calculate cpu frequency. used c++ because can embed in c# project if method working. found next code @ http://www.codeproject.com/articles/7340/get-the-processor-speed-in-two-simple-ways problem same: program gives me maximum frequency (like in registry value, 1-2 mhz difference) , looks loads cpu more should (i had cpu load spikes).

#include "stdafx.h" #include <windows.h> #include <cstdlib> #include "intrin.h" #include <winerror.h> #include <winnt.h>  float procspeedcalc() {  #define rdtsc __asm _emit 0x0f __asm _emit 0x31      // variables clock-cycles:     __int64 cyclesstart = 0, cyclesstop = 0;     // variables high-res preformance counter:     unsigned __int64 nctr = 0, nfreq = 0, nctrstop = 0;      // retrieve performance-counter frequency per second:     if(!queryperformancefrequency((large_integer *) &nfreq))         return 0;      // retrieve current value of performance counter:     queryperformancecounter((large_integer *) &nctrstop);      // add frequency counter-value:     nctrstop += nfreq;       _asm     {// retrieve clock-cycles start value:         rdtsc         mov dword ptr cyclesstart, eax         mov dword ptr [cyclesstart + 4], edx     }      do{     // retrieve value of performance counter     // until 1 sec has gone by:          queryperformancecounter((large_integer *) &nctr);       }while (nctr < nctrstop);      _asm     {// retrieve again clock-cycles after 1 sec. has gone by:         rdtsc         mov dword ptr cyclesstop, eax         mov dword ptr [cyclesstop + 4], edx     }      // stop-start speed in hz divided 1,000,000 speed in mhz     return    ((float)cyclesstop-(float)cyclesstart) / 1000000; }   int _tmain(int argc, _tchar* argv[]) {      while(true)     {         printf("cpu frequency = %f\n",procspeedcalc());         sleep(1000);     }      return 0; } 

i should mention i've tested last method on amd cpu. i've tried other codes rdtsc method, none working correctly.

finally, i've tried understand code used make program https://code.google.com/p/open-hardware-monitor/source/browse/ , complex me.

so, question is: how determine cpu frequency in real-time (even when cpu overclocked) using c++ or c# ? know question asked lot of times, none answers question.

yes, code sits , busy-waits entire second, has causes core 100% busy second. 1 second more enough time dynamic clocking algorithms detect load , kick cpu frequency out of power-saving states. wouldn't surprised if processors boost show frequency above labelled frequency.

the concept isn't bad, however. have sleep interval of 1 second. then, instead of assuming rdtsc invocations 1 second apart, divide actual time indicated queryperformancecounter.

also, recommend checking rdtsc both before , after queryperformancecounter call, detect whether there context switch between rdtsc , queryperformancecounter mess results.


unfortunately, rdtsc on new processors doesn't count cpu clock cycles. doesn't reflect dynamically changing cpu clock rate (it measure nominal rate without busy-waiting, though, big improvement on code provided in question).

so looks you'd need access model-specific registers after all. can't done user-mode. the openhardwaremonitor project has both driver can used , code frequency calculations


float procspeedcalc() {     /*         rdtsc:           it's pentium instruction "read time stamp counter". measures           number of clock cycles have passed since processor reset,           64-bit number. that's <code>_emit</code> lines do.     */     // microsoft inline assembler knows rdtsc instruction.  no need emit.      // variables cpu cycle counter (unknown rate):     __int64 tscbefore, tscafter, tsccheck;     // variables performance counter 9steady known rate):     large_integer hpetfreq, hpetbefore, hpetafter;       // retrieve performance-counter frequency per second:     if (!queryperformancefrequency(&hpetfreq)) return 0;      int retrylimit = 10;         {         // read cpu cycle count         _asm         {             rdtsc             mov dword ptr tscbefore, eax             mov dword ptr [tscbefore + 4], edx         }          // retrieve current value of performance counter:         queryperformancecounter(&hpetbefore);          // read cpu cycle count again, detect context switch         _asm         {             rdtsc             mov dword ptr tsccheck, eax             mov dword ptr [tsccheck + 4], edx         }     } while ((tsccheck - tscbefore) > 800 && (--retrylimit) > 0);      sleep(1000);      {         // read cpu cycle count         _asm         {             rdtsc             mov dword ptr tscafter, eax             mov dword ptr [tscafter + 4], edx         }          // retrieve current value of performance counter:         queryperformancecounter(&hpetafter);          // read cpu cycle count again, detect context switch         _asm         {             rdtsc             mov dword ptr tsccheck, eax             mov dword ptr [tsccheck + 4], edx         }     } while ((tsccheck - tscafter) > 800 && (--retrylimit) > 0);      // stop-start speed in hz divided 1,000,000 speed in mhz     return (double)(tscafter - tscbefore) / (double)(hpetafter.quadpart - hpetbefore.quadpart) * (double)hpetfreq.quadpart / 1.0e6; } 

most compilers provide __rdtsc() intrinsic, in case use tscbefore = __rdtsc(); instead of __asm block. both methods platform- , compiler-specific, unfortunately.


Comments

Popular posts from this blog

html5 - What is breaking my page when printing? -

html - Unable to style the color of bullets in a list -

c# - must be a non-abstract type with a public parameterless constructor in redis -