How to determine the hardware (CPU and RAM) on a machine?

前端 未结 13 1018
长发绾君心
长发绾君心 2020-12-31 03:29

I\'m working on a cross platform profiling suite, and would like to add information about the machine\'s CPU (architecture/clock speed/cores) and RAM(total) to the report of

13条回答
  •  温柔的废话
    2020-12-31 03:49

    The OP wants a CPU clock speed calculating routine portable between Windows and Linux. Here you go:

    #ifdef WIN32
    #define WIN32_LEAN_AND_MEAN
    #include 
    typedef unsigned __int64 usCount;
    static usCount GetUsCount()
    {
        static LARGE_INTEGER ticksPerSec;
        static double scalefactor;
        LARGE_INTEGER val;
        if(!scalefactor)
        {
            if(QueryPerformanceFrequency(&ticksPerSec))
                scalefactor=ticksPerSec.QuadPart/1000000000000.0;
            else
                scalefactor=1;
        }
        if(!QueryPerformanceCounter(&val))
            return (usCount) GetTickCount() * 1000000000;
        return (usCount) (val.QuadPart/scalefactor);
    }
    #else
    #include 
    #include 
    #include 
    typedef unsigned long long usCount;
    static usCount GetUsCount()
    {
    #ifdef CLOCK_MONOTONIC
        struct timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts);
        return ((usCount) ts.tv_sec*1000000000000LL)+ts.tv_nsec*1000LL;
    #else
        struct timeval tv;
        gettimeofday(&tv, 0);
        return ((usCount) tv.tv_sec*1000000000000LL)+tv.tv_usec*1000000LL;
    #endif
    }
    #endif
    static usCount usCountOverhead, CPUClockSpeed;
    #ifdef __GNUC__
    #include "x86intrin.h"
    #define __rdtsc() __builtin_ia32_rdtsc()
    #endif
    static usCount GetClockSpeed()
    {
      int n;
      usCount start, end, start_tsc, end_tsc;
      if(!usCountOverhead)
      {
        usCount foo=0;
        start=GetUsCount();
        for(n=0; n<1000000; n++)
        {
          foo+=GetUsCount();
        }
        end=GetUsCount();
        usCountOverhead=(end-start)/n;
      }
      start=GetUsCount();
      start_tsc=__rdtsc();
      for(n=0; n<1000; n++)
    #ifdef WIN32
        Sleep(0);
    #else
        sched_yield();
    #endif
      end_tsc=__rdtsc();
      end=GetUsCount();
      return (usCount)((1000000000000.0*(end_tsc-start_tsc))/(end-start-usCountOverhead));
    }
    

    Obviously this only works on x86/x64, and it relies on TSC counting at the same speed as the CPU. If you've done weird overclocking things e.g. on mine I overclock the FSB but downrate the multiplier to keep the core clock at spec, so TSC will count at FSB times the maximum multiplier which is too fast.

    To get the best results, before running GetClockSpeed() I'd suggest you run an anti-SpeedStep loop e.g.

    usCount start;
    start=GetUsCount();
    while(GetUsCount()-start<3000000000000ULL);
    CPUClockSpeed=GetClockSpeed();
    

    Niall

提交回复
热议问题