测试固定集是否相等而不分支

时间:2011-03-09 20:55:52

标签: c++ c bit-manipulation

我有一组整数(x,y,z)和一个取3个整数(u,v,w)的函数。如何测试if(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)都不包含重复项。

5 个答案:

答案 0 :(得分:3)

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

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

但是,您必须测量性能效果,看看它是更快还是更慢。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

如果a和b相同,则a^b为零。因此!(a^b)仅在a和b相同时才为非零。假设您的平台在没有分支的情况下可以执行逻辑“非”,那么您可以使用以下命令测试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的形式执行,那么这就是十个条件,并没有比天真的解决方案更好。

答案 3 :(得分:0)

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

如果您愿意进行内联汇编,可以使用一些CMPXCHG说明执行此操作。

答案 4 :(得分:0)

正如评论中所指出的,只要(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);

某些处理器有非分支'min'和'max'指令,可以让你做

  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);