Owe*_*wen 16 c++ optimization reference c++11
如果我做
typedef void Cb();
int foo(int const& a, Cb cb) {
int x = a;
cb();
return x - a;
}
Run Code Online (Sandbox Code Playgroud)
并编译g++ -O3 -save-temps -c foo.cpp
,我看到减法被保留,而如果cb();
被注释掉,整个函数优化为
xorl %eax, %eax
Run Code Online (Sandbox Code Playgroud)
我可以对参数的规范做些什么,a
这样无论调用是什么,都可以优化减法cb()
,并且不会强制a
成为唯一的引用(即,它可能被引用到其他地方,但是没有那些引用会被修改)?
M.M*_*M.M 15
执行建议的优化是不正确的,因为其余代码可能是:
static int var;
void func()
{
var++;
}
// ...
foo(var, func);
Run Code Online (Sandbox Code Playgroud)
我不知道你可以设置任何特定于编译器的属性来表示cb()
不会修改a
.
pep*_*ico 15
有__restrict
扩展名,你可以在gcc.godbolt.org上试试这个:
typedef void Cb();
int foo(const int & __restrict a, Cb cb) {
int x = a;
cb();
return x - a;
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,只有clang进行优化,gcc不会这样做.
请注意,类似限制的别名被认为是C++标准的一部分:
也许将来你可以通过标准来做到这一点.
你为什么不在int x = a;
函数调用下面移动这一行?
如果cb()
既不影响x
也不a
应该这样做,我认为编译器会再次优化调用,因为x不能在两次调用之间改变.如果您无法重新排序这两个调用,则可能无法首先对其进行优化.
这不是你可以暗示编译器要做的事情,因为在调用之后无法保证x和a都没有改变cb()
.
将此视为读/写访问的顺序.如果没有读取或写入访问a
和x
过程中会发生cb()
,你可以做函数调用的手动重新排序.
如果a
或x
写入,则无法重新排序,并且优化不正确.
如果x
被读取,则不能对函数调用进行重新排序,但如果x
真正只读取,则可以从a读取,并且x
仅在调用之后定义,因为它具有与a
调用之前声明的值相同的值.
restrict
如果编译器支持该扩展,则可以在引用上使用C.
(某些编译器允许__restrict
或者__restrict__
,它们是实现命名空间的一部分.)
这是您向编译器的承诺,即对象在任何地方都没有别名,因此可以对其进行优化.
如果你对编译器撒了谎,那么你就得到了你应得的破解代码.
归档时间: |
|
查看次数: |
1658 次 |
最近记录: |