【问题标题】:How do I call "cpuid" in Linux?如何在 Linux 中调用“cpuid”?
【发布时间】:2012-12-25 08:42:25
【问题描述】:

在为 Windows 编写新代码时,我偶然发现了来自 Windows API 的_cpuinfo()。由于我主要处理 Linux 环境 (GCC),因此我希望能够访问 CPUInfo。

我尝试了以下方法:

#include <iostream>

int main()
{
  int a, b;

  for (a = 0; a < 5; a++)
  {
    __asm ( "mov %1, %%eax; "            // a into eax
          "cpuid;"
          "mov %%eax, %0;"             // eax into b
          :"=r"(b)                     // output
          :"r"(a)                      // input
          :"%eax","%ebx","%ecx","%edx" // clobbered register
         );
    std::cout << "The code " << a << " gives " << b << std::endl;
  }

  return 0;
}

这个使用程序集,但我不想重新发明轮子。有没有其他方法可以在不组装的情况下实现 CPUInfo?

编译器错误:

lewis@lewis-desktop:~/Desktop/prog$ g++ -Wall CPUInfo.cpp
CPUInfo.cpp: In function ‘int main()’:
CPUInfo.cpp:10:22: error: expected ‘)’ before ‘;’ token
CPUInfo.cpp:10:23: error: expected primary-expression before ‘)’ token
CPUInfo.cpp:10:23: error: expected ‘;’ before ‘)’ token
CPUInfo.cpp:8:8: warning: unused variable ‘b’ [-Wunused-variable]
CPUInfo.cpp:12:8: error: expected ‘}’ at end of input

【问题讨论】:

  • 所以,我猜这是 g++。和 x86?你应该说。无论如何,问题是什么?你告诉我们你在做什么,并展示了代码。但毫无疑问。
  • @JerryCoffin 我正在运行 Linux(因为这将是 Linux 部分,以确定执行代码的计算机的 CPU)。我已经使用 Win API 中的 _cpuinfo() 函数确定了 Windows 版本/部分。这就是我的观点。
  • @DavidHeffernan 查看我更新的帖子,我忽略了添加编译器错误。
  • 我已经编辑了问题以反映(我认为)是预期的问题。如果我错了,请随时回滚。
  • 我不知道你为什么抱怨投反对票。现在,我没有投反对票,我看到它已被删除。但是原始问题省略了编译器的详细信息,未能提供错误消息并且没有提出问题。所以有人对你投了反对票。这是可以预料的。不要责怪反对者。修正问题。然后你就会得到选票。

标签: c++ assembly gcc x86 cpuid


【解决方案1】:

由于您使用 GCC 进行编译,因此您可以包含声明这些函数的 cpuid.h

/* Return highest supported input value for cpuid instruction.  ext can
   be either 0x0 or 0x8000000 to return highest supported value for
   basic or extended cpuid information.  Function returns 0 if cpuid
   is not supported or whatever cpuid returns in eax register.  If sig
   pointer is non-null, then first four bytes of the signature
   (as found in ebx register) are returned in location pointed by sig.  */
unsigned int __get_cpuid_max (unsigned int __ext, unsigned int *__sig)

/* Return cpuid data for requested cpuid level, as found in returned
   eax, ebx, ecx and edx registers.  The function checks if cpuid is
   supported and returns 1 for valid cpuid information or 0 for
   unsupported cpuid level.  All pointers are required to be non-null.  */
int __get_cpuid (unsigned int __level,
    unsigned int *__eax, unsigned int *__ebx,
    unsigned int *__ecx, unsigned int *__edx)

您不需要也不应该重新实现此功能。

【讨论】:

  • +1 不知道该标头存在。我总是用一些内联汇编来完成它。
  • @Mysticial 这就是我对 GCC 和 Linux 的完全无知派上用场的地方。我不得不用谷歌搜索答案!
  • 开发的基本规则是重用而不是重新实现。你自己写printf吗?还是您自己的strcmp?你自己写std::string吗?
  • 你能提供/包括一个示例用法吗?并可能添加返回类型:-P
  • 只有一份英特尔官方文档。
【解决方案2】:
for (a =0; a < 5; ++a;)

那里应该只有两个分号。你有三个。

这是基本的 C/C++ 语法; CPUID 是一个红鲱鱼。

【讨论】:

  • 错字。我在发布之前修复了它,由于某种原因它又回到了那里。我在 Git 上更改了分支,这可能就是原因。但是,是的,我确实知道这种“基本语法”。
  • 但是您发布的错误是由这个错字引起的。如果您已解决此问题但仍有问题,请更新错误列表。
猜你喜欢
  • 2012-08-26
  • 2017-04-02
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 2011-10-03
  • 2013-03-17
  • 2015-07-02
  • 1970-01-01
相关资源
最近更新 更多