c++ - 我不明白 DoNotOptimizeAway 的定义

标签 c++ benchmarking microbenchmark

我正在查看 Celero git repository DoNotOptimizeAway 的含义。但我还是不明白。你能帮我用外行的方式理解它吗?尽你所能。

The celero::DoNotOptimizeAway template is provided to ensure that the optimizing compiler does not eliminate your function or code. Since this feature is used in all of the sample benchmarks and their baseline, it's time overhead is canceled out in the comparisons.

最佳答案

您没有包含定义,仅包含文档。我认为您是在寻求帮助以了解它存在的原因,而不是定义。

它阻止编译器从重复循环中进行 CSEing 和提升工作,因此您可以重复相同的工作足够多次以达到可测量的程度。例如在运行 10 亿次的循环中放一些短的东西,然后您可以轻松地测量整个循环的时间(一秒左右)。有关在 asm 中手动执行此操作的示例,请参见 Can x86's MOV really be "free"? Why can't I reproduce this at all?。如果你想要这样的编译器生成的代码,你需要一个像 DoNotOptimizeAway 这样的函数/宏。

在禁用优化的情况下编译整个程序将毫无用处:在 C++ 语句之间存储/重新加载所有内容会产生截然不同的瓶颈(通常是存储转发延迟)。见 Adding a redundant assignment speeds up code when compiled without optimization

另请参阅 Idiomatic way of performance evaluation? 了解一般的微基准测试陷阱


也许查看实际定义也会有所帮助。

此问答 (Optimization barrier for microbenchmarks in MSVC: tell the optimizer you clobber memory?) 描述了 DoNotOptimize 宏的一种实现方式(并询问如何将其从 GNU C++ 移植到 MSVC)。

escape 宏来自 Chandler Carruth 的 CppCon2015 演讲 "Tuning C++: Benchmarks, and CPUs, and Compilers! Oh My!"。该演讲还详细说明了编写微基准测试时为什么需要它:在启用优化的情况下进行编译时阻止整个循环进行优化。

(如果有问题,让编译器将事情从循环中提升出来而不是重复计算它们会更难解决问题。如果函数足够大而不是不需要,则创建一个函数 __attribute__((noinline)) 会有所帮助内联。检查编译器的 asm 输出以查看它提升了多少设置。)


顺便说一句,GNU C/C++ 的良好定义通常具有零额外成本:
asm volatile("" :: "r"(my_var)); 编译为零 asm 指令,但要求编译器在其选择的寄存器中具有 my_var 的值。 (并且由于 asm volatile ,必须在 C++ 抽象机中“运行”那么多次)。

这只会影响优化,前提是编译器可以将其所属的计算转换为其他内容。 (例如,在循环计数器上使用它会阻止编译器仅使用指针增量并与结束指针进行比较以执行正确的 for(i=0;i<n;i++) sum+=a[i]; 迭代次数

使用像 asm volatile("" :"+r"(my_var)); 这样的读-修改-写操作数会强制编译器忘记所有它知道的关于该值的范围限制或常量传播信息,并将其视为传入函数 arg。例如它是 42 ,或者它是非负的。这可能会对优化产生更大影响。


当他们说“开销在比较中被抵消”时,他们希望不是在谈论从单个计时结果中显式减去任何东西,也不是在谈论 DoNotOptimizeAway 本身的基准测试。

那是行不通的。现代 CPU 的性能分析不会通过将每条指令的成本相加来进行。乱序流水线执行意味着,如果前端(总指令吞吐量)不是瓶颈,而且它所需的执行单元也不是,则额外的 asm 指令可以轻松实现零额外成本。

如果他们的可移植定义类似于 volatile T sink = input; ,那么额外的 asm 存储只有在您的代码在缓存的存储吞吐量上出现瓶颈时才会产生成本。

所以关于抵消的说法听起来有点乐观。正如我上面所解释的,加上上面的上下文/优化相关因素。有可能是 DoNotOptimizeAway )


相同功能的相关问答:

关于c++ - 我不明白 DoNotOptimizeAway 的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52203710/

相关文章:

c++ - 为什么 string::resize 和 string::substr O(1)

c++ - 在 C++ 中读/写二进制文件

c++ - Google 基准测试结果中显示的时间没有意义

缓存命中、未命中和预测 - 对性能的影响

macos - nanotime 在 MacOS 上有什么作用?

c++ - 如何用QToolButton正确管理文本和图标?

c++ - 了解追加模式下的闪存文件系统磨损

正则表达式库基准测试

c++ - 简单 for 循环中的大量时间损失

c++ - 为什么我从编译器得到 "expected unqualified-id before »}«"?