C 使用条件循环每个数字的最快方法

C 使用条件循环每个数字的最快方法,c,performance,bit-manipulation,bitwise-operators,C,Performance,Bit Manipulation,Bitwise Operators,给定一个64位整数,其中要计算的最后52位和要忽略的前导12位,循环7位打开和所有其他位关闭的每个组合的最快方法是什么 例如: 第一排列: 0[x57]1111111 最后排列 00000000000011111110[x45] 其中0[xn]表示noff(零)位 速度是绝对关键的,我们希望尽可能节省每一个时钟周期,因为它是需要在合理的时间内评估数十亿个状态的更大解决方案的一部分 不需要有效的解决方案,但是一些伪代码就可以了:)您需要的是一个好的算法,它可以在最短的时间内将您从一个排列带到下

给定一个64位整数,其中要计算的最后52位和要忽略的前导12位,循环7位打开和所有其他位关闭的每个组合的最快方法是什么

例如:

第一排列:

0[x57]1111111
最后排列

00000000000011111110[x45]
其中
0[xn]
表示
n
off(零)位

速度是绝对关键的,我们希望尽可能节省每一个时钟周期,因为它是需要在合理的时间内评估数十亿个状态的更大解决方案的一部分


不需要有效的解决方案,但是一些伪代码就可以了:)

您需要的是一个好的算法,它可以在最短的时间内将您从一个排列带到下一个排列

现在,我想到的第一个算法是用七个循环遍历所有组合

  • 第一个循环通过52位,为下一个循环设置一位
  • 第二个循环通过设置1之后的位,为第三个循环设置1
  • …ect
这将为您提供最快的迭代。下面是一些伪C++代码:

__int64 deck;
int bit1, bit2, bit3, ...;
for (bit1=0;bit1<52-6;bit1++) {
  for (bit2=bit1+1;bit2<52-5;bit2++) {
    ...
      for (bit7=bit6+1;bit7<52;bit7++) {
        deck = (1<<bit1)+(1<<bit2)+(1<<bit3)+...;  // this could be optimized.
        // do whatever with deck
      }
    ...
  }
}

我想你会对这篇文章感兴趣:


它以非常有效的方式解决您的问题。

我认为每个排列之间都有关系

我们可以看到这个数字随着一种模式的排列而增加

这一数学并非适用于所有解决方案,但适用于某些解决方案,希望能说明我的意思:

Permutation 3 difference = ((3%7+1)^2) * (roundUp(3/7) = 16
Permutation 10 difference = ((10%7+1)^2) * (roundUp(10/7) = 32
因此,我们将从绝对值循环:

int perm = 1;
for int64 i = 127; perm < totalPermutations
{
    i = i + ((perm%7+1)^2) * (roundUp(perm/7);
    perm++;
}
int perm=1;
对于int64,i=127;置换<总置换
{
i=i+((perm%7+1)^2)*(综述(perm/7);
perm++;
}

同样,数学是错误的,但给出了一个想法,我相信这是可能的。至于它是否优于按位运算,则必须进行测试。

只是要澄清,所有数字的作用域是只有七个设定位,还是只有七个连续位?例如,0[x54]1110010111,0[x30]10[x26]111111所有7位的组合都设置为最大值,而不是连续的。例如,一个可能是000…1100…1…01。在最后52位内始终设置有7位。作为解决方案,如果有一个循环将整数设置为从第一个置换(127)到最后一个置换(4468415255281664)的值,我相信这是一个关系(模数置换#乘以7时,可能是一个比例因子或固定的加法)这可以用于获得下一个排列。我会倾向于Alexander的方法。优化后,内部循环看起来更快。单步走可以证明是正确的。但是-你是否同样重视你对组合的评估?也就是说,你是否再次剥开位?如果是,可能是位模式不是正确的表示法。请注意:此算法在前52位上运行,而不是最后一位。一个简单的修复方法是调整位移位操作。回答很好,谢谢。我确实认为还有更多的解决方案,但我写的答案可能是错误的,但可能会给你一个解决此问题的不同方法的想法请注意,我的答案太模糊了,我会写在问题注释中。我已经对我的问题写了一条注释,如果我的注释可信,它可能会优于7个嵌套循环吗?我会这样做的。内部循环可以展开,“外部”循环比特在它的外部或外部。此外,内部比特的移动可以通过1个移位来完成。快速一看,我想:“碰撞检测?WTF?”+1。每次我读到那个博客时,我都会想“我应该更经常地读这个。”然后我就忘了它,直到我再次读到它。我真的应该更经常地读它;-)回到主题上来,这是解决问题的一种非常有趣的方法。嗯……每次迭代七次操作。效率会更高。谢谢你,优秀的文章,我会完整地阅读它,就像一个问题一样,这会和我在问题评论中概述的解决方案一样快吗?如果不快的话?@Tom我真的不知道我的数学很糟糕,我还没有计算出一个工作公式,所以我还不知道:)如果我能找到它,我会把它贴在这里
int perm = 1;
for int64 i = 127; perm < totalPermutations
{
    i = i + ((perm%7+1)^2) * (roundUp(perm/7);
    perm++;
}