1. 指针大小不同
指针 (void*, char* 等) | 4 字节 | 8 字节 |
size_t(sizeof 返回值) | 4 字节 | 8 字节 |
这意味着:
-
std::string、std::vector 等容器的内部指针(如数据指针、迭代器)在 x64 下占用 8 字节,而在 x86 下是 4 字节。
-
内存寻址能力:
-
x86 最大支持 4GB(理论 2³² = 4GB) 内存。
-
x64 支持 16EB(2⁶⁴) 内存(实际受操作系统限制)。
-
2. std::string 的大小不同
不同标准库实现(libstdc++、libc++、MSVC STL)在 x86 和 x64 下的 sizeof(std::string) 不同:
GCC (libstdc++) | 12-16 字节 | 32 字节 |
Clang (libc++) | 12 字节 | 24 字节 |
MSVC (Release) | 28 字节 | 32 字节 |
MSVC (Debug) | 32-40 字节 | 40+ 字节 |
为什么 x64 的 std::string 更大?
-
指针和 size_t 变大(8 字节 vs 4 字节)。
-
短字符串优化(SSO)的缓冲区可能更大(x64 下可存更多短字符串)。
3. 内存对齐不同
-
x86 默认对齐方式通常是 4 字节。
-
x64 默认对齐方式是 8 字节(某些情况可能是 16 字节,如 SSE 指令优化)。
这会影响结构体/类的 sizeof 大小:
cpp
struct Example {
char c; // 1 字节
int i; // 4 字节
void* ptr; // 4 字节(x86)或 8 字节(x64)
};
x86 | 12 字节 | char + 3 填充 + int + void* |
x64 | 16 字节 | char + 7 填充 + int + void* |
4. 函数调用约定不同
默认调用约定 | __cdecl / __stdcall | __fastcall(前 4 参数用寄存器) |
参数传递 | 栈(stack) | 前 4 个参数用 RCX, RDX, R8, R9 |
栈对齐 | 4 字节 | 16 字节 |
这会影响:
-
函数指针和回调(x64 更高效,但 ABI 不同)。
-
内联汇编(x86 和 x64 的汇编指令不同)。
5. 标准库容器(std::vector, std::map 等)的内存占用
由于指针和 size_t 变大,x64 下的容器通常占用更多内存:
std::vector<int> | 12 字节(3×指针) | 24 字节(3×8 字节) |
std::map<int, int> | 16 字节(RB-tree 节点) | 32 字节(节点更大) |
6. 性能差异
寄存器数量 | 8 个通用寄存器 | 16 个通用寄存器 |
SIMD 优化 | SSE(128-bit) | AVX/AVX2(256-bit) |
内存限制 | ≤4GB(通常 2GB 用户态) | 极大(TB 级) |
代码优化 | 较少寄存器,更多栈操作 | 更多寄存器,更快计算 |
-
x64 通常更快(更多寄存器,更好的 SIMD 支持)。
-
x86 内存占用更小(适合嵌入式或旧设备)。
总结
指针大小 | 4 字节 | 8 字节 |
size_t | 4 字节 | 8 字节 |
std::string 大小 | 12-28 字节 | 24-40 字节 |
内存对齐 | 4 字节 | 8/16 字节 |
调用约定 | __cdecl | __fastcall |
容器内存占用 | 较小 | 较大 |
性能 | 较慢(寄存器少) | 更快(寄存器多) |
如何选择?
-
x64:现代应用,需要高性能、大内存。
-
x86:旧设备、嵌入式系统、兼容性要求。
评论前必须登录!
注册