模拟属性"unpredictable"



现代C++中有[[likely]][[unlikely]]属性。G++和clang++中都有相应的CCD_ 3和CCD_。但也有__builtin_unpredictable(x)__builtin_expect_with_probability(x, 1, 0.5)或(同样)__builtin_expect_with_probability(x, 0, 0.5)内置,这告诉编译器防止CPU用来自(错误)预测分支的指令填充管道,因为管道从错误预测路径恢复的flush+成本在统计上大于完全没有推测执行的执行。

ifelse分支上使用[[likely]]或相等的[[unlikely]]属性(如以下片段)是否等效于使用假设的[[unpredictable]]属性?

if (x) [[likely]] {
// "if" branch
} else [[likely]] {
// "else" branch
}

if (x) [[unlikely]] {
// "if" branch
} else [[unlikely]] {
// "else" branch
}

如我所知,如果有else,编译器默认将if分支视为[[likely]],如果没有else,则将[[unlikely]](因为它通常是早期退出当前函数的不愉快路径检查的形式)。所以,如果我只是省略其中一个属性,那么指定假设的[[unpredictable]]属性就不等价了。

似乎用likely标记ifelse分支都会收到警告(unlikely相同):

main.cpp:9:27: warning: both branches of ‘if’ statement marked as ‘likely’ [-Wattributes]
9 |             if (i*j == p) [[likely]]
|                           ^~~~~~~~~~
10 |                 return 0;
11 |             else [[likely]]
|                  ~~~~~~~~~~

所以我想这个问题仍然是假设性的。对于最小完整示例,g++似乎支持[[likely]][[unlikely]],但不支持__builtin_unpredictable。类似地,clang++支持__builtin_unpredictable,但不支持[[likely]]__builtin_expect(x, 1)0(至少clang 10不支持。因此,比较所有三个选项是很棘手的。下面是一个比较[[likely]][[unlikely]]的最小完整示例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
bool isPrime(int p) {
for (int i=2;i<p;i++)
for (int j=2;j<p;j++)
if (i*j == p) [[likely]]
return 0;
// else [[unlikely]] <--- gets a warning
//     j++; <--- remove from for loop 
return 1; }
int main(int argc, char **argv) {
int numPrimes=0;
int start=atoi(argv[1]);
int end=atoi(argv[2]);
for (int p=atoi(argv[1]);p<atoi(argv[2]);p++)
if (isPrime(p)) { numPrimes++;}
printf("There are %d primes between %d and %d",numPrimes,start,end);
}

以下是评估:

$ g++ -std=c++2a -O3 main.cpp -o main
$ time ./main 2 10000
There are 1229 primes between 2 and 10000
real    1m16.083s
user    1m14.014s
sys 0m0.247s
$ sed -i "s/likely/unlikely/g" main.cpp
$ g++ -std=c++2a -O3 main.cpp -o main
$ time ./main 2 10000
There are 1229 primes between 2 and 10000
real    0m38.277s
user    0m38.100s
sys 0m0.012s

相关内容

  • 没有找到相关文章

最新更新