gpt4 book ai didi

c++ - 如何从 C++ 获取 x86_64 中的 CPU 周期数?

转载 作者:IT老高 更新时间:2023-10-28 12:52:14 53 4
gpt4 key购买 nike

我在 SO 上看到这篇文章,其中包含 C 代码以获取最新的 CPU 周期计数:

CPU Cycle count based profiling in C/C++ Linux x86_64

有没有办法可以在 C++ 中使用此代码(欢迎使用 windows 和 linux 解决方案)?虽然是用 C 编写的(C 是 C++ 的子集),但我不太确定这段代码是否可以在 C++ 项目中工作,如果不能,如何翻译?

我使用的是 x86-64

EDIT2:

找到了这个函数,但是VS2010无法识别汇编程序。我需要包括任何东西吗? (我相信我必须将 uint64_t 换成 long long for windows ....?)

static inline uint64_t get_cycles()
{
uint64_t t;
__asm volatile ("rdtsc" : "=A"(t));
return t;
}

EDIT3:

从上面的代码我得到错误:

"error C2400: inline assembler syntax error in 'opcode'; found 'data type'"

有人可以帮忙吗?

最佳答案

从 GCC 4.5 及更高版本开始,__rdtsc()现在 MSVC 和 GCC 都支持内在

但需要的包含不同:

#ifdef _WIN32
#include <intrin.h>
#else
#include <x86intrin.h>
#endif

这是 GCC 4.5 之前的原始答案。

直接退出我的一个项目:

#include <stdint.h>

// Windows
#ifdef _WIN32

#include <intrin.h>
uint64_t rdtsc(){
return __rdtsc();
}

// Linux/GCC
#else

uint64_t rdtsc(){
unsigned int lo,hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32) | lo;
}

#endif

这个 GNU C Extended asm告诉编译器:

  • volatile :输出不是输入的纯函数(因此每次都必须重新运行,而不是重用旧结果)。
  • "=a"(lo)"=d"(hi) :输出操作数是固定寄存器:EAX 和 EDX。 (x86 machine constraints)。 x86 rdtsc指令将其 64 位结果放入 EDX:EAX,因此让编译器使用 "=r" 选择输出行不通:没有办法让 CPU 将结果发送到其他任何地方。
  • ((uint64_t)hi << 32) | lo - 将两个 32 位半部分零扩展为 64 位(因为 lo 和 hi 是 unsigned ),并将它们逻辑移位 + OR 到单个 64 位 C 变量中。在 32 位代码中,这只是一种重新解释;这些值仍然只保留在一对 32 位寄存器中。在 64 位代码中,您通常会得到一个实际的 shift + OR asm 指令,除非高半部分被优化掉。

(编者注:如果您使用 unsigned long 而不是 unsigned int,这可能会更有效。然后编译器会知道 lo 已经零扩展为 RAX。它不会知道上half 为零,因此 |+ 是等价的,如果它想以不同的方式合并。理论上,内在函数应该给你两全其美,只要让优化器做好。)

https://gcc.gnu.org/wiki/DontUseInlineAsm如果你能避免它。但是,如果您需要了解使用内联 asm 的旧代码以便您可以用内在函数重写它,希望本节对您有所帮助。另见 https://stackoverflow.com/tags/inline-assembly/info

关于c++ - 如何从 C++ 获取 x86_64 中的 CPU 周期数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13772567/

53 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com