首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rdtsc无序执行的解决方案?

rdtsc无序执行的解决方案?
EN

Stack Overflow用户
提问于 2019-02-14 12:43:34
回答 1查看 836关注 0票数 2

我正试图用rdtsc代替clock_gettime(CLOCK_REALTIME &ts),以便根据cpu周期而不是服务器时间对代码执行时间进行基准测试。工作台标记代码的执行时间对于软件来说是至关重要的。我尝试在孤立的核心上运行x86_64 3.20GHzubuntu机器上的代码,得到以下数字:

案例1:时钟获取时间: 24纳米秒

代码语言:javascript
复制
void gettime(Timespec &ts) {
        clock_gettime(CLOCK_REALTIME, &ts);
}

案例2: rdtsc (没有mfence和编译器屏障) : 10 ns

代码语言:javascript
复制
void rdtsc(uint64_t& tsc) {
        unsigned int lo,hi;
        __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
        tsc = ((uint64_t)hi << 32) | lo;
}

案例3: rdtsc (带有mfence和编译器屏障) : 30 ns

代码语言:javascript
复制
void rdtsc(uint64_t& tsc) {
        unsigned int lo,hi;
        __asm__ __volatile__ ("mfence;rdtsc" : "=a" (lo), "=d" (hi) :: "memory");
        tsc = ((uint64_t)hi << 32) | lo;
}

这里的问题是我知道rdtsc是一个非序列化调用,可以由CPU重新排序,另一个选择是rdtscp,它是一个序列化调用,但rdtscp调用后的指令可以在rdtscp调用之前重新排序。使用内存屏障会增加执行时间。

  • 对延迟敏感代码进行基准测试的最优化和最好的方法是什么?
  • 我提到的情况是否会得到优化呢?
EN

回答 1

Stack Overflow用户

发布于 2019-02-14 14:11:26

您希望lfence;rdtsc启动时钟,rdtscp;lfence停止时钟,因此屏障超出了时间间隔。

(或者有时您希望lfence;rdtsc;lfence启动时钟,以获得额外的可重复性,而代价是增加开销。)

MFENCE是错误的指令;它不能保证序列化指令流(但实际上它在Skylake上使用最新的微码来修复一个错误)。LFENCE序列化指令流,而不等待存储缓冲区为空,仅供ROB使用。这在英特尔总是正确的,但在AMD上只有在光谱仪的缓解功能,使lfence不仅仅是一个诺普。(我猜AMD不会重新排序WC内存中的movntdqa加载,因此lfence作为内存屏障是没有意义的,它只用作防止投机性执行的执行障碍,或者是RDTSC。)

还请参阅Get CPU cycle count?,其中有一个关于序列化rdtsc的部分。但是,您也不需要使用内联的asm;使用__rdtsc()_mm_lfence()。(但与一般的微基准测试一样,检查编译器的asm输出以确保它实现了您想要的结果也不失为一个好主意。)

您无法避免开销,与一对指令的成本相比,它总是很重要的。

另外,clflush to invalidate cache line via C function作为一个减去测量开销的例子。

但是还要注意的是,通常将代码放在循环中更有用,因为在结果准备好之前执行延迟比等待指令从ROB中实际退出更有意义。请参阅RDTSCP in NASM always returns the same value中的一个例子(在asm中),以度量单个insn的吞吐量/延迟。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54690703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档