【问题标题】:Bitwise equality按位相等
【发布时间】:2011-01-13 03:19:33
【问题描述】:

我需要在两个字节之间执行按位相等。这意味着,例如,如果我有两个字节:00011011 和 00011110,则结果为 11111010 我看到的唯一快速方法是使用以下语句

byte a, b;//set input bytes
byte c = ~(a^b);//output bytes

但我想知道是否有更快的解决方案。在这些相等操作之后,我想屏蔽我需要的位。所以我需要使用 AND 操作。于是代码变成了:

byte a, b;//set input bytes
byte m;//mask, intresting bits are set to 1, others to 0
byte c = (~(a^b))&m;//output bytes

难道没有更快更简单的方法不需要使用所有这些按位运算,因为这部分代码会被非常频繁地调用。

【问题讨论】:

  • 我在 Mono/C#.Net 中工作,但我认为 C 系列中任何语言的语法都是等效的,并不那么重要。
  • 比位运算快吗?你真的在开玩笑吗?
  • 等等。您想要比两个按位操作“更快”的东西,两个直接实现您描述的语义的操作?嗯?
  • 为什么您认为您的语言的运算符 == 不够好?
  • 像这样的按位运算通常非常非常快 - 您有什么证据表明您需要优化它们?

标签: c# c optimization bit-manipulation


【解决方案1】:

您在寻找错误的地方进行此优化;您最终不会在这里找到任何更好的按位运算。即使你这样做了,它也几乎不会加速任何事情。真正的胜利将来自一次处理的不仅仅是一个字节。处理器已经不得不做一堆位移和屏蔽操作,以便它可以假装你正在处理字节。一次处理 1 个字的字节数组,或使用矢量指令(如果可用)。

【讨论】:

    【解决方案2】:

    你想要的是一个 XNOR 操作。不幸的是,C#/Mono 不支持这一点。我认为您的解决方案是最佳的。

    【讨论】:

    • 如果 MS JIT 编译器能够将 ~(a^b) 优化为 XNOR,我不会感到惊讶。 CommuSoft 应该查看生成的汇编代码,看看是否是这种情况。
    • 这是个好主意。我很想知道这是否也被优化了。
    • 我在 VS2008 中打开了 Debug/Windows/Disassembly 窗口以查看生成了哪些程序集,我看到了一个 XOR 语句和一个 NOT 语句。这意味着它没有被优化。但是,我们只讨论了 2 条汇编指令:这非常快。
    • 那太糟糕了。感谢您的调查。
    【解决方案3】:

    说实话,这些操作似乎足够快。我认为您不应该尝试进一步优化它们,而是先完成您的软件,看看您是否对整体性能感到满意,如果不满意,请使用分析器。我很确定问题出在其他地方。

    【讨论】:

      【解决方案4】:

      我怀疑它可以在更少的操作中完成。这看起来是最优的。也许您可以将 ~(a^b) 存储在查找表中(256*256 个条目)?我怀疑你会得到很多好处,甚至可能让事情变得更糟,但你可以尝试一下。

      【讨论】:

      • 你做了基准测试吗?理论上 ~(a^b) 可能会更快,它可能在两个周期和管道中执行得很好,对内存的索引查找可能需要几个周期。
      • OP 应该注意,编译器为索引表执行的操作可能至少与直接计算结果的操作一样昂贵(可能更多)。这还没有考虑到额外的内存访问。
      • 缓存未命中比算术运算慢 2 个数量级。
      • 当查找表和实际输入字节数组适合同一缓存行时,此操作应该很快。但是,我希望 ~(a^b) 也一样快(它甚至可能被 JIT 编译器优化)。
      猜你喜欢
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2017-06-06
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      相关资源
      最近更新 更多