是否有标准的常量* nix基准,如果没有,如何制作`bogobench`?

时间:2016-11-04 21:09:28

标签: linux time emulation benchmarking qemu

普通的单线程 * nix 程序可以使用像time这样的工具进行基准测试,即:

# how long does `seq` take to count to 100,000,000
/usr/bin/time seq 100000000 > /dev/null

输出:

1.16user 0.06system 0:01.23elapsed 100%CPU (0avgtext+0avgdata 1944maxresident)k
0inputs+0outputs (0major+80minor)pagefaults 0swaps

...但返回的数字始终取决于系统,从某种意义上说,它也衡量用户的硬件。

是否存在一些非相对基准测试方法或命令行工具,它们会在任何系统(或至少是一个相当大的系统子集)上返回大致相同的虚拟时序数?就像grep -m1 bogo /proc/cpuinfo返回a roughly approximate but stable unit一样,这样的基准也应该返回一个类似的持续时间单位。

假设对普通命令进行基准测试,我们有一个魔法工具bogobench(其中" bogo "是一个形容词,表示" 有些虚假状态",但不一定具有与 BogoMIPs 相同的算法:

bogobench foo bar.data

我们在两个物理上分开的系统上运行它:

  1. a 1996 Pentium II
  2. 2015 Xeon
  3. 所需的输出类似于:

    21 bogo-seconds
    

    所以bogobench在这两种情况下应该返回相同的数字,即使它可能在第二个系统上完成的时间要少得多。

    qemu这样的硬件模拟器可能是一种方法,但不一定是唯一的方法:

    1. 将代码插入到基准测试脚本bogo.sh
    2. bogo.sh复制到可引导的Linux磁盘映像 bootimage.iso ,在bogo.sh将自动运行的目录中,然后立即关闭仿真器。在此期间,它输出某种形式的计时数据,以解析为 bogo-seconds
    3. 使用qemu个最小-machine个选项之一运行 bootimage.iso

      qemu-system-i386 -machine type=isapc bootimage.iso
      
    4. 但我不确定如何让qemu使用虚拟时钟,而不是主机CPU的时钟,qemu本身似乎是一个看似沉重的工具简单的任务。 (对于这样的任务,真的 MAME MESS 会比qemu更多才多艺的模拟器 - 但我是不熟悉 MAME ,虽然MAME currently has some capacity for 80486 PC emulation。)

      在线我们有时会将计算机X 上基于时间的基准测试与计算机Y 上的基准测试进行比较和对比。我希望用户 X Y 能够在虚拟机器Z 上进行基准测试,并获得奖励积分如果需要,可以模拟 X Y (如 MAME ),除非不考虑 X Y 的实际运行时间(与 MAME 不同,仿真通常可以播放)。通过这种方式,用户可以报告程序在有趣情况下的执行情况,而程序员不必担心结果会因用户硬件的特性(例如CPU怪癖,占用资源的后台进程等)而产生偏差。

      实际上,即使是用户的拥有的硬件,基于time的基准也可能不可靠,因为用户通常无法确定某些后台进程, (或错误,或硬件错误,如坏扇区或病毒),可能不会降低性能的某些方面。而更虚拟的基准应该不那么容易受到这种影响。

2 个答案:

答案 0 :(得分:4)

我认为实现这一目标的唯一理智方法是使用周期精确的模拟器来进行某种硬件设计。

AFAIK,没有适用于现代x86硬件的公开可用的周期精确模拟器,因为它非常复杂,尽管有很多关于x86微架构内部结构的知识(Agner Fog的东西,英特尔和AMD自己的优化指南和标签wiki中的其他东西,足够的行为仍然是一个充满CPU设计商业秘密的黑盒子,它最多可以模拟类似的东西。 (例如,分支预测绝对是最秘密但非常重要的部分之一)。

虽然应该可以接近模拟英特尔Sandybridge或Haswell的实际管道和无序核心/ ROB / RS(远远低于实时),但是没有人知道它。

但其他硬件设计的周期精确模拟器存在Donald Knuth's MMIX architecture是一个干净的RISC设计,实际上可以用硅片构建,但目前只有存在于纸上。

从该链接:

  

特别感兴趣的是MMMIX元模拟器,它能够对复杂管道进行动态调度,允许超标量执行任意数量的功能单元,并具有多种缓存和分支预测等,包括详细实现硬中断和软中断。

所以你可以将它作为参考机器,让每个人都可以运行他们的基准测试,每个人都可以获得可比较的结果,告诉你在MMIX上运行的速度有多快(在使用gcc编译MMIX之后)。但不是它在x86上运行的速度有多快(大概也是用gcc编译),即使对于以不同方式执行相同工作的两个程序,这可能会有很大差异。

针对编程难题和Code Golf网站[fastest-code]的{​​{1}}挑战,专为此目的而设计。它是一个玩具架构,通过存储到0xffffffffffffffff来打印到stdout之类的东西,所以它不一定能告诉你任何关于某些东西在任何真实硬件上运行的速度。

GOLF,AFAIK没有完整的C实现,所以你只能用手写的asm来实现它。这与MMIX有很大不同,MMIX是优化编译器的目标。

答案 1 :(得分:3)

可以(可能?)扩展为更准确的一种实用方法是使用现有工具来测量被测代码的某些硬件不变性能指标,然后应用公式来提出bogoseconds分数。

不幸的是,大多数易于衡量的硬件指标不变 - 相反,它们依赖于硬件。然而,一个显而易见的应该是不变的将是"指令退休"。如果代码在每次运行时都使用相同的代码路径,则所有硬件 1 上的指令退役计数应该相同。

然后你应用某种标称时钟速度(让我们说1 GHz)和名义CPI(让我们说1.0)来获得你的bogoseconds - 如果你测量15e9指令,你输出 15 bogoseconds 的结果。

这里的主要缺陷是名义CPI可能偏离实际CPI!虽然大多数程序在1 CPI左右徘徊,但很容易找到它们可以接近0.25或宽度的倒数的示例,或者如果存在许多冗长的档位则可以是10或更多。当然,这样的极端程序可能是您想要进行基准测试的 - 即使您没有问题,如果您使用基准测试来评估代码更改,它将忽略CPI中的任何改进或回归,并且仅查看指令数。

尽管如此,它可以满足您的要求,因为它可以有效地模拟每个周期执行正好1条指令的机器,也许它是一种合理的宽图像方法。使用像perf stat -e instructions这样的工具很容易实现(就像单线程一样)。

为了修补漏洞,你可以试着让公式变得更好 - 让我们说你可以为缓存未命中添加一个因子来解释那个大的停顿源。不幸的是,您如何以硬件不变的方式测量缓存未命中?性能计数器不会提供帮助 - 它们依赖于本地缓存的行为和大小。好吧,您可以使用cachegrind以与机器无关的方式模拟缓存。事实证明,cachegrind甚至涵盖了分支预测。因此,您可以将指令计数,缓存未命中和分支未命中数插入更好的公式(例如,使用典型的L2,L3,RAM延迟和分支未命中的典型成本)。

我认为,就这种简单的方法而言,这将会带给你。在那之后,您可能只是撕掉任何现有的x86 2 仿真器并在那里添加简单的机器模型。您不需要精确循环,只需选择标称宽度并对其进行建模。可能无论是什么底层仿真cachegrind都可能是一个很好的匹配,你可以免费获得缓存和分支预测建模。

1 当然,这并不排除指令计数机制中的错误或不准确。

2 您没有标记您的问题x86 - 但我会假设您的目标是您的目标,因为您只提到了英特尔芯片。

相关问题