从uint64_t数组中屏蔽掉不需要的位

时间:2013-10-22 09:43:52

标签: c++ bit-manipulation vectorization simd intrinsics

我有一个8 uint64_t(512位)的数组。我还收到2个数字作为函数参数。   让他们分别是54和133。   我需要掩盖位置(基于零)低于54或高于133的每一位。

最具成本效益的方法是什么?

使用一个uint64_t很容易做到。

int a=6;
int b=12;
uint64_t source=0xD0400000000000;
uint64_t mask=0xFFFFFFFFFFFFFFFF;
uint64_t result=source&((mask<<(a+63-b))>>a);//D0000000000000

但是数据大于uint64_t(在这种情况下是数组)存在问题。   另外,另一个问题是当这些位我想要提取多个uint64_t的交叉边界时 这段代码必须非常快,所以我必须避免分支或任何昂贵的操作。

有没有办法用内在函数实现它以使其快速执行?

1 个答案:

答案 0 :(得分:0)

无论你喜欢与否,你都需要特殊处理 第一个和最后一个数组元素,if。 基本上,你必须将你的第一个和最后一个转换为 位数/数组索引对,并从那里开始工作。掩盖 除了指定范围之外的所有东西,你都可以将所有东西都扯掉 第一个数组索引,并在最后一个(可能使用 std::fill),并特别处理第一个和第二个元素 最后一个数组索引(可能是相同的,这反过来又需要 特殊处理,与它们的情况不同 不同)。非常粗略(并且没有任何错误处理):

//  quot is element index,
//  rem is bit number in element.
div_t first = div( firstBitNumber, bitsInWord );
div_t last = div( lastBitNumber, bitsInWord );
std::fill( array.begin(), array.begin() + first.quot, 0 );
if ( first.quot == last.quot ) {
    array[ first.quot ] &= ((1 << last.rem) - 1) & ~((i << first.rem) - 1);
} else {
    array[ first.quot ] &= ~((i << first.rem) - 1);
    array[ last.quot ] &= ((1 << last.rem) - 1);
}
std::fill( array.begin() + last.quot + 1, array.end(), 0 );

您可能需要使用移位运算符进行一些转换 为了确保它们使用数组元素的完整大小。 当然,你绝对想要确保第一个和最后一个 在任何此之前都处于界限之内。