【问题标题】:How to use bit operations to replace modulu and division operators?如何使用位运算来代替模数和除法运算符?
【发布时间】:2012-11-26 16:40:13
【问题描述】:

我有这行代码:

 base_num = (arr[j]/base)%256;

这一行循环运行,操作“/”和“%”需要大量资源和时间来执行。我想更改此行并应用位操作以最大化程序性能。我该怎么做?

谢谢。

【问题讨论】:

  • base 是常数,还是会改变?
  • 如果编译器有价值,它会在比% 更快的每个平台上用&0xFF 替换%256base 的值是多少?
  • 您可以将base_num 声明为 8 位(无符号)整数
  • 基础变化值:base = (int)pow(256,(float)i);
  • @user1756004 呃,这不应该是这样计算的。 int base = 1 << (8*i);。但这会溢出相当小的iunsigned long long 可能是更好的选择。

标签: c++ c module bit-manipulation division


【解决方案1】:

如果 base 是 2 的 n 次方,您可以将除法替换为右移 n 位。然后,由于取整数的模 256 等价于取其最后 8 位,因此您可以将其与 0xFF 进行与运算。或者,如果您将其与 256*base 进行 AND 运算,然后将 n 向右移位,则可以反转操作。

base_num = arr[j] >> n;
base_num &= 0xFF;

当然,任何半体面的编译器都应该能够为您做到这一点。

【讨论】:

  • 你需要移动n位,2^n1 << n
  • kernel that dominatespow 函数(来自glibc 在顶部定义为(简化):if (base == 2) { return (1 << exp) }
  • 这是给你的new privilege:D
  • 是的,但是 base_num 不是 2 的 n 次方。像这样的基本变化:
  • base = (int)pow(256,(float)i);或者这个:base = 1
【解决方案2】:

-O1 或更高版本添加到您的编译器选项中,编译器将为您完成。

在 gcc 中,-O1 开启 -ftree-slsr,根据文档,

对树木执行直线强度降低。这可以识别涉及乘法的相关表达式,并在可能的情况下用成本较低的计算替换它们。

这将替换模数和基数(如果它是常数)。但是,如果您知道基数将是 2 的某个非常数幂,则可以重构周围的代码,以得到该数字的 log2,然后将 >> 减去 1。

【讨论】:

    【解决方案3】:

    您也可以将 base_num 声明为 8 位整数:

    #include <stdint.h>
    
    uint8_t base_num;
    uint16_t crap;
    crap = 0xFF00;
    base_num = crap;
    

    如果您的编译器符合标准,它会将byte(0xFF00) (0x00) 的值放入base_num

    我还没有遇到在纯 C(C++ 或 C#)中执行饱和算术的编译器,但如果有,它会将大于 0xFFsat_byte(0xFF00) 的值放入,它会将 @ 987654328@ 转为base_num

    请记住,您的编译器会警告您在这种情况下会丢失精度。在这种情况下,您的编译器可能会出错(Visual Studio 使用Treat Warnings as Errors On)。如果发生这种情况,您可以这样做:

    base_num = (uint8_t)crap;
    

    但这似乎是你想要避免的。

    您尝试做的似乎是删除模运算符,因为这需要除法,而除法是最昂贵的基本算术运算。我通常不会以任何方式将此视为瓶颈,因为任何“智能”编译器(即使在调试模式下)都会将其“优化”为:

    base_num = crap & 0xFF;
    

    在受支持的平台(我听说过的所有主流处理器 - x86、AMD64、ARM、MIPS)上,应该是任何平台。听到没有基本的 AND 和 OR 算术指令的处理器,我会傻眼的。

    【讨论】:

      猜你喜欢
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-12-29
      • 1970-01-01
      • 2019-05-31
      • 2011-05-30
      • 2011-05-08
      • 2012-09-14
      相关资源
      最近更新 更多