大数组26位无符号整数

时间:2012-01-10 00:19:41

标签: c arrays bit-manipulation

我需要在RAM中使用大量的26位变量。使用32位int太昂贵了。访问应尽可能快(特别是读操作)。

我采用了以下方案:每个26位值分为3个8位值和1个2位值。

#define N 500000000
uint8 arr1[N], arr2[N], arr3[N];
uint8 arr4[N / 4];

int read_value(int index)
{
  int a1 = arr1[index];                                   // bits 0..7
  int a2 = arr2[index];                                   // bits 8..15
  int a3 = arr3[index];                                   // bits 16..23
  int a4 = (arr4[index / 4] >> (2 * (index % 4))) & 3;    // bits 24..25
  return a1 | (a2 << 8) | (a3 << 16) | (a4 << 24);
}

有没有更好的技术来做到这一点? 或者也许有一种很好的方法来处理27/28/29/30位整数?

2 个答案:

答案 0 :(得分:0)

当你说使用32位整数“太贵”时,你的意思是空间吗?

假设你这样做,我真的不确定如何帮助你。但是,就读取速度而言,C / C ++中的数组为您提供了对数组元素的恒定访问(假设内存已经在CPU缓存中;如果不是,则需要更长)。因此,读取元素0花费与读取元素10,000相同的时间量;你所拥有的代码可能会让它变慢,但我不能肯定地说。

虽然看起来这个代码应该做你想做的事情,但它可能最简单的做一个int数组,即使它会占用更多的空间。如果您必须这样做,可以尝试将inline放在方法声明中,以便编译器可以在您使用它时对其进行扩展。

答案 1 :(得分:0)

内存加载比CPU中的简单算术指令花费更多,所以不应该使用uint8这样的数组。读取每个元素会花费很多负载。至少使用uint16数组,因为负载较少

uint16 arr1[N];     // byte 0-15
uint8  arr2[N];     // byte 16-23
uint8  arr3[N / 4]; // byte 25-26

但这仍然很慢。快速解决方案是在循环中一次读取所有13 uint32(或uint64,如果您正在运行64位计算机),然后将它们提取到 16 26位{{1 }}Š。有很多种方法可以将这些26位int存储在13 int中。例如,连续存储每个26位unint32

  

0 A 1 ... A 15

或者存储16个元素的位0-15的前32个字节,每个元素的位16-23的后16个字节,最后的字节将用于24-25位。内存映射将是这样的

int

这通常用于每通道奇数位的图像格式。例如,对于每通道格式10比特,则每个像素将以5个字节存储,前四个存储每个像素的高8位,每个像素的低2位将被打包到剩余的字节中

您应该测试并选择最适合您的情况。