如何不优化 - 愚蠢函数的机制
How not to optimize away - mechanics of a folly function
我正在寻找一种编程技术,以确保用于基准测试的变量(没有可观察到的副作用)不会被编译器优化
这提供了一些信息,但我最终使用了愚蠢和以下函数
/**
* Call doNotOptimizeAway(var) against variables that you use for
* benchmarking but otherwise are useless. The compiler tends to do a
* good job at eliminating unused variables, and this function fools
* it into thinking var is in fact needed.
*/
#ifdef _MSC_VER
#pragma optimize("", off)
template <class T>
void doNotOptimizeAway(T&& datum) {
datum = datum;
}
#pragma optimize("", on)
#else
template <class T>
void doNotOptimizeAway(T&& datum) {
asm volatile("" : "+r" (datum));
}
#endif
我想使用上述内容,但我对其工作原理知之甚少。我最感兴趣的是非VC++部分以及为什么/如何行
asm volatile("" : "+r" (datum));
创建一个不可优化的上下文,或者为什么人们会选择实现这样的事情。两种方法之间的比较也会很有趣(我不知道pragma optimize
是如何工作的,但它看起来像一个更干净的解决方案 - 虽然不便携)
标准方法可以停用优化,因此,如果您需要停用优化,则只能使用您的实现提供的任何功能。比较这两种方法没有意义,除非您找到支持这两种方法的编译器。
无论如何,在海湾合作委员会,
asm volatile("" : "+r" (datum));
表示用户提供的未经验证的汇编代码嵌入到 GCC 生成的汇编中。第一个字符串文字 (""
) 包含要注入的汇编代码。它是空的,所以实际上根本没有发出任何代码。
:
后面的部分通知 GCC 汇编代码的影响。 "+r" (datum)
意味着GCC应该假设汇编代码读取并修改datum
。即使它没有。这样做的原因是,任何最终将值存储在datum
中的早期计算都不能因为不必要的而丢弃。同时,汇编代码本身不能因为不必要而被丢弃,因为可能会对datum
进行修改。 volatile
还将汇编代码标记为不得优化的代码,如下所述:
GCC 的优化器有时会在确定不需要输出变量时丢弃
asm
语句。此外,如果优化器认为代码将始终返回相同的结果(即其输入值在调用之间没有变化),则可能会将代码移出循环。使用volatile
限定符将禁用这些优化。[...]
使用两种不同的方法来防止删除汇编代码似乎有点多,真的,但我想最好确定一下。
r
约束意味着代码并不关心GCC为汇编代码提供的寄存器,并记录在这里:
'r'
允许使用寄存器操作数,前提是它位于常规寄存器中。
+
修饰符意味着代码可以读取和写入datum
,并记录在这里:
"+"
表示此操作数由指令读取和写入。[...]
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++ 中的纯虚函数机制如何公开来自 DLL 的函数
- 派生类中函数参数变化的虚函数按常量类型在"function parameter"会破坏虚拟机制吗?
- C++:使用回调机制调用函数
- C++模板机制只是一个类型构建器函数吗
- 参考虚拟构造函数的虚拟函数机制
- 如何不优化 - 愚蠢函数的机制
- C++模板机制来获取函数参数的数量,这将适用于 lambda 和普通函数
- QPixmap的loadFromData函数使用了一些奇怪的缓存机制?
- java arraylist有任何类似c++vector capacity()的函数,或者机制不同
- 在虚拟析构函数的情况下,虚拟机制是如何工作的
- 虚函数机制
- 虚函数调用机制
- 具有私有构造函数的类的私有继承的工作机制
- 使C函数指针与C++中基于C样式堆栈的调用机制一起工作
- 当我从赋值操作符返回值时,首先,调用复制构造函数的机制和基础是什么?
- 为什么纯虚拟机制不考虑继承函数?