在c++中存储和访问N维位数组中单个位的最快方法是什么?

What is the fastest way to store and access single bits in an N dimensional array of bits in c++?

本文关键字:单个位 方法 是什么 数组 存储 c++ 访问      更新时间:2023-10-16

我有一个代码,我需要以随机的方式从一个大的位数组(总共几兆字节)中读写单个数据位。类似于用N维数组玩战舰。

我怀疑紧凑数组会更快,因为它会将一些数组保存在缓存中。另一方面,我知道作为数组对象访问数组元素的时间等同于通过编译时指针值进行访问,而在std::vector的典型实现中,元素访问时间与通过运行时指针值访问元素的时间相同(更慢)。我不知道bitset和bitfield是怎么适应的

我不需要这个代码是可移植的,只需要非常快(x86)。

这个问题没有唯一的答案,因为它取决于处理器架构(和编译器)。

也就是说,位数组相当快。您只需将其创建为int s数组,然后通过选择正确的int来访问这些位并提取正确的位。它将是紧凑的,快速的,只要你的int有两个位数的功率(32,64等)-否则你可能不得不做一个紧凑和速度之间的交易(例如在一个36位的处理器上,你可以选择速度,每int只使用32位)。

紧凑情况下的代码变为(p[idx / BITS_PER_INT] >> (idx % BITS_PER_INT))。对于快速的情况,BITS_PER_INT = 2 << SHIFT(p[idx >> SHIFT] >> (idx & (BITS_PER_INT-1))) & 1是一样的。

如果您需要对数据的存储进行更多的控制,您可以自定义布局以符合您的要求(尽管如果可移植性不是问题,这也可能不是问题)。

再次,因为它也是特定于实现的最快的,我可能应该提到std::vector<bool>,虽然不能保证尽可能快或紧凑,但很可能它至少是其中之一,如果需要的话,可能是它们之间的一个很好的权衡。

在研究了元素访问如何转换为汇编代码之后,我继续实现了我自己的位寻址方法。我使用了

char array[n][n]...[n/8];

并创建了一个查找表

char lookup[8]={1,2,4,8,16,32,64,128};

并使用8位最低有效位将最后一个数组索引分成两部分来访问查找表,并使用二进制或|来写入位,使用二进制和&


读取部分:

bool result=(bool)(array[x][y]...[z>>8]&lookup[(char)(z&255)])>>((char)(z&255))

写部分:

array[x][y]...[z>>8] |= lookup[(char)(z&255)] //writes 1

我对性能非常满意,这应该可以编译成接近最小的汇编代码,但我没有任何可靠的证据。