在c++中存储和访问N维位数组中单个位的最快方法是什么?
What is the fastest way to store and access single bits in an N dimensional array of bits in c++?
我有一个代码,我需要以随机的方式从一个大的位数组(总共几兆字节)中读写单个数据位。类似于用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
我对性能非常满意,这应该可以编译成接近最小的汇编代码,但我没有任何可靠的证据。
- 有没有一种优雅而快速的方法来测试整数中的 1 位是否位于连续区域
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- 使用192/256位整数求和无符号64位整数向量的点积的最快方法
- std::bind,无法让具有单个参数的方法工作
- 将位字符串转储到二进制文件的最佳方法是什么
- 有哪些方法可以对基于 256 位密钥的矩阵进行加扰?
- 何时使用按位运算而不是算术替代方法?
- 从 int 中剥离位时,编译器会警告一个转换,但不警告其他转换.有解决方法吗?
- 在C++中有多个指向单个对象的指针的正确方法是什么?
- 哪个是设置位的最佳方法以及为什么?
- 使用 AVX2 将 8 位从 32 位值 (__m256i) 解压缩到__m256的最快方法
- 基于整数向量执行位排列的有效方法?
- 在调试配置中仅优化单个方法
- 如何将单个位转换为字符
- 返回不同类型变量的单个 get 方法
- 将 32 个 0/1 值打包到单个 32 位变量的位中的最快方法是什么?
- 在c++中存储和访问N维位数组中单个位的最快方法是什么?
- 如何使操作符[]返回对unsigned int中单个位的引用
- 支持单个位偏移的类似"memcpy"的功能?
- 通常实现为单个位的布尔变量