Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 分支预测优化_C++_Optimization_G++_Branch_Prediction - Fatal编程技术网

C++ 分支预测优化

C++ 分支预测优化,c++,optimization,g++,branch,prediction,C++,Optimization,G++,Branch,Prediction,我试图理解gcc/clang对这段代码做了什么样的神奇优化 #include <random> #include <iostream> int main() { std::random_device rd; std::mt19937 mt(rd()); const unsigned arraySize = 100000; int data[arraySize]; for (unsigned c = 0; c < array

我试图理解gcc/clang对这段代码做了什么样的神奇优化

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    const unsigned arraySize = 100000;
    int data[arraySize];

    for (unsigned c = 0; c < arraySize; ++c)
        data[c] = mt() % 256;

    long long sum = 0;

    for (unsigned i = 0; i < 100000; ++i)
    {
        for (unsigned c = 0; c < arraySize; ++c)
        {
            if (data[c] >= 128)
                sum += data[c];
        }
    }
    std::cout << sum << std::endl;
}
#包括
#包括
int main()
{
std::随机_装置rd;
标准:mt19937 mt(rd());
const unsigned arraySize=100000;
int数据[arraySize];
for(无符号c=0;c=128)
总和+=数据[c];
}
}

std::cout这是gcc的输出(使用gcc.godbolt.org,带有-O3)

您可以看到它执行比较“cmpl$127,$ecx”,但是在比较之后它没有分支。相反,它总是添加(在比较上方的行中使用“addq”),然后根据比较使用添加的结果(感谢“cmovg”“conditional move”指令)


它避免了内部循环中的分支,因此性能不依赖于分支预测。因此,对输入进行排序(如第二个示例中所做的那样)没有什么区别。

您看过汇编程序的输出了吗(真想不到发布了它?)-我还假设您正在对苹果进行比较,并且您已经尝试了使用相同库的相同硬件上的新旧编译器的输出?在编译这两个编译器时使用了哪些标志?在第二个示例中,您正在对数组进行排序。一旦您开始命中127以上的数据,您将始终调用
+=
操作符。这个操作应该被缓存,因为你每次迭代都在做。我读了一篇非常好的文章,解释了保持内存和操作“热”以提高性能的好处。@user657267-std=c++11-O3A常见的误解是,这是分支预测,而不是预测。
#include <random>
#include <iostream>
#include <algorithm>
int main()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    const unsigned arraySize = 100000;
    int data[arraySize];

    for (unsigned c = 0; c < arraySize; ++c)
        data[c] = mt() % 256;

    std::sort(data, data + arraySize);
    long long sum = 0;

    for (unsigned i = 0; i < 100000; ++i)
    {
        for (unsigned c = 0; c < arraySize; ++c)
        {
            if (data[c] >= 128)
                sum += data[c];
        }
    }
    std::cout << sum << std::endl;
}
.L4: //Inner loop
    movslq  (%rax), %rdx
    movq    %rdx, %rcx
    addq    %rsi, %rdx
    cmpl    $127, %ecx
    cmovg   %rdx, %rsi
    addq    $4, %rax
    cmpq    %rdi, %rax
    jne .L4