我在so上看到了这篇帖子,其中包含获取最新CPU周期计数的C代码:

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

有没有办法在C++中使用这个代码(Windows和Linux解决方案欢迎)?虽然用C语言编写(C是C++的子集),但我不太确定如果这个代码在C++项目中工作,如果不是,怎么翻译?

我使用的是x86-64

EDIT2:

找到此函数,但无法让VS2010识别汇编程序.我需要包括什么吗?(我想我必须用uint64_tlong long换windows……)

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

EDIT3:

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

"错误C2400:‘opcode’中的内联汇编程序语法错误;找到‘data’ 键入‘"

有人能帮帮忙吗?

推荐答案

从GCC 4.5后的版本开始,现在同时支持MSVCthe 100 intrinsic和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).x86rdtsc指令将其64位结果放在edX:EAX中,因此让编译器 Select 带"=r"的输出是行不通的:没有办法要求CPU将结果转到其他任何地方.
  • ((uint64_t)hi << 32) | lo-零-将两个32位的一半扩展到64位(因为lo和hi是unsigned),并将它们一起逻辑Shift+OR运算为单个64位C变量.在32位代码中,这只是一种重新解释;值仍然只保留在一对32位寄存器中.在64位代码中,您通常会得到实际的Shift+OR ASM指令,除非高半部分被优化掉.

(编者按:如果您使用unsigned long而不是unsigned int,这可能会更有效率.那么编译器将知道lo已经被零扩展到RAX.它不会知道上半部分是零,所以如果它想要以不同的方式合并,|+是等价的.从理论上讲,只要让优化器做好工作,内在机制应该给您带来两全其美的效果.)

如果你能避免的话.但是,如果您需要了解使用内联asm的旧代码,以便可以使用intrinsic重写它,那么希望本节很有用.另见https://stackoverflow.com/tags/inline-assembly/info

C++相关问答推荐

修改pGM使用指针填充2-D数组但不起作用

C中出现分段错误后关闭文件

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

增加getaddrinfo返回的IP地址数量

带有sigLongjMP中断I/O的异常处理程序

如何创建一个C程序来存储5种动物的名字,并在用户 Select 其中任何一种动物时打印内存地址?

为什么我会收到释放后堆使用错误?

S将C语言宏定义为自身的目的是什么?(在glibc标题中看到)

如何确保我将使用C标准库函数的函数版本,如&getc";,而不是类似函数的宏版本?

使用ld将目标文件链接到C标准库

不带Malloc的链表

具有正确标头的C struct 定义问题

如何组合两个宏来初始化C语言中的字符串数组?

带有数组指针的 struct 在print_stack()函数中打印随机数

哪个首选包含第三个库S头文件?#INCLUDE;文件名或#INCLUDE<;文件名&>?

C中的数组下标和指针算法给出了不同的结果

从Raku nativecall调用时精度不同

如何在C中计算包含递增和递减运算符的逻辑表达式?

strlen 可以是[[未排序]]吗?

计算 e^x 很好.但不是 x 的罪