【问题标题】:C++20 Likely and UnLikely?C++20 可能和不太可能?
【发布时间】:2021-12-19 18:16:41
【问题描述】:

我正在阅读https://iq.opengenus.org/cpp-likely-and-unlikely-attributes/,但我不理解/不同意一些事情。

  1. 在以下代码中:

    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]] 或者这会在后台自动发生,就好像一侧很可能,而另一侧不是,这是否重要或有什么不同? (虽然我希望如果一方不太可能,那么另一方(如果可能的话)很有可能。

  1. 提出以下声明:

% 操作对于 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


【解决方案1】:

如果我们制作 else 代码 [[likely]] 或者这会在后台自动发生,就好像一侧很可能,而另一侧没有,这是否重要或有什么不同?

C++ 标准可能只是推荐的做法示例。见[dcl.attr.likelihood]。因此,如何实际使用它们取决于实现。

虽然推荐的做法示例暗示只需要一个标记,而观察到差异的编译器似乎也暗示了这一点。

另外我不明白为什么 % 很重,它只是读取数字的底部位。

仅适用于 2 的幂。但应该知道,在编译时是二的幂。对于已知的非 2 次幂常数 (Why does GCC use multiplication by a strange number in implementing integer division?),还有一种方法可以降低此操作的成本。

对于运行时值来说,它很重,是除法。

由于不断传播,优化器可能知道某个值。然后应用优化。

【讨论】:

  • “只求二的幂”为什么?任何数字都可以这样做,只需到附近的 2 的更高次方...
  • @Algo - 认真的吗? 9 模 3 是 0,而 9 模 4 是 1。请问现在的算法是什么?
猜你喜欢
  • 1970-01-01
  • 2019-01-18
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 2012-06-10
  • 2016-04-13
  • 2014-02-17
  • 2011-02-13
相关资源
最近更新 更多