首页 > 解决方案 > NtQuerySystemInformation 返回特定核心的否定结果 - 这是什么意思

问题描述

我正在尝试输出我机器上每个处理器的性能。我有两组,每组有 36 个处理器。我正在做这样的事情

PVOID WLAlloc(DWORD dwSize)
{
    PVOID pMem = nullptr;
    pMem = HeapAlloc(GetProcessHeap(),NULL,dwSize);
    return pMem;
}

void test()
{
    int numofGroups = 2;
    DWORD uSize = 2 * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
    PVOID pMem = WLAlloc(uSize);
    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*  m_pCoreUsageInfoArray = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)pMem;
    NTSTATUS status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, m_pCoreUsageInfoArray, uSize, NULL);
    if (status >= 0)
    {
        for (int i = 0; i < 72; i++) 
        {
            auto t = m_pCoreUsageInfoArray[i];
            std::cout << "Core: " << i << " Idle:" << t.IdleTime.QuadPart << " Kernel: " << t.KernelTime.QuadPart << " User :" << t.UserTime.QuadPart << std::endl;
        }
    }
}

我得到这个作为输出:

Core: 23 Idle:0 Kernel: -9223358841219038703 User :0

知道为什么我得到一个负数吗?

标签: c++multithreadingwinapi

解决方案


您只为 2 分配空间SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION,但随后您尝试迭代到索引 72,这是索引 2 及更高的未定义行为

您需要修复循环以仅迭代您预先分配的项目,或者首先查询实际大小并以适当的大小重试调用:

DWORD uSize = 0;

NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL, 0, &uSize);

PVOID pMem = WLAlloc(uSize);
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* m_pCoreUsageInfoArray = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)pMem;

if (NT_ERROR(NtQuerySystemInformation(SystemProcessorPerformanceInformation, m_pCoreUsageInfoArray, uSize, NULL)))
{
    return;
}

int numofGroups = uSize / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);

for (int i = 0; i < numofGroups; i++)
{
    auto t = m_pCoreUsageInfoArray[i];
    std::cout << "Core: " << i << " Idle:" << t.IdleTime.QuadPart << " Kernel: " << t.KernelTime.QuadPart << " User :" << t.UserTime.QuadPart << std::endl;
}

推荐阅读