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;
}