none
How to get CPU speed when turbo boost enabled RRS feed

  • Question

  • Hi there,

    I have a system with two intel xeon 2.6Ghz CPU and they can run up to 3.6Ghz when turbo boost enabled.

    I am trying to get the CPU speed when it runs at 3.6Ghz using C# through WMI, but I get 2.6Ghz always.

    at the same time the task manager and CPU monitor from CPUID are able show the CPU speed correctly.

    does there anyone  know how to can I get the correct CPU speed (3.6Ghz) using C#?

    thanks.

    Saturday, July 27, 2019 11:40 AM

All replies

  • You can try with RDTSC

    =>

    ulong nFreq, nStartTime, nEndTime, nStart, nEnd, nDiffRDTSC, nDiffTime;
    if (QueryPerformanceFrequency(out nFreq))
    {                 
        IntPtr pAddress = IntPtr.Zero;
        if (IntPtr.Size == 4)
            pAddress = Alloc(RDTSC_32);
        else
            pAddress = Alloc(RDTSC_64); 
        pRDTSC = (RDTSC)Marshal.GetDelegateForFunctionPointer(pAddress, typeof(RDTSC));
        QueryPerformanceCounter(out nStartTime);
        nStart = pRDTSC();                   
        System.Threading.Thread.Sleep(100);
        QueryPerformanceCounter(out nEndTime);
        nEnd = pRDTSC();
    
        nDiffRDTSC = nEnd - nStart;
        nDiffTime = nEndTime - nStartTime;
        ulong nCPUFrequency = (ulong)(nDiffRDTSC / (((double)nDiffTime) / nFreq));
    
        Console.WriteLine("CPU Frequency : " + string.Format("{0:0.00###} GHz", nCPUFrequency / 1000000000.0f));
    
        if (IntPtr.Size == 4)
            VirtualFree(pAddress, (UIntPtr)RDTSC_32.Length, MEM_RELEASE);
        else
            VirtualFree(pAddress, (UIntPtr)RDTSC_64.Length, MEM_RELEASE);
    }

    with declarations =>

            [DllImport("Kernel32.dll", SetLastError = true)]
            public static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, uint flAllocationType, uint flProtect);
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            public static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, uint dwFreeType);
    
            public const uint PAGE_EXECUTE_READWRITE = 0x40;
            public const uint MEM_COMMIT = 0x1000;
            public const uint MEM_RELEASE = 0x00008000;
            static IntPtr Alloc(byte[] bytes)
            {
                var pAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)bytes.Length,  MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                Marshal.Copy(bytes, 0, pAddress, bytes.Length);
                return pAddress;
            }
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            public static extern bool QueryPerformanceFrequency(out ulong lpFrequency);
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            public static extern bool QueryPerformanceCounter(out ulong lpPerformanceCount);
            
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            public delegate ulong RDTSC();
            public static RDTSC pRDTSC;
            
            private static readonly byte[] RDTSC_32 = new byte[] {
                0x0F, 0x31,                     // rdtsc
                0xC3                            // ret 
            };
    
            private static readonly byte[] RDTSC_64 = new byte[] {
                0x0F, 0x31,                     // rdtsc 
                0x48, 0xC1, 0xE2, 0x20,         // shl rdx, 20h
                0x48, 0x0B, 0xC2,               // or rax, rdx 
                0xC3                            // ret 
            };



    • Edited by Castorix31 Sunday, July 28, 2019 9:26 PM
    Sunday, July 28, 2019 5:29 PM
  • ..................

    hi Castorix31,

    thanks but it does not work.

    as you can see the CPU base speed is 2.10GHz and it is now 2.93GHz now.

    but the reading value from read time stamp counter is still about 2.1GHz which is the same as from WMI.  



    • Edited by Serron Tuesday, July 30, 2019 1:06 PM
    Tuesday, July 30, 2019 1:04 PM
  • My processor doesn't support Turbo Boost, so I cannot do real tests.

    You can also try CallNtPowerInformation

    Test sample =>

    SYSTEM_INFO si = new SYSTEM_INFO();
    GetSystemInfo(out si);
    IntPtr pPROCESSOR_POWER_INFORMATION = IntPtr.Zero, pPROCESSOR_POWER_INFORMATIONOrig = IntPtr.Zero;
    uint nSize = (uint)(Marshal.SizeOf(typeof(PROCESSOR_POWER_INFORMATION)) * si.dwNumberOfProcessors);
    pPROCESSOR_POWER_INFORMATION = Marshal.AllocHGlobal((int)nSize);
    pPROCESSOR_POWER_INFORMATIONOrig = pPROCESSOR_POWER_INFORMATION;
    int nRet = CallNtPowerInformation(POWER_INFORMATION_LEVEL.ProcessorInformation, IntPtr.Zero, 0, pPROCESSOR_POWER_INFORMATION, nSize);
    if (nRet == 0)
    {
        PROCESSOR_POWER_INFORMATION ppi = new PROCESSOR_POWER_INFORMATION();
        for (int n = 0; n < si.dwNumberOfProcessors; n++)
        {
            ppi = (PROCESSOR_POWER_INFORMATION)Marshal.PtrToStructure(pPROCESSOR_POWER_INFORMATION, typeof(PROCESSOR_POWER_INFORMATION));
            Console.WriteLine("CPU : " + ppi.Number.ToString());
            Console.WriteLine("CPU Frequency (Current) : " + string.Format("{0:0.00###} GHz", ppi.CurrentMhz / 1000.0f));
            Console.WriteLine("CPU Frequency (Max) : " + string.Format("{0:0.00###} GHz", ppi.MaxMhz / 1000.0f));
            Console.WriteLine("CPU Frequency (Limit) : " + string.Format("{0:0.00###} GHz", ppi.MhzLimit / 1000.0f));
            pPROCESSOR_POWER_INFORMATION += Marshal.SizeOf(typeof(PROCESSOR_POWER_INFORMATION));
        }
    }
    Marshal.FreeHGlobal(pPROCESSOR_POWER_INFORMATIONOrig);  
    

    with declarations :

            [StructLayout(LayoutKind.Sequential)]
            public struct PROCESSOR_POWER_INFORMATION
            {
                public uint Number;
                public uint MaxMhz;
                public uint CurrentMhz;
                public uint MhzLimit;
                public uint MaxIdleState;
                public uint CurrentIdleState;
            }
    
            [DllImport("PowrProf.dll", SetLastError = true)]
            public static extern int CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel, IntPtr InputBuffer, uint InputBufferLength, IntPtr OutputBuffer, uint OutputBufferLength);
    
            public enum POWER_INFORMATION_LEVEL
            {
                SystemPowerPolicyAc,
                SystemPowerPolicyDc,
                VerifySystemPolicyAc,
                VerifySystemPolicyDc,
                SystemPowerCapabilities,
                SystemBatteryState,
                SystemPowerStateHandler,
                ProcessorStateHandler,
                SystemPowerPolicyCurrent,
                AdministratorPowerPolicy,
                SystemReserveHiberFile,
                ProcessorInformation,
                SystemPowerInformation,
                ProcessorStateHandler2,
                LastWakeTime,                                   // Compare with KeQueryInterruptTime()
                LastSleepTime,                                  // Compare with KeQueryInterruptTime()
                SystemExecutionState,
                SystemPowerStateNotifyHandler,
                ProcessorPowerPolicyAc,
                ProcessorPowerPolicyDc,
                VerifyProcessorPowerPolicyAc,
                VerifyProcessorPowerPolicyDc,
                ProcessorPowerPolicyCurrent,
                SystemPowerStateLogging,
                SystemPowerLoggingEntry,
                SetPowerSettingValue,
                NotifyUserPowerSetting,
                PowerInformationLevelUnused0,
                SystemMonitorHiberBootPowerOff,
                SystemVideoState,
                TraceApplicationPowerMessage,
                TraceApplicationPowerMessageEnd,
                ProcessorPerfStates,
                ProcessorIdleStates,
                ProcessorCap,
                SystemWakeSource,
                SystemHiberFileInformation,
                TraceServicePowerMessage,
                ProcessorLoad,
                PowerShutdownNotification,
                MonitorCapabilities,
                SessionPowerInit,
                SessionDisplayState,
                PowerRequestCreate,
                PowerRequestAction,
                GetPowerRequestList,
                ProcessorInformationEx,
                NotifyUserModeLegacyPowerEvent,
                GroupPark,
                ProcessorIdleDomains,
                WakeTimerList,
                SystemHiberFileSize,
                ProcessorIdleStatesHv,
                ProcessorPerfStatesHv,
                ProcessorPerfCapHv,
                ProcessorSetIdle,
                LogicalProcessorIdling,
                UserPresence,
                PowerSettingNotificationName,
                GetPowerSettingValue,
                IdleResiliency,
                SessionRITState,
                SessionConnectNotification,
                SessionPowerCleanup,
                SessionLockState,
                SystemHiberbootState,
                PlatformInformation,
                PdcInvocation,
                MonitorInvocation,
                FirmwareTableInformationRegistered,
                SetShutdownSelectedTime,
                SuspendResumeInvocation,
                PlmPowerRequestCreate,
                ScreenOff,
                CsDeviceNotification,
                PlatformRole,
                LastResumePerformance,
                DisplayBurst,
                ExitLatencySamplingPercentage,
                RegisterSpmPowerSettings,
                PlatformIdleStates,
                ProcessorIdleVeto,                              // Deprecated.
                PlatformIdleVeto,                               // Deprecated.
                SystemBatteryStatePrecise,
                ThermalEvent,
                PowerRequestActionInternal,
                BatteryDeviceState,
                PowerInformationInternal,
                ThermalStandby,
                SystemHiberFileType,
                PhysicalPowerButtonPress,
                QueryPotentialDripsConstraint,
                EnergyTrackerCreate,
                EnergyTrackerQuery,
                UpdateBlackBoxRecorder,
                PowerInformationLevelMaximum
            }
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
    
            [StructLayout(LayoutKind.Sequential)]
            public struct SYSTEM_INFO
            {
                public ushort wProcessorArchitecture;
                public ushort wReserved;
                public uint dwPageSize;
                public IntPtr lpMinimumApplicationAddress;
                public IntPtr lpMaximumApplicationAddress;
                public IntPtr dwActiveProcessorMask;
                public uint dwNumberOfProcessors;
                public uint dwProcessorType;
                public uint dwAllocationGranularity;
                public ushort wProcessorLevel;
                public ushort wProcessorRevision;
            }

    Wednesday, July 31, 2019 12:04 PM
  • hi Castorix31,

    I really appreciate your help here, after study the document from Intel.

    now, I did achieve how to get the this frequency correctly.

    My process is,

    1)read Bus speed (ExtClock) from WMI Win32_Processor class.

    2)read IA32_PERF_STATUS from MSR, get the data bit 15-8, this is frequency ratio

    3)Current Freq= ExtClock * IA32_PERF_STATUS[15:8] MHz

    Wednesday, August 21, 2019 1:06 AM