c – 避免使用内联asm优化变量
作者:互联网
我正在阅读Preventing compiler optimizations while benchmarking,它描述了来自Chandler Carruths talk CppCon 2015: Chandler Carruth “Tuning C++: Benchmarks, and CPUs, and Compilers! Oh My!”的clobber()和escape()如何影响编译器.
通过阅读,我假设如果我有像“g”(val)这样的输入约束,那么编译器将无法优化掉val.但是在下面的g()中,没有生成代码.为什么?
如何重写notOottimize()以确保为g()生成代码?
template <typename T>
void doNotOptimize(T const& val) {
asm volatile("" : : "g"(val) : "memory");
}
void f() {
char x = 1;
doNotOptimize(&x); // x is NOT optimized away
}
void g() {
char x = 1;
doNotOptimize(x); // x is optimized away
}
解决方法:
确切地说,为g()生成代码意味着什么?如果你自己编写,你会写什么代码?说真的,这是一个真实的问题.在从编译器开始哄骗它之前,你必须决定你期望的输出.
无论如何,让我们来看看你现在拥有的东西.在f()中,
void f() {
char x = 1;
doNotOptimize(&x); // x is NOT optimized away
}
您正在获取x的地址,这会阻止优化器将其分配到寄存器中.它必须在内存中分配才能拥有一个地址.
但是,在g()中,
void g() {
char x = 1;
doNotOptimize(x); // x is optimized away
}
x只是一个局部变量,任何理智的优化器都会在寄存器中分配它,或者在这种情况下作为常量.这是允许的,因为你从不接受它的地址;你只是用它的价值.因此,例如,编译器可能会生成如下代码:
g():
mov al, 1 // store 1 in BYTE-sized register AL
...
或者在这种情况下根本不生成任何代码,并用它的常量值代替变量的任何使用.
你的doNotOptimize代码,
template <typename T>
void doNotOptimize(T const& val) {
asm volatile("" : : "g"(val) : "memory");
}
对val参数使用g约束,它表示它可以存储在通用寄存器,内存或常量中,无论优化器最方便.由于val是常量,当内联此调用时,优化器将其保留为常量.你的“内存”clobber说明符没有效果,因为这里没有修改内存.
所以,我们能做些什么?好吧,我们可以强制变量x在内存中分配,即使它不需要,也可以使用m约束:
template <typename T>
void doNotOptimize(T const& val) {
asm volatile("" : : "m"(val) : "memory");
}
void g() {
char x = 1;
doNotOptimize(x);
}
现在编译器无法优化x的存储,并被强制发出以下代码:
g():
mov BYTE PTR [rsp-1], 1
ret
请注意,这与声明x变量volatile会产生的效果基本相同.
还记得我刚开始提出的问题吗?那是你想要的输出吗?
或者,您可能希望编译器发出即时寄存器移动.如果是这样,r约束将起作用 – 或any of the x86-specific constraints允许您指定特定寄存器.这会强制优化器在寄存器中分配值,即使它不需要:
g():
mov eax, 1
ret
但是,我不能看出其中任何一个的意义.
如果你想制作一个测试使用单个const-reference参数调用函数的开销的微基准测试,那么更好的选择是确保调用的函数的定义对于优化器是不可见的.然后,它无法内联该功能并且必须安排进行呼叫,包括所有必要的设置.如果你只是studying how a compiler might emit that code,这也很有效.(当然,你不能使用模板功能.好吧,除非你想要abuse C++11’s extern
templates.)
标签:c,assembly,performance-testing,compiler-optimization,inline-assembly 来源: https://codeday.me/bug/20190727/1551854.html