先看一下代码中随处可见的字节对齐宏定义:
#define BYTE_ALIGN(x,a) ( ((x) + ((a) - 1) ) & ( ~((a) - 1) ) )
字节对齐实现了什么功能呢?
其实就是计算不小x的、a的最小公倍数。
经过实验,我发现,a要为2的n次方,才会实现上面说的对齐功能,如果a不止2的n次方,BYTE_ALIGN(x,a)
后的值还是x
。
#include
#include
using namespace std;
#define BYTE_ALIGN(x,a) ( ((x) + ((a) - 1) ) & ( ~((a) - 1) ) )
int main() {
int a = 15;
int x = 39;
for (int i = 0; i < 4; i++) {
cout << "------ a = " << a + i << " ------ " << endl;
for (int j = 0; j < 4; j++) {
printf("x = %d, a = %d, BYTE_ALIGN(x,a) = %d\n",\
x + j, a + i, BYTE_ALIGN(x + j, a + i));
}
cout << endl;
}
}
/*
输出结果:
------ a = 15 ------
x = 39, a = 15, BYTE_ALIGN(x,a) = 49
x = 40, a = 15, BYTE_ALIGN(x,a) = 48
x = 41, a = 15, BYTE_ALIGN(x,a) = 49
x = 42, a = 15, BYTE_ALIGN(x,a) = 48
------ a = 16 ------
x = 39, a = 16, BYTE_ALIGN(x,a) = 48
x = 40, a = 16, BYTE_ALIGN(x,a) = 48
x = 41, a = 16, BYTE_ALIGN(x,a) = 48
x = 42, a = 16, BYTE_ALIGN(x,a) = 48
------ a = 17 ------
x = 39, a = 17, BYTE_ALIGN(x,a) = 39
x = 40, a = 17, BYTE_ALIGN(x,a) = 40
x = 41, a = 17, BYTE_ALIGN(x,a) = 41
x = 42, a = 17, BYTE_ALIGN(x,a) = 42
------ a = 18 ------
x = 39, a = 18, BYTE_ALIGN(x,a) = 40
x = 40, a = 18, BYTE_ALIGN(x,a) = 40
x = 41, a = 18, BYTE_ALIGN(x,a) = 42
x = 42, a = 18, BYTE_ALIGN(x,a) = 42
*/
可以看到只有当a = 16
是BYTE_ALIGN对齐结果都是16的倍数48。a为其他值时实现不了所谓的对齐。
我们把a改为32看一下:
/*
------ a = 31 ------
x = 39, a = 31, BYTE_ALIGN(x,a) = 65
x = 40, a = 31, BYTE_ALIGN(x,a) = 64
x = 41, a = 31, BYTE_ALIGN(x,a) = 65
x = 42, a = 31, BYTE_ALIGN(x,a) = 64
------ a = 32 ------
x = 39, a = 32, BYTE_ALIGN(x,a) = 64
x = 40, a = 32, BYTE_ALIGN(x,a) = 64
x = 41, a = 32, BYTE_ALIGN(x,a) = 64
x = 42, a = 32, BYTE_ALIGN(x,a) = 64
------ a = 33 ------
x = 39, a = 33, BYTE_ALIGN(x,a) = 71
x = 40, a = 33, BYTE_ALIGN(x,a) = 72
x = 41, a = 33, BYTE_ALIGN(x,a) = 73
x = 42, a = 33, BYTE_ALIGN(x,a) = 74
*/
a = 32
确实实现了对齐到32的整数倍64。a = 31
或a = 33
算出的结果都是乱的,不知道干了个啥逻辑。
用二进制手动演算一下:
若a = 16, x = 40
值 | 二进制 |
---|---|
a | 0000 0001 0000 |
x | 0000 0010 1000 |
~((a) - 1) ) | 1111 1111 0000 |
((x) + ((a) - 1) | 0000 0011 0111 |
BYTE_ALIGN(x,a) | 0000 0011 0000 |
~((a) - 1) ) 用低位取0,就是为了能与到比a大的结果。
((x) + ((a) - 1)就是为了增加x的值,之后与运算可以得到更大的结果。
经常在图片处理的时候做字节对齐,将图像的宽和高对齐为64或512的整数倍。
浏览别人的博客,发现上面说的只是向上对齐,还有向下对齐。
#define alignment_down(a, size) (a & (~(size-1)) )
#define alignment_up(a, size) ((a+size-1) & (~ (size-1)))
a=0, size=8, 则alignment_down(a,size)=0, alignment_up(a,size)=0.
a=6, size=8, 则alignment_down(a,size)=0, alignment_up(a,size)=8.
a=8, size=8, 则alignment_down(a,size)=8, alignment_up(a,size)=8.
a=14, size=8,则alignment_down(a,size)=8, alignment_up(a,size)=16.
注:size应当为2的n次方, 即2, 4, 8, 16, 32, 64, 128, 256, 1024, 2048, 4096 …