【问题标题】:Using bitwise operations使用按位运算
【发布时间】:2013-10-21 14:23:57
【问题描述】:
  • 您多久使用一次按位运算“hacks”来执行某种操作 优化?它在什么样的情况下真正有用?

示例:而不是使用 if:

if (data[c] >= 128) //in a loop
    sum += data[c];

你写:

int t = (data[c] - 128) >> 31;
sum += ~t & data[c];

当然,假设它针对这种特定情况会产生相同的预期结果。

  • 值得吗?我觉得不可读。你多久遇到一次 这?

注意:我在所选答案中看到了此代码:Why is processing a sorted array faster than an unsorted array?

【问题讨论】:

  • 数组排序了吗?数据满足 if 语句的频率是多少? 50%、25%、75%?
  • 在另一个问题中,排序使它更有效..但我问的是使用按位运算来做同样的优化而不排序或使用 if()..我更关心可读性以及是否是矫枉过正
  • 视情况而定。 if 语句每秒使用 1,000,000 次吗? (夸张)在信号处理等处理能力会导致瓶颈的某些应用中,按位运算非常有用。
  • 我很少做这样的事情,如果我做这样的事情,我会大量评论它以包括它所做的正常可读版本以及原因优化。然而,几乎从不需要这样的优化。

标签: c optimization bit-manipulation conditional-statements


【解决方案1】:

在某些情况下,使用此类 hack 可能会很有用。例如,他们可以删除一些 Java 虚拟机“优化”,例如分支预测器。我发现它们在少数情况下只有一次有用。主要的是乘以-1。如果您在一个庞大的阵列上执行数百次,那么简单地翻转第一位比实际多次翻转更有效。我用它的另一个例子是知道一个数字是否是 2 的幂(因为它很容易用二进制计算出来。)基本上,当你想作弊时,位黑客很有用。这是一个人类的类比。如果您有数字列表并且需要知道它们是否大于 29,您可以自动知道第一个数字是否大于 3,那么整个数字是否大于 30,反之亦然。按位运算只是让您可以执行类似于二进制的作弊。

【讨论】:

    【解决方案2】:

    虽然该代码是显示正在发生的事情的绝佳方式,但我通常不会使用这样的代码。如果必须要快,通常会有更快的解决方案,例如在 x86 上使用 SSE 或在 ARM 上使用 NEON。如果这些都不可用,当然,我会使用它,只要它有帮助并且是必要的。

    顺便说一下,我解释一下它是如何工作的in this answer

    与 Skylion 一样,我经常使用的一件事是弄清楚一个数字是否是 2 的幂。想一想你会怎么做……然后看看这个:(x & (x - 1)) == 0 && x != 0

    我想你第一次看到它时会觉得很棘手,但是一旦你习惯了它,它就会比任何不使用位数学的替代方案简单得多。它之所以有效,是因为从数字中减去 1 意味着借位从数字的最右端开始并贯穿所有零,然后在第一个变成零的 1 处停止。将该数字与原始数字进行与运算,然后使最右边的 1 为零。 2 的幂只有一个 1,它消失了,留下零。所有其他数字将至少有一个 1,除了零,这是一种特殊情况。一个常见的变体不会测试零,并且可以将其视为 2 的幂,或者知道不会发生零。

    同样地,您可以使用 bitmath 轻松完成其他一些事情,但如果没有它就不会那么容易了。正如他们所说,为工作使用正确的工具。有时位数学是正确的工具。

    【讨论】:

      【解决方案3】:

      按位运算非常有用,教授。 Knuth 写了一本关于他们的书:http://www.amazon.com/The-Computer-Programming-Volume-Fascicle/dp/0321580508

      仅举几个最简单的例子:int 乘以和除以 2 的幂(使用左移和右移),mod 相对于 2 的幂,掩码等等。使用按位运算时,请务必提供足够的 cmets 来了解正在发生的事情。

      但是,您的示例 data[c]>128 不适用于 IMO,请保持这种方式。 但如果你想计算data[c] % 128,那么data[c] & 0x7f 会快得多(其中& 表示按位与)。

      【讨论】:

        猜你喜欢
        • 2018-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多