平台为 x86 或者 路由器常见的 MIPS x86 gcc 7.3 MIPS gcc 7.5
比如这个代码
char buf[10];
uint32_t *p = (uint32_t *) (buf+1); // p 指向没有 4 字节对其的地址。
// 下面的各种操作也都是正常的 (至少运行起来是正常的)
*p = 0x12345678;
*p = *p + 1;
这样没有对其的情况下会有什么影响呢? “对齐”操作是编译器工作还是 CPU 的工作呢? 会有多大效率差别呢?
1
WordTian 2018-02-13 21:32:24 +08:00 via Android
内存数据对齐,和硬盘 4K 对齐起的作用类似啊。
内存也是由很多个块组成的,没对齐的话,很多数据就会同时存在两个块中,就要从两个块中进行读取。 效率的话,取决于你的数据类型,块大小,和 CPU 从内存中取数据的机制吧应该 |
2
WordTian 2018-02-13 21:37:02 +08:00 via Android
有些嵌入式设备的 CPU 就没有从两个块中取数据再提取合并的机制,碰上这种情况应该就抓瞎了
|
3
xwyam 2018-02-13 23:04:36 +08:00 via Android
我在 Cavium 的 MIPS 下遇到过问题的。还是建议声明一个 int 变量,用 memcpy 在变量和缓冲区之间复制数据,这样一般没有坑。
|
4
wzxlovesy 2018-02-14 00:04:41 +08:00 via Android
一般机器都是 32 位机器,所以一次操作 4 字节是有效的,注意大小头,注意越界就行
|
5
changnet 2018-02-14 00:12:54 +08:00 via Android
这个是分为两种情况的
1. 编译器在编译的时候能识别,会自动帮你对齐,损失一些效率但不是很大 2.cpu 指令支持不对齐数据读取,比如 x86 cpu,也只是影响一些效率 3.cpu 不支持不对齐数据读取,程序应该是挂掉 |
6
congeec 2018-02-14 02:09:36 +08:00 via iPhone
编译器咋处理的我不清楚,得看汇编代码
不过我确定栈已经破坏了,这程序吃枣药丸 |
7
zwyc 2018-02-14 08:43:24 +08:00 via Android
楼主的示例中,代码就是要去访问一个非对齐的地址,编译器是不会去帮忙做对齐的。如果去做就是改变了原有的代码行为。编译器就是做了错误的优化。
|