数据模型和字长
source link: https://itlanyan.com/data-model-and-type-size/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在 Windows 上开发C++程序,使用 long
数据类型发现很容易溢出,才想到 Windows 平台上 long
的字长和 int
一样是 4,而不是 Linux 上常见的 8。
数据类型和字长
根据 C++标准,有: sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
,同时又规定:
char
:至少8位(一个字节)short
:至少16位(两个字节)int
:至少16位(两个字节)long
:至少32位(4个字节)long long
:至少64位(8个字节)
int
的字长可以是 2,long
的字长可以是 4,因此 MSVC 下 long 和 int 大小一样没问题,只是比较少见。
展开来说,蒸熟类型的字长和编译器及操作系统采用的数据模型有关,已知的数据模型和字长关系有:
数据模型 | 解释 | short字长 | int字长 | long字长 | long long字长 |
LP32 | long和pointer是32位,即2/2/4模型 | 2 | 2 | 4 | 8 |
ILP32 | int、long和pointer是32位,即2/4/4模型 | 2 | 4 | 4 | 8 |
LP64 | long和pointer是64位,即4/8/8模型 | 2 | 4 | 8 | 8 |
LLP64 | long long和pointer是64位,即4/4/8模型 | 2 | 4 | 4 | 8 |
ILP64 | int、long和pointer是64位,即8/8/8模型 | 2 | 8 | 8 | 8 |
SILP64 | short、int、long和pointer是64位 | 8 | 8 | 8 | 8 |
char
都是8位,即一个字长(byte),目前没见到哪个神经病系统或者编译器使用其他字长
如今的桌面和移动主流处理器基本上支持64地址,因此现在32位模型较少使用(旧硬件、旧系统以及X32 ABI会用到);此外 SILP64 基本上也没见哪个编译器使用,实在是没必要。Windows 上的 MSVC(以及mingw环境下的GCC/clang) 使用的是 LLP64
模型,所以 int
和 long
都是4个字节。除了Windows,主流操作系统和编译器(绝大部分Linux/Unix、Macos,以及cygwin上的gcc/clang)都采用的是 LP64 模型,这也是为什么一般都会默认long
是8个字节,即64位。
除了 LP64 ,另一个在科学计算领域常见的模型是 ILP64,例如Intel MKL的某些库分 LP64 和 ILP64 版本。在大量数据处理的场景,int32
很容易溢出,因此矩阵/向量行列索引也需要用64位整数。在现代的处理器上,64位整数和32位整数运算的性能基本一致,但是会多占用一倍的内存。如果用到了第三方库(例如OpenBLAS),要让要求使用一致的数据模型,否则可能导致错误的结果。
定长整数类型
鉴于不同数据模型导致的基本类型字长不一样,对于跨平台的保证64位整数,long
是不可靠的。幸运的是,C++11引入了定长整数类型。对于定长整数有要求的场景,建议用以下数据类型:
std::int8/std::uint8
std::int16/std::uint16
std::int32/std::uint32
std::int64/std::uint64
另外一个常用类型时 size_t
,一般是 unsigned long long int
的别名,绝大多数情况下都能保证64位,不考虑符号的情况下够用了。但是对于 OpenMP for循环的场景,其要求索引是有符号整数,类似的少数场景下 size_t
无法使用。
对于范围更大的整数需求,例如 int128
,C/C++标准未提及,但是不少编译器已经内置支持。如果编译器不支持,则需要手动引入相应的开源代码。
2. 64-Bit Programming Models: Why LP64?
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK