【问题标题】:Why does __get_cpuid return all zeros for leaf=4?为什么 __get_cpuid 对 Leaf=4 返回全零?
【发布时间】:2018-02-26 14:16:01
【问题描述】:

我想写一个简单的程序调用__get_cpuid来获取缓存信息:

#include <cpuid.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int leaf = atoi(argv[1]);

    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;

    if (__get_cpuid(leaf, &eax, &ebx, &ecx, &edx))
    {
        printf("leaf=%d, eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n",
                leaf, eax, ebx, ecx, edx);
    }
    return 0;
}

首先,我将leaf 传递为 2:

$ ./a.out 2
leaf=2, eax=0x76035a01, ebx=0xf0b2ff, ecx=0x0, edx=0xca0000

由于ebx中有0xff,这意味着我可以从leaf=4获取缓存信息(参考here):

$ ./a.out 4
leaf=4, eax=0x0, ebx=0x0, ecx=0x0, edx=0x0

但这一次,所有的返回值都是0。为什么我无法从__get_cpuid 获取有效信息?

【问题讨论】:

  • 尝试使用__get_cpuid_count,它允许指定子叶。 IE。 __get_cpuid_count(leaf, 0, &amp;eax, &amp;ebx, &amp;ecx, &amp;edx).
  • @user786653 它有效!您能否详细说明__get_cpuid__get_cpuid_count 之间的区别?为什么__get_cpuid 不起作用?谢谢!

标签: gcc x86 cpu intel cpuid


【解决方案1】:

查看 EAX=4 的链接引用,我们看到需要将 ECX 设置为“要查询的缓存级别(例如 0=L1D、1=L2 或 0=L1D、1=L1I、2=L2)” .

我无法快速找到有关 __get_cpuid 的任何文档,但搜索确实出现了 soure code,我注意到您需要调用 __get_cpuid_count 以在调用 cpuid 之前设置 ecx (否则你会得到随机的答案——看起来大多是 0)。

【讨论】:

  • 我假设你得到了全零,因为ecx 持有的垃圾数量高于你的 CPU 的缓存级别数(在带有 eDRAM 的 CPU 上可能高达 4 级)。 IIRC,这就是 CPUID 告诉你你已经枚举了最后一级缓存的方式。
猜你喜欢
  • 2018-05-30
  • 1970-01-01
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多