我正在寻找以64位整数排列位的最快方法。
给定一个名为“array”的表,对应于一个排列数组,意味着它的大小为64,并且填充了0到63之间的唯一数字(即没有重复),对应于64位整数中的位位置,I可以这样排列位
bit = GetBitAtPos(integer_, array[i]);
SetBitAtPos(integer_, array[i], GetBitAtPos(integer_, i));
SetBitAtPos(integer_, i, bit);
(by looping i from 0 to 63)
GetBitAtPos being
GetBitAtPos(integer_, pos) { return (integer >>) pos & 1 }
Setbitatpos也基于相同的原则(即使用C运算符), 形式为SetBitAtPos(整数,位置,bool_bit_value)
如果可能,我正在寻找更快的方法来执行此任务。我愿意接受任何解决方案,包括必要时的内联汇编。我很难找到比这更好的方法,所以我想我会问。
我想执行这样的任务来隐藏64位生成的整数中的数据(其中第一位4可以显示信息)。它比一个XOR模板imo(除非我错过了一些东西)要好一些,主要是因为有人试图找到相关性。 它还允许进行逆操作,不会丢失宝贵的位......
但是我觉得这个操作有点贵......
由于
答案 0 :(得分:1)
由于排列是不变的,你应该能够提出一种比逐个移动位更好的方法(如果你可以发布你的秘密排列,我就可以去了)。最简单的改进是在输入和输出中同时移动具有相同距离(可以是模块化距离,因为您可以使用旋转)的位。如果这样的群体很少,这是一种非常好的方法。
如果这样做不如你所希望的那么好,看看你是否可以使用bit_permute_step来移动全部或大部分位。有关更多想法,请参阅该网站的其余部分。
如果你可以使用PDEP和PEXT,你可以移动位中的位,其中位之间的距离可以任意改变(但它们的顺序不能)。它是afaik,虽然它们的速度有多快(但它们尚未可用)。
最好的方法可能是其他答案中提到的这些和其他技巧的组合。
有太多的可能性来探索它们,真的,所以你可能不会找到最好的方式进行排列,但是使用这些想法(以及发布的其他想法)你无疑可以找到比你现在使用的更好的东西。
PDEP和PEXT已经有一段时间了,因此它们的性能已知,在3个周期的延迟和1个/周期的吞吐量下,它们比大多数其他有用的置换原语(除了普通的原语之外)更快。
答案 1 :(得分:0)
答案 2 :(得分:0)
对于64位数字,我认为(由于存在大量可能性)(找到最佳算法)的问题可能无法解决。最具可扩展性和最容易自动化的一个是查找表:
result = LUT0[ value & 0xff] +
LUT1[(value >> 8) & 0xff] +
LUT2[(value >> 16) & 0xff] + ...
+ LUT7[(value >> 56) & 0xff];
可伸缩性来自于可以使用任意数量的查找表(实际范围从3到32?)的事实。此方法容易受到缓存未命中的影响,并且无法并行化(至少对于大型表大小)。
如果存在某些对称性,可以使用一些聪明的技巧 - 例如在英特尔交换两位:
test eax, (1<<BIT0 | 1<<BIT1)
jpe skip:
xor eax, (1<<BIT0 | 1<<BIT1)
skip:
这个OTOH极易受到分支错误预测的影响。