如何使用 rdtsc 在 Qemu i386 系统中进行基准测试

How to benchmark in Qemu i386 system using rdtsc

目前我正在尝试测量在同一环境中使用两种不同的编程语言完成一项操作所花费的时钟周期数。 (不使用 OS)

目前我正在使用 Qemu-i386 模拟器并使用 rdtsc 来测量时钟周期。

/* Return the number of CPU ticks since boot. */
static inline u64 rdtsc(void)
{
    u32 hi, lo;
    // asm("cpuid");
    asm("rdtsc" : "=a" (lo), "=d" (hi));
    return ((u64) lo) | (((u64) hi) << 32);
}

取rdtsc运行前后的差值应该提供时钟周期数。

    start_time = rdtsc();
    operation();
    stop_time = rdtsc();
    num_cycles = stop_time-start_time;

但是即使我进行了 100 多次迭代并且变化了数千个周期,差异也不是恒定的。

qemu-system-i386-内核out.elf

尝试在 QEMU 仿真下对来宾软件进行基准测试充其量是极其困难的。 QEMU 的模拟不具有任何类似于真实硬件 CPU 的性能特征:一些在硬件上很快的操作,如浮点,在 QEMU 上非常慢;我们不对缓存建模,您不会看到任何类似于数据集达到缓存行或 L1/L2/etc 缓存大小限制时看到的性能曲线;等等。

影响现代 CPU 性能的重要因素包括(至少):

  • 执行的原始指令计数
  • TLB 未命中
  • 分支预测器未命中
  • 缓存未命中

如果您使用 -icount 选项,QEMU 不会跟踪最后三个中的任何一个,并且只会对第一个进行模糊的尝试。 (特别是,在没有 -icount 的情况下,我们提供给虚拟机的 RDTSC 值或多或少只是主机 CPU RDTSC 值,因此用它测量的时间将包括各种 QEMU 开销,包括翻译所花费的时间来宾代码。)

假设您在 x86 主机上,您可以在 KVM 虚拟机下尝试 运行 的 -enable-kvm 选项。然后至少你会看到硬件的真实性能 CPU,尽管你仍然会看到一些来自开销的噪音,因为其他主机进程与 VM 争用 CPU。