0

我编写了一个基本代码来找出 nop 占用的时钟周期数。我们知道 nop 需要一个时钟周期。

#include <stdio.h>
#include <string.h>
#include <stdint.h>


int main(void)
{
    uint32_t low1, low2, high1, high2;
    uint64_t timestamp1, timestamp2;
    asm volatile ("rdtsc" : "=a"(low1), "=d"(high1));
    asm("nop");
    asm volatile ("rdtsc" : "=a"(low2), "=d"(high2));
    timestamp1 = ((uint64_t)high1 << 32) | low1; 
    timestamp2 = ((uint64_t)high2 << 32) | low2; 
    printf("Diff:%lu\n", timestamp2 - timestamp1);
    return 0;
}

但输出不是1。

有时是 14 或 16。

我可以知道这背后的原因吗?我有什么遗漏吗

4

1 回答 1

1

我们知道 nop 需要一个时钟周期。

现代 CPU 可以被认为是一个阶段的流水线。前端可能会并行获取和解码多个指令,并将生成的微操作放入缓冲区中,等待它们的依赖关系得到满足(在被执行单元获取之前,可以在其中执行多个微操作)多个执行单元同时执行)。

ANOP没有微操作 - 它只是被前端丢弃。它不花费1个周期。

但输出不是1。

编译器生成的指令可能需要 14 或 16 个周期来处理第​​一个的输出rdtsc,然后为第二个做准备rdtsc,然后是第二个rdtsc本身。

请注意,它rdtsc可能会计算一个固定频率计时器的周期,该计时器没有 CPU 的当前(可变)时钟频率;所以 14 或 16 个“时间周期”可能是(例如)7 或 8 个 CPU 周期。

于 2020-01-12T01:53:05.330 回答