【问题标题】:Efficient bit masking code in C [closed]C中的高效位掩码代码[关闭]
【发布时间】:2012-10-15 21:20:08
【问题描述】:

由于 C 的位运算符 &|~ 通常也是汇编语言操作码,因此位掩码代码原则上应该非常快。

对于如何在模拟算法的内部循环中添加位掩码,我有一些选择。本质上,它归结为是使用一组预先封装好的掩码,还是使用左移和右移动态更改掩码。

是否有特殊的技巧/技术可以使位掩码尽可能避免不必要的开销?从效率的角度来看,以下三种方法中的任何一种是特别好还是坏?

  • 选项 1:循环遍历一组预装掩码,例如挑选特定的位

    unsigned char mask[8]={0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
    for(i=0;i<8;i++) {
        ...
        (mask[i] & mem_data )
        ...
    

    }

  • 选项 2:在每次循环迭代中向下移动多个位置

    unsigned char mask=0x80;
    for(i=0;i<8;i++) {
         ...
         mem_data & (mask>>i)
         ...
    }
    
  • 选项 3:在每次循环迭代中精确地向下移动一个位置

    unsigned char mask=0x80;
    while(mask) {
          ...
          mem_data & mask
          mask>>=1;
          ...
    }
    

编辑: 从示例中删除了 putchar(),以免分散问题的注意力

【问题讨论】:

  • 我认为对于其中任何一个,putchar 的价格会贵几个(至少 3-4 个)数量级,所以我不用担心。
  • 只需对其进行分析并找出答案。如果编译器为每一个生成非常相似的代码,我实际上不会太惊讶。
  • 那么...您给我们代码并希望我们为您分析它?
  • 一个很好的问题应该是“选项 x 比选项 y 快,这是为什么呢?” (怀疑)
  • 速度完全不重要。对于大多数通用处理器,所有算术/逻辑/按位运算都同样快。 (这对于嵌入式的东西可能有点不同)在 x86 上,如果它可以与总线和缓存流量并行执行,则该操作将不会花费任何周期。将花费循环的是分支(循环一两个,位条件一两个),这将破坏分支预测并耗尽前瞻。第一个 (LUT) 示例具有浪费缓存槽的额外缺点(但它可以甚至被优化掉)。 YMMV。措施。算了。

标签: c assembly bit-manipulation performance


【解决方案1】:

位掩码常用于嵌入式世界。

并非所有处理器都可以使用变量参数进行按位移位。例如,在 MSP430 处理器上,您一次只能位移一位。该实施将求助于软件以可变数量进行转移。在这种情况下,必须避免选择 2。更一般地查看程序的汇编输出以比较最有效的解决方案。

【讨论】:

  • 更不用说上述示例都不会导致执行任何位移。代码已完全优化,没有对 putchar 的展开调用。
  • @VladLazarenko 这完全取决于实现,我敢肯定并非所有实现都会展开循环。
  • 好答案。此外,值得注意的是选项 1 可能会产生数组偏移和/或其他指针操作(除非编译器展开循环)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多