在 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 数组声明为 intlong 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 位整数数组是不是存在性能损失?的主要内容,如果未能解决你的问题,请参考以下文章

x86-64指令系统

使用 g++ -march=x86-64 构建的代码可以在 32 位操作系统上运行吗?

如果 x86-64 中没有兼容模式开关,我是不是保证不会遇到非 64 位指令?

为什么Windows 32位称为Windows x86而不是Windows x32?

x86 32位操作码,x86-x64不同或完全删除

如何查看自己的linux是32位还是64位