对不起,如果这个问题听起来很愚蠢。我只是模糊地意识到数据对齐的问题,从未做过任何 64 位编程。我现在正在处理一些 32 位 x86 代码。它经常访问一个 int 数组。有时会读取一个 32 位整数。有时会读取两个或多个。在某些时候,我想将代码设为 64 位。我不确定是否应该将此 int 数组声明为int
or long int
。我宁愿保持整数的宽度相同,所以我不必担心差异。我有点担心,虽然读/写一个与自然词不一致的地址可能会很慢。
4 回答
仅当加载或存储跨越对齐边界时才会发生未对齐惩罚。边界通常是以下两者中的较小者:
- 硬件的自然字长。(32 位或 64 位*)
- 数据类型的大小。
如果您在 64 位(8 字节)架构上加载 4 字节字。它不需要是 8 字节对齐的。它只需要 4 字节对齐。
同样,如果你在任何机器上加载一个 1 字节的字符,它根本不需要对齐。
*请注意,SIMD 向量可能意味着更大的自然字长。例如,16 字节 SSE 在 x86 和 x64 上仍然需要 16 字节对齐。(除非显式未对齐的加载/存储)
所以简而言之,不,您不必担心数据对齐。语言和编译器非常努力地防止您担心它。
因此,只要坚持使用对您最有意义的任何数据类型。
64 位 x86 CPU 仍然为有效处理 32 位值而进行了大量优化。即使在 64 位操作系统上,访问 32 位值至少与访问 64 位值一样快。实际上,它实际上会更快,因为消耗的缓存空间和内存带宽更少。
这里有很多很好的信息: Performance 32 bit vs. 64 bit algorithms
更多信息https://superuser.com/questions/56540/32-bit-vs-64-bit-systems,其中答案声称最严重的速度下降了 5%(从应用程序的角度来看,而不是单个操作)。
简短的回答是否定的,你不会受到性能影响。
每当您访问任何内存位置时,都会将整个高速缓存行读入 L1 高速缓存,并且对该行中任何内容的任何后续访问都尽可能快。除非您的 32 位访问跨越高速缓存行(如果它在 32 位对齐上则不会),它将与 64 位访问一样快。