在 x86-64 中访问 32 位整数数组是不是存在性能损失?
Posted
技术标签:
【中文标题】在 x86-64 中访问 32 位整数数组是不是存在性能损失?【英文标题】:Is there a performance penalty access an array of 32-bit integers in x86-64?在 x86-64 中访问 32 位整数数组是否存在性能损失? 【发布时间】:2012-09-16 20:50:19 【问题描述】:对不起,如果这个问题听起来很愚蠢。我只是模糊地意识到数据对齐的问题,从未做过任何 64 位编程。我现在正在处理一些 32 位 x86 代码。它经常访问一个 int 数组。有时会读取一个 32 位整数。有时会读取两个或多个。在某些时候,我想将代码设为 64 位。我不确定是否应该将此 int 数组声明为 int
或 long int
。我宁愿保持整数的宽度相同,所以我不必担心差异。我有点担心,虽然读/写与自然词不一致的地址可能会很慢。
【问题讨论】:
如果你想要固定宽度的整数试试:int32_t
in <stdint.h>
int
是架构的自然类型。除非你有充分的理由使用不同的类型,否则不要。
@PeteBecker 不,不是。 int
在今天的大多数系统上仍然只有 32 位。
AFAIK 访问由 4 对齐但不是 8 对齐的 dword 不会受到惩罚。
@Mysticial - 来自 C++ 标准:“普通整数具有执行环境架构所建议的自然大小”。如果“今天的大多数系统”不这样做,那么系统设计就会出现严重问题。 (但请注意,“系统”没有定义整数大小;编译器会定义)。
【参考方案1】:
仅当加载或存储跨越对齐边界时才会发生未对齐惩罚。边界通常是以下两者中较小的一个:
硬件的自然字长。 (32 位或 64 位*) 数据类型的大小。如果您在 64 位(8 字节)架构上加载 4 字节字。它不需要是 8 字节对齐的。只需 4 字节对齐即可。
同样,如果您在任何机器上加载 1 字节字符,则根本不需要对齐。
*请注意,SIMD 向量可能意味着更大的自然字长。例如,16 字节 SSE 在 x86 和 x64 上仍然需要 16 字节对齐。 (除非显式未对齐的加载/存储)
简而言之,您不必担心数据对齐问题。语言和编译器非常努力地避免您担心它。
所以只要坚持使用对您最有意义的任何数据类型。
【讨论】:
【参考方案2】:64 位 x86 CPU 仍针对有效处理 32 位值进行了高度优化。即使在 64 位操作系统上,访问 32 位值至少与访问 64 位值一样快。实际上,它实际上会更快,因为消耗的缓存空间和内存带宽更少。
【讨论】:
【参考方案3】:这里有很多有用的信息: Performance 32 bit vs. 64 bit arithmetic
更多信息https://superuser.com/questions/56540/32-bit-vs-64-bit-systems,其中答案声称最严重的速度下降了 5%(从应用程序的角度来看,而不是单个操作)。
简短的回答是否定的,您不会受到性能影响。
【讨论】:
【参考方案4】:每当您访问任何内存位置时,都会将整个缓存行读入 L1 缓存,并且对该行中任何内容的任何后续访问都尽可能快。除非您的 32 位访问跨越缓存线(如果它在 32 位对齐上则不会),否则它将与 64 位访问一样快。
【讨论】:
不完全。访问 1 个值将是相同的。如果您访问同一高速缓存行中的另一个 32 位值,它将已经存在-您甚至可以使用“后续...”来说明这一点。由于每个缓存行加载更多数据元素,因此使用较小的数据大小通常对缓存更友好。以上是关于在 x86-64 中访问 32 位整数数组是不是存在性能损失?的主要内容,如果未能解决你的问题,请参考以下文章
使用 g++ -march=x86-64 构建的代码可以在 32 位操作系统上运行吗?
如果 x86-64 中没有兼容模式开关,我是不是保证不会遇到非 64 位指令?