您如何测试您的计算机每秒可以执行多少条指令?

Posted

技术标签:

【中文标题】您如何测试您的计算机每秒可以执行多少条指令?【英文标题】:How can you test how many instructions per second your computer can do? 【发布时间】:2013-08-20 22:14:51 【问题描述】:

有没有一种快速/简单的方法来做到这一点(至少粗略估计)?

我正在对算法进行基准测试,我认为知道我的计算机执行指令的绝对速度并将其与我的渐近分析进行比较会很酷。

【问题讨论】:

不,真的没有(一种简单的方法)。问题相当简单:您的计算机可以执行的指令数量(很大程度上)取决于这些指令的混合和顺序。获得一个意味着任何事情的结果通常涉及一些知名基准的结果——但有意义的基准通常相当复杂。即便如此,您也必须小心——这些数字通常意味着比预期的要少。 @DanielKO Whetstone 基准测试最初是用 Algol 编写的,基于大约 1970 年从英国国家物理实验室收集的统计数据,但仅使用四元素数组来测试数组访问。然后将其翻译成 Fortran。 Dhrystone 基于类似的原理,用不同的语言,用 Ada 编写,但翻译成 C。大约 30 年前,当我第一次研究 Whetstone 时,我认为它已经过时且不切实际。 @DanielKO 关键是四个元素数组和访问它们的循环可以以不适用于更大数组的方式进行优化,而四个是Whetstone中唯一的数组大小。虽然我查阅了***的日期,但早在***出现之前,我就知道了 Whetstone 的历史。 '这个有 30 年历史的基准仍然被广泛使用,因此它是最接近“粗略估计”的基准'。我是否错过了使 结论看起来合乎逻辑的重要信息? :) 如果你使用原始的 Dhrystone 基准并用 gcc -O3 编译它(几年前),你会得到幻想的数字,因为(至少)其中一个循环变成了虚无,因此花费零时间。每秒指令数是指令数/时间 -> 无限数。但是总的基准不是零,时间,所以你最终会得到一些幻想数字在 100-1000 倍的处理器的理论值。您可以采取一些技巧来使编译器相信您需要循环内的代码,但这不再是原始来源。此外,Drhystone 基于 VAX 指令。 【参考方案1】:

如果您想知道您的 CPU 可以做什么,请查看文档。您的 CPU 供应商指定所有指令的延迟和吞吐量,以及各种其他信息(每个周期可以发出或停用多少条指令、缓存延迟等等)。在此基础上,您可以计算出理论峰值吞吐量。

如果您想要执行您的 CPU 实际在执行的操作,请运行您自己的代码并测量其性能。

但是,请记住,现代 CPU 是非常复杂的野兽,它们的性能取决于多种因素,您几乎无法接近最大化 CPU,并理解 为什么,或者究竟是什么阻碍了您的代码,需要对硬件有相当透彻的了解。 (我通常的经验法则是,如果你能持续获得理论峰值 FLOPS 的 30-40%,你就做得很好)

【讨论】:

或者只是让内核给你BogoMIPS。它至少与任何理论(即与任何上下文无关)估计一样有用。 @DanielKO 除了“文档所说的”几乎没有“与任何上下文脱节”。这是关于你的 CPU 是如何工作的以及它能够做什么的硬事实信息,如果你试图让你的代码表现良好,这是非常相关的。但是,是的,如果您只是想要一个快速估计而忽略很多细微差别,那么这个数字可能是一个非常好的候选者。 @jalf:指令不是独立执行的,因此即使是对每条指令如何执行的详尽描述,也很少能揭示在执行过程中实际会发生什么。缓存未命中、分支错误预测、数据依赖等,这是我提到的上下文的一部分。 @DanielKO 是的。这些都与我的回答没有任何矛盾,不是吗?但是,如果您想知道您的 CPU 在给出完美优化代码的情况下能够提供的最大理论吞吐量,那么您可以假设没有缓存未命中、分支错误预测或数据依赖性。所有这些都有助于解释为什么你的代码比这个理论最大值慢得多,这是整个点【参考方案2】:

这是一个典型的“在理论上,理论和实践是一样的,在实践中它们不是”的典型案例。

现代 CPU 具有非常复杂的逻辑,这意味着实际执行的操作数量与您仅查看代码或思考问题时所想的不同 [除非您的大脑只有小星球并知道那个特定的 CPU 是如何工作的]。例如,处理器可能会推测性地在分支的一侧或另一侧执行指令,即使它还没有完全到达分支 - 如果那是“错误”的一侧,那么它将丢弃这些指令的结果 - 但是当然,执行它们需要时间。

