_mm_lfence()时间开销不确定吗?

时间:2019-02-04 17:05:21

标签: c performance x86 intrinsics rdtsc

我正在尝试确定读取元素所需的时间,以确保它是缓存命中或缓存未命中。为了阅读,我使用_mm_lfence()函数。我得到了意外的结果,检查后我发现lfence函数的开销不是确定性的。 因此,我正在执行一个程序,该程序在例如10万次迭代的循环中测量此开销。我得到一个迭代超过1000个时钟周期的结果,而下一次迭代则得到200个时钟周期。在函数功能开销之间存在如此大差异的原因是什么?如果如此不可靠,我如何正确判断缓存命中和缓存未命中的延迟呢?我正在尝试使用与本文相同的方法:Memory latency measurement with time stamp counter

给出不可靠结果的代码是这样的:

//this is the fuction exists into the app.js

const index = require('./serverSide/router/index');
initRoutes() {
      app.use('/admin', index);
    app.use('/', (req, res) => {
        res.sendFile(__dirname + './src/index.html');
    });
    app.use(function (req, res, next) {
        const err = new Error('Not Found');
        err.status = 404;
        next(err);
    });
}

//and this is into the class Router

class Router {
    constructor(router) {
       console.log('/**Routing**/');
       router.get('/', this.result());
    }
    result(req, res) {
      console.log("works");
    }
 }

 module.exports = Router;

arr中的值在不同范围内变化,arr_size为100000。

2 个答案:

答案 0 :(得分:3)

  

我得到一个循环超过1000个时钟周期的结果,而下一次是200个。

在前几次迭代之后,像CPU这样的声音就会从空闲状态提高到正常时钟速度。

请记住, RDTSC计数 reference 个周期(固定频率,等于或接近CPU的最大非涡轮频率),非核心时钟周期< / strong>。 (怠速/涡轮/等等)。较旧的CPU具有RDTSC计数核心时钟周期,但是多年来,CPU供应商已经将RDTSC频率固定为使其对clock_gettime()有用,并对此事实with the invariant_tsc CPUID feature bit进行了广告宣传。另请参见Get CPU cycle count?

如果您确实要使用RDTSC而不是性能计数器,请禁用Turbo并使用预热循环将CPU置于其最大频率。


有些库可让您对HW性能计数器进行编程,并设置权限,以便可以在用户空间中运行rdpmc。实际上,其开销比rdtsc低。有关在用户空间中访问性能计数器的方式的概述,请参见What will be the exact code to get count of last level cache misses on Intel Kaby Lake architecture

我还找到了一篇有关向Linux rdpmc(PAPI)添加用户空间perf支持的论文:ftp://ftp.cs.uoregon.edu/pub/malony/ESPT/Papers/espt-paper-1.pdf。 IDK是否使它成为主流内核/性能代码。

答案 1 :(得分:-1)

实用答案:使用rdtscp而不是rdtsc(以及编译器障碍,我不确定您是否会找到该版本),并在rdtscp实例之间放下栅栏。它不是完美的,但这应该减少错误。 Here is a slightly dated post that should be useful.

比您想了解的还要多:很难对指令的顺序和推测进行推理。 Lfence是一把非常沉重,复杂的锤子。它也会在此之后引起猜测,但它本身可以推测地执行(有趣)。有关更多详细信息,请查看此blogpost