我有一段用clang++编译的内联程序集:

    asm volatile ("LFENCE\n\t"
              "RDTSC\n\t"
              "shl $32, %%rdx\n\t"
              "or %%rdx, %%rax\n\t"
              : "=a" (retval)
              :: "%rax", "%rdx");

在OSX上,如上所述检查rdtsc的总成本约为10-20个周期。当我在Linux(不是虚拟机)上编译相同的代码时,大约需要2500个周期。这使我怀疑Linux在做一些愚蠢的事情,例如在用户空间中禁用RDTSC。从这些文章中,看来至少已经考虑了Linux:
  • rdtsc, too many cycles
  • http://lwn.net/Articles/388188/

  • 我正在运行Ubuntu 14.04

    问题:
  • 内核模式中只有rdtsc确实使它进入了Ubuntu内核吗?
  • 如果存在,如何检测当前设置?
  • 如何使用户模式rdtsc再次正常工作?

  • PS:我完全知道rdtsc会出现错误的测量,管道冲洗等问题。我可以忍受它们,并在需要时采取预防措施。我只希望rdtsc快速。

    最佳答案

    自20年前问世以来,英特尔一直在说“安全的操作系统会在系统初始化期间设置TSD标志,以禁止用户访问时间戳计数器”。大多数操作系统都忽略了英特尔。每隔5年左右,某个安全研究人员就会在某处“发现”一种使用这种精确定时来削弱密码,加密密钥等的新方法。示例:http://people.csail.mit.edu/tromer/papers/cache.pdfhttp://www.daemonology.net/papers/htt.pdf

    如果您还补充说,人们以为它以恒定速率滴答(不是在旧的CPU上)就引起了问题;那么,人们就认为它与性能有关(不是在较新的CPU上)就引起了问题;然后,那些简单地使用它的人会错误地使用它(例如,在出现大量错误的情况下安排一个短序列);它似乎开始变得更糟。

    如果再加上这些,则在多CPU系统(尤其是NUMA系统)上出现“out_of_sync TSC”问题;它变得更糟(尤其是对于内核试图使其“保持同步”的状态)。

    最后,如果您看一下性能监视计数器,事件探查器等;您意识到RDTSC是该工作的错误工具。然后,您将目光投向“一天中的时间”和“经过的时间”功能,并意识到那里也有不错的/便携式替代品。

    注意:我不知道Ubuntu是否在所有系统上,或者仅在某些系统(例如,速率不是恒定的和/或CPU之间不同步的系统)上的用户空间中禁用了RDTSC,甚至还没有禁用一切。我所知道的是它应该在20年前禁用。

    编辑:以上是所提问题的答案。以下是您需要的答案。

    正确使用RDTSC;首先在循环中计时“无”,然后丢弃“高于正常”结果(由IRQ,任务切换等引起)。使用它来查找“无”的平均值(仅RDTSC的平均开销)。

    接下来,对要测试的代码执行完全相同的操作(包括丢弃“高于正常”的结果),以找到“RDTSC +您的代码”的平均开销。

    最后;从“RDTSC +您的代码”结果中减去单独的RDTSC的平均开销,即可得出您的代码需要花费多长时间。

    10-07 22:28