C++ 是C++;11+;编译器足够聪明,可以优化内部;如果;声明?
这最好用以下代码来描述:C++ 是C++;11+;编译器足够聪明,可以优化内部;如果;声明?,c++,optimization,compilation,branch,C++,Optimization,Compilation,Branch,这最好用以下代码来描述: void foo(vector<vector<int>>& a, vector<vector<int>>& b, bool flag) { vector<vector<int>> c; for (int i ...) { for (int j ...) { int value; if (fla
void foo(vector<vector<int>>& a, vector<vector<int>>& b, bool flag) {
vector<vector<int>> c;
for (int i ...) {
for (int j ...) {
int value;
if (flag)
value = a[i][j] + b[i][j];
else
value = a[i][j] - b[i][j];
}
}
}
void foo(向量&a、向量&b、bool标志){
载体c;
对于(int i…{
对于(int j…{
int值;
国际单项体育联合会(旗)
价值=a[i][j]+b[i][j];
其他的
值=a[i][j]-b[i][j];
}
}
}
在面值处,该标志在每个内部循环上进行求值和分支,尽管在任何一个循环之前已知。C++11+编译器会生成两个独立的代码路径,在开始时对分支进行求值,还是应该手动完成
在给我讲讲过早优化之前,请理解,这是为了让程序员对次要细节更加了解。这可能取决于示例的复杂性,但编译器能够进行此类优化。让我们来看一个简单而完整的示例:
extern bool get_bool()无例外;
extern int get_int()noexcept;
extern void foo1()无异常;
外部无效foo0()noexcept;
void foo()不例外{
bool b=get_bool();
int i_mx=get_int();
int j_mx=get_int();
对于(int i=0;i
如果我们用clang编译,生成的代码是:
foo(): # @foo()
push rbp
push r15
push r14
push r12
push rbx
call get_bool()
mov r14d, eax
call get_int()
mov r15d, eax
call get_int()
test r15d, r15d
jle .LBB0_9
mov r12d, eax
test eax, eax
jle .LBB0_9
xor ebx, ebx
test r14b, r14b
je .LBB0_3
.LBB0_6: # =>This Loop Header: Depth=1
mov ebp, r12d
.LBB0_7: # Parent Loop BB0_6 Depth=1
call foo1()
dec ebp
jne .LBB0_7
inc ebx
cmp ebx, r15d
jne .LBB0_6
jmp .LBB0_9
.LBB0_3: # =>This Loop Header: Depth=1
mov ebp, r12d
.LBB0_4: # Parent Loop BB0_3 Depth=1
call foo0()
dec ebp
jne .LBB0_4
inc ebx
cmp ebx, r15d
jne .LBB0_3
.LBB0_9:
pop rbx
pop r12
pop r14
pop r15
pop rbp
ret
很明显,
测试r14b,r14b
行被移到了循环之外。同样,根据代码的复杂性,您的里程数可能会有所不同。更好地检查生成的程序集是肯定的。 < P>在最新的C++标准中,优化方法很少(2021),例如拷贝删除和返回值优化。
这使得“编译器”可以应用任何特定于平台的优化
问题中的函数不产生任何效果,因此很可能被完全优化掉
但是为了解决(我假设的是)潜在的问题,一个典型的编译器将能够推断相同的条件甚至应用于嵌套循环,例如
int foo(vector<vector<int>> a, vector<vector<int>> b, bool flag) {
int value = 0;
for (int i = 0; i < a.size(); i++) {
for (int j = 0; j < a[i].size(); j++) {
if (flag)
value += a[i][j] + b[i][j];
else
value += a[i][j] - b[i][j];
}
}
return value;
}
这些东西的优化将如下所示
#include <iostream>
#include <vector>
#include <execution>
int main(int argc , char *argv[])
{
std::vector<std::vector<int>> b{{2,3} ,{4,7}};
std::vector<std::vector<int>> aq{{7,8} ,{2,17}};
std::for_each(std::execution::par, b.begin(), b.end() ,[&](auto& x){
for (auto& w : x)
w = aq[&x - b.data()][&w - x.data()];
});
std::cout << "and then " << b[0][1] << std::endl;
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
std::向量b{{2,3},{4,7};
std::载体aq{{7,8},{2,17};
std::for_each(std::execution::par,b.begin(),b.end(),[&](auto&x){
用于(自动&w:x)
w=aq[&x-b.data()][&w-x.data()];
});
为什么不自己试试呢?gcc会将代码优化为零,所以会非常快:几乎所有这类问题的答案都是“是”.@Bathsheba我真的很喜欢评论部分。@Evg:我确定我理解这个问题是为了在发布链接之前,让程序员更加了解一些小细节。
#include <iostream>
#include <vector>
#include <execution>
int main(int argc , char *argv[])
{
std::vector<std::vector<int>> b{{2,3} ,{4,7}};
std::vector<std::vector<int>> aq{{7,8} ,{2,17}};
std::for_each(std::execution::par, b.begin(), b.end() ,[&](auto& x){
for (auto& w : x)
w = aq[&x - b.data()][&w - x.data()];
});
std::cout << "and then " << b[0][1] << std::endl;
}