我需要在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位整数?
答案 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位将被打包到剩余的字节中
您应该测试并选择最适合您的情况。