【发布时间】:2021-12-19 18:16:41
【问题描述】:
我正在阅读https://iq.opengenus.org/cpp-likely-and-unlikely-attributes/,但我不理解/不同意一些事情。
-
在以下代码中:
void doModulus( vector<int> &vec , int mod ){ // here the value of mod we are passing is 224, vec is of size 1024 holding values in [1,255] for( int i = 0 ; i<vec.size() ; i++ ) { if( vec[i] >= mod ) [[unlikely]]{ // so we are prioritizing else statement here vec[i] = vec[i] % mod ; }else { vec[i] = vec[i] ; } } }
如果我们将 else 代码设为 [[likely]] 或者这会在后台自动发生,就好像一侧很可能,而另一侧不是,这是否重要或有什么不同? (虽然我希望如果一方不太可能,那么另一方(如果可能的话)很有可能。
- 提出以下声明:
% 操作对于 cpu 来说是一个计算量很大的操作,所以让我们 尝试优化我们的代码。
虽然“优化”是指添加 if else 条件,但我使用 chrono 测试了代码,似乎在没有 if-else 的情况下执行时间快了 2-3 倍...
另外我不明白为什么 % 很重,它只是关于读取数字的底部位。
【问题讨论】:
-
模是除法的余数,在算法上是不平凡的。它有多快或多慢取决于平台。但是分支机构有自己的相关成本。如果模数太慢,并且您只关心检查某些位,请考虑使用按位和屏蔽这些位,这是一个简单的操作,应该是大多数架构上最快的操作之一。无论哪种方式,除非性能有问题,否则我不会担心。
-
除以 224 的余数是不是“只是读取数字的底部位”。没有底部位可以指示
% 224的结果。 -
@DrewDormann %2 是最右边的位,%4 是最右边的 2 位...
-
虽然“优化”是指添加 if else 条件,但我使用 chrono 测试了代码,似乎在没有 if-else 的情况下执行时间快了 2-3 倍... 老实说,您的问题的其余部分更有趣,但是如果没有最小可重现示例,则无法回答;我仍然疯狂的猜测是你可能想看看这个:stackoverflow.com/a/11227902/2945027
-
@AlexGuteniev:在某些 CPU 上,值得进行分支以避免硬件划分,即使它错误预测了很多,比如 25% 甚至 50%。在具有更高吞吐量整数除法器的最新 Intel CPU(Ice Lake 等)上,收支平衡错误预测率可能更低。可能不值得仅仅为了避免乘法逆(以常数为模),即使它是签名的
int需要额外的工作,除非模式是完全可预测的。
标签: c++ cpu c++20 chrono micro-optimization