我在SO上看到这篇文章,其中包含C代码以获取最新的CPU周期数:
基于CPU周期计算的C/C++ Linux x86_64中的分析
有没有办法在C++中使用这个代码(欢迎使用windows和linux解决方案)?虽然用C语言编写(而C是C++的一个子集)但我不太确定这段代码是否适用于C++项目,如果没有,如何翻译呢?
我使用的是x86-64
EDIT2:
找到此功能但无法让VS2010识别汇编程序.我需要包含任何内容吗?(我相信我必须换uint64_t到long long窗户......?)
static inline uint64_t get_cycles()
{
uint64_t t;
__asm volatile ("rdtsc" : "=A"(t));
return t;
}
Run Code Online (Sandbox Code Playgroud)
EDIT3:
从上面的代码我得到错误:
"错误C2400:'操作码'中的内联汇编语法错误;找到'数据类型'"
有人可以帮忙吗?
在最近的英特尔ISA文档中,该lfence指令被定义为序列化指令流(防止指令流无序执行).特别是,该指令的描述包括以下行:
具体来说,LFENCE不会执行,直到所有先前的指令在本地完成,并且在LFENCE完成之前没有后续指令开始执行.
请注意,这适用于所有的指令,不只是内存加载指令,使得lfence 更多的不仅仅是一个存储排序防护.
虽然这现在出现在ISA文档中,但不清楚它是否是"架构",即所有x86实现都遵守,或者它是否特定于Intel.特别是AMD处理器是否也将lfence序列化为指令流?
我正在NASM中使用RDTSC和RDTSCP测量各种汇编语言指令的机器周期,以帮助优化。
我读了Intel的Gabriele Paoloni撰写的“如何在Intel IA-32和IA-64指令集体系结构上对代码执行时间进行基准测试”(2010年9月)和其他Web资源(其中大多数是C语言中的示例)。
使用下面的代码(从C转换),我测试了各种指令,但RDTSCP在RDX中始终返回零,在RAX中始终返回7。我首先认为7是周期数,但显然并非所有指令都需要7个周期。
rdtsc
cpuid
addsd xmm14,xmm1 ; Instruction to time
rdtscp
cpuid
Run Code Online (Sandbox Code Playgroud)
返回7,这并不奇怪,因为在某些体系结构上,添加了7个周期(包括延迟)。前两个指令(根据某些情况)可以颠倒,先是cpuid,然后是rdtsc,但这在这里没有什么区别。
当我将指令更改为2周期指令时:
rdtsc
cpuid
add rcx,rdx ; Instruction to time
rdtscp
cpuid
Run Code Online (Sandbox Code Playgroud)
这还会在rax中返回7,在rdx中返回零。
所以我的问题是:
如何访问和解释RDX:RAX中返回的值?
为什么RDX总是返回零,应该返回什么?
更新:
如果我将代码更改为此:
cpuid
rdtsc
mov [start_time],rax
addsd xmm14,xmm1 ; INSTRUCTION
rdtscp
mov [end_time],rax
cpuid
mov rax,[end_time]
mov rdx,[start_time]
sub rax,rdx
Run Code Online (Sandbox Code Playgroud)
我的rax达到了64,但这听起来像是周期太多。