CPU一次只会从4倍数开始的地址一次性读取32位数(数据总线宽度)放到缓存里。然后根据需要剔除不要的部分,拼合、移位后传输到内部寄存器里,保证内部寄存器里的数据总是正确内容。也就是说1字节的数据读取时肯定能读到。2字节的数据可能跨4倍数的界限,这时候就需要两个访存周期读取48位数,然后拼合并剔除不要的部分。这个过程是很浪费时间的。
你改编译器开关只是改变了编译出来的数据排列,CPU读取的时候还是4字节4字节的顺序读的。
对于不同的CPU和不同的设置,CPU访存特性是不同的。x86系列CPU都支持不对齐访问,也提供了开关禁用这个机制。有的CPU(ARM的一些型号)根本不支持不对齐访问,如果你的程序中要访问奇数地址,CPU会直接中止执行,抛出异常。
需要字节对齐的本质在于对于32位系统,[b]地址总线寻址之使用A[2]~A[31],0和1用于逻辑控制。那么地址就只能以4字节为跨越来寻址[/b][color=red][/color]
(意思是32位有0,1两位不能用,这样就每次寻址是30位,也就是定位跨度是4个字节,一次io读取就要读取4个字节的内容)。OK,具体例子就不举了,一般的规则是
• 单个字节(char)能对齐到任意地址
• 2字节(short)以2字节边界对齐
• 4字节(int, long)以4字节边界对齐
你改编译器开关只是改变了编译出来的数据排列,CPU读取的时候还是4字节4字节的顺序读的。
对于不同的CPU和不同的设置,CPU访存特性是不同的。x86系列CPU都支持不对齐访问,也提供了开关禁用这个机制。有的CPU(ARM的一些型号)根本不支持不对齐访问,如果你的程序中要访问奇数地址,CPU会直接中止执行,抛出异常。
需要字节对齐的本质在于对于32位系统,[b]地址总线寻址之使用A[2]~A[31],0和1用于逻辑控制。那么地址就只能以4字节为跨越来寻址[/b][color=red][/color]
(意思是32位有0,1两位不能用,这样就每次寻址是30位,也就是定位跨度是4个字节,一次io读取就要读取4个字节的内容)。OK,具体例子就不举了,一般的规则是
• 单个字节(char)能对齐到任意地址
• 2字节(short)以2字节边界对齐
• 4字节(int, long)以4字节边界对齐