测试固定集是否相等且无分支

发布于 2024-10-21 06:21:11 字数 371 浏览 5 评论 0原文

我有一组整数 (x, y, z) 和一个采用 3 个整数 (u, v, w) 的函数。如何测试 (x,y,z) == (u,v,w) ?天真的方法是:

bool match = (x == u || x == v || x == w) && (y == u || y == v || y == w) && (z == u || z == v || z == w);

有人知道一些智能位运算/算术可以做同样的事情吗?

我可以假设 (x, y, z)(u, v, w) 都不包含重复项。

I have a set of integers (x, y, z) and a function that takes 3 integers (u, v, w). How can I test if (x,y,z) == (u,v,w)? The naive way is:

bool match = (x == u || x == v || x == w) && (y == u || y == v || y == w) && (z == u || z == v || z == w);

Does anyone know of some smart bit operations/arithmetic to do the same thing?

I can assume that neither (x, y, z) or (u, v, w) contain duplicates.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

沫雨熙 2024-10-28 06:21:11

在这种情况下,您可以用按位运算替换逻辑运算以消除分支:

bool match = (x == u | x == v | x == w)
           & (y == u | y == v | y == w)
           & (z == u | z == v | z == w);

但是,您必须测量性能影响以确定这是更快还是更慢。

In this case, you can replace the logical operations by bitwise operations to eliminate the branching:

bool match = (x == u | x == v | x == w)
           & (y == u | y == v | y == w)
           & (z == u | z == v | z == w);

However, you would have to measure the performance effect to see if this is faster or slower.

树深时见影 2024-10-28 06:21:11

您可以通过在进行实际测试之前转换为无符号并比较总和来预先消除一堆不相等的向量。

You can eliminate a bunch of unequal vectors up front by converting to unsigned and comparing the sums before doing the real test.

忆伤 2024-10-28 06:21:11

如果 a 和 b 相同,则 a^b 为零。因此,仅当 a 和 b 相同时 !(a^b) 才非零。假设您的平台可以在没有分支的情况下执行逻辑“not”,因此您可以使用单个分支测试 a 是否是 (u, v, w) 的成员:

if(!(a^u) | !(a^v) | !(a^w))

因此是否所有 (x, y, z) 都是成员(u, v, w) 的使用:

if(
    (!(a^u) | !(a^v) | !(a^w))) &
    (!(b^u) | !(b^v) | !(b^w))) &
    (!(c^u) | !(c^v) | !(c^w))))

即仅对各种结果执行按位与操作,并且再次仅执行单个分支。

如果您的平台需要一个分支来执行 !,例如,如果它本质上是作为 a 执行的? 0 : -1,那么这就是十个条件,并不比简单的解决方案更好。

If a and b are the same then a^b is zero. So !(a^b) is non-zero only when a and b are the same. Supposing your platform can do logical 'not' without a branch, you can therefore test whether a is a member of (u, v, w) with a single branch using:

if(!(a^u) | !(a^v) | !(a^w))

And hence whether all of (x, y, z) are members of (u, v, w) using:

if(
    (!(a^u) | !(a^v) | !(a^w))) &
    (!(b^u) | !(b^v) | !(b^w))) &
    (!(c^u) | !(c^v) | !(c^w))))

i.e. just doing a bitwise and on the various results, and again only a single branch.

If your platform needs a branch to perform !, e.g. if it's performed essentially as a ? 0 : -1, then that's ten conditionals and no better than the naive solution.

扬花落满肩 2024-10-28 06:21:11

在 C 语言中,没有分支就无法做到这一点。

如果您愿意内联汇编,可以使用一些 CMPXCHG 指令来完成此操作。

In C there is no way to do this without branching.

If you are willing to inline-assembly you can do this with some CMPXCHG instructions.

柏林苍穹下 2024-10-28 06:21:11

正如评论中所指出的,只要 (x,y,z) 中的所有元素都包含在集合 (u,v,w) 中,你的“天真的”方式就会匹配。如果您确实想测试这些集合是否相等,您可能需要

 (x==u && ((y==v && z==w) || (y==w && z==v))) ||
 (y==u && ((z==v && x==w) || (x==w && z==v))) ||
 (z==u && ((x==v && y==w) || (y==w && x==v)));


您可以快速过滤掉许多不匹配的情况,

  bad = (x+y+z) - (u+v+w);

某些处理器具有非分支“最小”和“最大”指令,这将允许您执行以下操作:

  a = min(x,y)
  b = max(x,y)
  c = min(b,z)
  x = min(a,c)
  y = max(a,c)
  z = max(b,z) 
  //repeat sorting sequence for u,v,w
  match = (x==u)&(y==v)&(z==w);

As pointed out in the comments, your 'naive' way matches whenever all the elements in (x,y,z) are contained in the set (u,v,w). If you really want to test if the sets are equivalent, you probably want

 (x==u && ((y==v && z==w) || (y==w && z==v))) ||
 (y==u && ((z==v && x==w) || (x==w && z==v))) ||
 (z==u && ((x==v && y==w) || (y==w && x==v)));


You can quickly filter out many mismatches with

  bad = (x+y+z) - (u+v+w);

Some processors have a non-branching 'min' and 'max' instructions, which would allow you to do

  a = min(x,y)
  b = max(x,y)
  c = min(b,z)
  x = min(a,c)
  y = max(a,c)
  z = max(b,z) 
  //repeat sorting sequence for u,v,w
  match = (x==u)&(y==v)&(z==w);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文