指令也被乱序执行,这意味着很难准确预测哪条指令将在何时执行。有一些例外。

如果您一次通过所有可用的执行单元推送数据和指令,您将只能获得(任何接近)理论吞吐量 - 这意味着拥有正确的指令组合,当然还有缓存中的所有代码和数据.

因此,理论上我们可以通过编写非常聪明的代码来填充处理器以使其最大化。在实践中,这很快就变成了一项艰巨的任务。

但是,问题在于测量指令的吞吐量,在现代 CPU 上,使用合适的额外软件就可以做到这一点。在 linux perftool 或 oprofile 上,对于 windows,有 Intel 的 VTune 和 AMD 的 Code Analyst。这些将允许您(取决于足够的权限)获取处理器中的“性能计数器”,该处理器具有“指令数”、“浮点操作数”、“高速缓存未命中数”、“分支错误预测”和处理器性能的许多其他测量。因此,给定足够长的运行时间(至少几秒钟,最好更多),您可以测量处理器执行的实际计数或时钟周期。

【讨论】:

“...转得非常非常非常快。”,我们可以连接一个发电机并将其用作能源吗? 对于“理论的乐趣”;在现代 CPU(例如 Intel Nehalem 及更高版本,带有“循环流检测器”)上,我会考虑尝试一个包含单字节 NOP 指令的循环(因此指令会被前端丢弃并且不会让它微操作缓冲区)。我猜你可能会通过这种方式超过“理论上每个周期 100 条指令”。 @Brendan:不,英特尔 CPU 至少确实在整个管道中运行 NOP。它们在 ROB 中占用一个插槽,但在 RS 中占用为零(未融合域:不需要执行单元)。这对于 SnB 家族来说绝对是正确的,但我还没有测试过 Nehalem。在发布到后端之前将它们丢弃可能是实用的,但这不是一个非常有价值的优化。大概不值得麻烦在 NOP 之后的第一条指令从不是前一条指令结束的 RIP 开始,没有跳转。此外,“指令”的性能计数器是错误的。 (不过,这不是交易中断。)【参考方案3】:

在当今的实践中,有效指令数主要取决于内存延迟,这是性能的主要瓶颈。等待数据是不好的。处理器可以通过缓存、流水线和并发等技术在一定程度上缓解这个问题,但问题仍然存在,而且随着时间的推移只会变得更糟。

正确的实施可以产生巨大的不同。你可能想看看这个关于cache-friendly code的问题。

【讨论】:

【参考方案4】:

现代 CPU 是流水线指令处理,因此没有这样的常量。

但是,您可以在算法开始和结束时读出 CPU 滴答数。我认为这是通过这种测量所能达到的最低水平。

http://en.wikipedia.org/wiki/Time_Stamp_Counter

注意:为什么这不是 100% 准确存在很多问题,我可以提及的很少,但我相信社区将能够添加到列表中: -OS 抢占您的进程 -cache 未命中(算法第一次运行速度会变慢,如果随后运行会更快) - 在较旧的 CPU 上,CPU 滴答对 CPU 频率不是不变的

【讨论】:

除非(实际上)机器上根本没有运行其他任何东西,否则这通常根本不会很准确。时间戳计数器对于在单个时间片中运行的非常 段代码很有用。对于像一个完整程序这样的东西,从操作系统获取时间通常更有意义(例如,Linux 上的times 或 Windows 上的GetProcessTimes)。 在 unix 系统上,clock_gettime() 是首选方式,因为您可以指定如何测量时间(如果您真的需要,它甚至会映射到 RDTSC); C++11 或多或少将其合并到std::chrono【参考方案5】:

您可以在 Linux 中使用 Perf 工具。它易于使用。

要获取有关 CPU 周期、每周期指令 (IPC)、缓存命中/未命中等的统计信息,只需使用 Perf 运行您的程序。示例命令是

性能统计 -d <exename>

欲了解更多信息,请访问http://www.brendangregg.com/perf.html或https://perf.wiki.kernel.org/index.php/Tutorial

【讨论】:

以上是关于您如何测试您的计算机每秒可以执行多少条指令?的主要内容,如果未能解决你的问题,请参考以下文章

用「闪电侠」的例子解释一下进程和线程

ssl剖析及案例

基于 GPU 的显卡可以加速您的程序计算,如何?

cpu含有多少条指令

计算机速度GHz等于每秒多少次

i7 975EE与i7980XE两种CPU的峰值计算能力每秒多少次浮点运