使用“超线程”正确测量CPU使用情况
Correctly measure CPU usage with HyperThreading?
我知道SO上有几个关于如何使用以下两种方法之一测量CPU使用率的答案:
- 通过使用性能计数器(PDH API)
- 通过使用GetProcessTime()并将其除以墙时间或GetSystemTime()中的时间
几天来,我无法用这两种机制中的任何一种对我的程序进行CPU使用率测量,这两种方法的CPU使用率都小于任务管理器或Process Explorer中显示的。这些工具是如何做到这一点的?这与启用超线程有关吗?我将在没有HyperThring的CPU上进行测试,但如果有人能指出我在这里遗漏了什么,我将非常感谢。
为了说明我所尝试的,以下是进行基于PDH的测量的代码:
class CCpuUsageMonitor
{
public:
CCpuUsageMonitor(const wchar_t* pProcessName)
{
GetSystemInfo(&m_SystemInfo);
auto nStatus = PdhOpenQuery(NULL, NULL, &m_hPdhQuery);
_ASSERT(nStatus == ERROR_SUCCESS);
nStatus = PdhAddCounter(m_hPdhQuery, L"\Processor(_Total)\% Processor Time", NULL, &m_hPdhCpuUsageCounter);
_ASSERT(nStatus == ERROR_SUCCESS);
wchar_t pCounterPath[PDH_MAX_COUNTER_PATH];
StringCbPrintf(pCounterPath, PDH_MAX_COUNTER_PATH, L"\Process(%s)\%% Processor Time", pProcessName);
nStatus = PdhAddCounter(m_hPdhQuery, pCounterPath, NULL, &m_hPhdProcessCpuUsageCounter);
_ASSERT(nStatus == ERROR_SUCCESS);
}
~CCpuUsageMonitor()
{
PdhCloseQuery(&m_hPdhQuery);
}
void CollectSample()
{
auto nStatus = PdhCollectQueryData(m_hPdhQuery);
_ASSERT(nStatus == ERROR_SUCCESS);
}
double GetCpuUsage()
{
DWORD nType;
PDH_FMT_COUNTERVALUE CounterValue;
auto nStatus = PdhGetFormattedCounterValue(m_hPdhCpuUsageCounter, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, &nType, &CounterValue);
_ASSERT(nStatus == ERROR_SUCCESS);
return CounterValue.doubleValue;
}
double GetProcessCpuUsage()
{
DWORD nType;
PDH_FMT_COUNTERVALUE CounterValue;
auto nStatus = PdhGetFormattedCounterValue(m_hPhdProcessCpuUsageCounter, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, &nType, &CounterValue);
_ASSERT(nStatus == ERROR_SUCCESS);
return CounterValue.doubleValue / m_SystemInfo.dwNumberOfProcessors;
}
private:
SYSTEM_INFO m_SystemInfo;
HANDLE m_hPdhQuery;
HANDLE m_hPdhCpuUsageCounter;
HANDLE m_hPhdProcessCpuUsageCounter;
};
使用第二种方法,我基本上在代码运行前后通过GetProcessTime()获取两个进程时间的快照,根据墙时间乘以处理器数量进行减法和除法。
以下是我过去使用过的几个链接,以及一篇关于GetThreadTimes错误原因的好文章(我不会将其用作可靠的数据源):
http://blog.kalmbachnet.de/?postid=28
https://msdn.microsoft.com/en-us/library/aa392397(VS.85).aspx
http://www.drdobbs.com/windows/win32-performance-measurement-options/184416651
https://msdn.microsoft.com/en-us/library/aa394279(VS.85).aspx
你看起来很顺利,而且知识渊博,这些链接至少会让你朝着正确的方向前进。
从此链接:
从Windows 8开始,任务管理器和性能监视器报告CPU利用率的方式发生了变化。。。
此更改会影响CPU利用率的计算方式。任务管理器中的值现在对应于处理器信息\%Processor Utility和处理程序信息\%Privileged Utility能计数器,而不是像Windows 7中那样对应于处理器信息\%Processor Timerocessor Information \%Privilged Time计数器。
您的代码将按照编写的方式工作,而不是更改查询的计数器。您正在使用处理器计数器;您应该切换到在Windows 8中启用的处理器信息;并且还使用";"效用";计数器的版本。
如果您像当前一样查询格式化的值,那么通过1秒的轮询,您将在任务管理器上显示相同的数字。
如果要在较长的时间间隔内进行计算,可以查询原始值;将数字转换为CCD_ 1结构,而不是当前的CCD_。用于计算分子使用的值在PDH_RAW_COUNTER
结构的FirstValue
中;基本";分母的值在CCD_ 5中。
- 分别测量每个线程上花费的 CPU 时间(C++)
- C++从多线程 CPU 程序迁移到 GPU
- 如何测量一组特定线程的 CPU 时间?
- 线程SCHED_RR Posix 计时器使用的是 100% CPU
- 在MIDI播放线程上降低CPU
- C++多线程算法创建在同一 CPU 线程上运行的多个线程
- 我有 12 个 CPU,1 个插槽,每个插槽 6 个内核,每个内核 2 个线程 - 这些信息如何对应于 MPI 和 Op
- 如何在 Qt5 中设置线程的 CPU 关联?
- 我的CPU/OS可以处理多少个线程
- 超线程性能比较
- 我的多线程游戏始终为100%CPU.如何管理线程活动以减少CPU负载
- 即使使用睡眠,线程也不会放弃CPU时间
- 线程池正在占用所有CPU资源
- 在运行时查找特定线程的CPU核心
- 在每个主机线程(多线程 CPU)上创建一个 cuda 流
- 考虑 CPU 提升模式的多线程超线性性能实现
- 使用“超线程”正确测量CPU使用情况
- 如何决定是否使用超线程
- 多线程CPU到GPU使用CUDA 7.0/VS2012 c++ /CLI/OpenCV
- 如果已知访问顺序是安全的,如何在没有互斥锁的情况下同步线程/CPU