【问题标题】:In which cases GetSystemInfo/GetLogicalProcessorInformationEx returns different processor count within the same program run?在哪些情况下 GetSystemInfo/GetLogicalProcessorInformationEx 在同一程序运行中返回不同的处理器计数?
【发布时间】:2020-10-27 07:02:06
【问题描述】:

有 Windows API 函数来获取 CPU 和 CPU Cache 拓扑。

GetSystemInfodwActiveProcessorMaskdwNumberOfProcessors 填充SYSTEM_INFO

GetLogicalProcessorInformationEx 可用于获得有关每个处理器的更精确信息,例如缓存大小、缓存行大小、缓存关联性等。其中一些信息也可以通过_cpuidex 获得。

我问的是,在哪些情况下,一个调用获得的值与另一个调用获得的值不一致,如果两个调用都是在没有程序重启的情况下进行的。

具体来说,CPU 计数可以改变吗:

  • 用户是否应该休眠、安装新处理器并唤醒系统?或者即使这样也行不通?
  • 或者操作系统/硬件可以动态决定插入另一个处理器?
  • 还是可以通过虚拟机实现,但不能在真实硬件上实现?

可以改变缓存行大小和缓存大小:

  • 对于GetLogicalProcessorInformationEx,因为处理器在运行时被替换
  • _cpuid 只是因为系统包含具有不同缓存属性的处理器,并且后续调用在不同的处理器上

这些问题的实际原因是我只想获取此信息一次,并将其缓存:

  • 我将使用它来调整分配器,因此更改已分配内存的分配策略可能会导致内存损坏。
  • 这些函数可能很昂贵,它们可能是内核调用,我想避免这种情况

【问题讨论】:

  • 它当然可以在休眠情况下发生变化,在高端服务器设备上即使没有它也可能会发生变化。这肯定会发生在真实的硬件上,而不仅仅是虚拟机。尽管除非您在极其专业的服务器级设备上运行,否则您不太可能看到它。
  • 我应该说,我的意思是处理器数量可能会改变,我不确定所有 CPU 的缓存线是否都必须相同,但我想如果它是 GetSystemInformation 和不是 GetLogicalProcessorInformationEx。
  • 您能否提供有关如何重现此问题的更多信息?喜欢如何使用GetLogicalProcessorInformationEx 来获取处理器数量?以及您的环境信息(例如物理处理器和逻辑处理器数量)、您的应用程序目标架构 (x86/x64/arm64) 和您的系统架构?
  • @Rita,我没有在特定架构上重现此行为。我想知道何时重现此行为,特别是在哪些架构上,如果它们在这方面有所不同。 GetLogicalProcessorInformation 文档中的示例包含 CPU 计数,Ex 版本也可以这样做

标签: windows winapi processor cpuid


【解决方案1】:

如果一个线程被调度在属于不同处理器组且具有不同数量处理器的内核上运行,GetSystemInfoGetLogicalProcessorInformation 将返回不同数量的处理器,即核心所属的组。

在支持热添加 CPU 的服务器级系统上,处理器的数量可以改变如下:

  • 热添加 CPU 使得有一个处理器组少于 64 个处理器并且线程在该组上运行会改变GetSystemInfoGetLogicalProcessorInformation 报告的处理器数量,以及 GetLogicalProcessorInformationEx
  • 处理器组的最大大小为 64,Windows 始终以最小化组总数的方式创建组。因此,组数是逻辑核心总数除以 64 的上限。热添加 CPU 可能会导致创建新组。这不仅改变了处理器的总数,还改变了组的数量,只能通过GetLogicalProcessorInformationEx获得。

在虚拟机上,处理器的数量也可以动态增加而无需热插拔。

您可以使用PNPCPU 工具模拟热添加处理器。这对于测试取决于处理器数量的一段代码的正确性很有用。

通过编写设备驱动程序并注册synchronousasynchronous 驱动程序通知,可以在添加新处理器时从系统接收通知。如果没有设备驱动程序,我认为这是不可能的。

我认为,在当前系统上,GetLogicalProcessorInformationEx 返回的缓存属性只能在线程迁移到其中一个或多个这些属性不同的另一个内核或 CPU 时发生变化。例如,在 Intel Lakefield 处理器上,L2 缓存的属性取决于线程正在运行哪个内核,因为不同的内核具有不同属性的不同 L2 缓存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 2016-03-09
    相关资源
    最近更新 更多