为何80位浮点数占用128位内存?16位整数为何无此差异?
问题:80位浮点数为何占用128位内存?
C语言示例代码
#include <stdio.h> #include <stdint.h> int main() { int16_t i16; __float80 r80; printf("size of 16 bit integer: %u\nsize of 80 bit real: %u\n", sizeof(i16) * 8, sizeof(r80) * 8); return 0; }
Fortran语言示例代码(注:使用整数字面量作为kind参数不具备可移植性)
program test implicit none integer(2) :: i16 real(10) :: r80 print '("size of 16 bit integer: ", i0, /, "size of 80 bit real: ", i0)', & & storage_size(i16), storage_size(r80) end program test
编译运行输出
使用gcc与gfortran编译运行后,两者输出均为:
size of 16 bit integer: 16 size of 80 bit real: 128
疑问
为何80位浮点数的内存占用为128位?我猜测这与内存对齐和优化有关,但为何16位整数仍保持16位的内存占用?
解答
80位x86扩展精度浮点数(对应代码里的__float80和real(10))的有效数据长度确实是80位,但内存占用128位完全是内存对齐导致的:
- x86-64架构下,gcc/gfortran默认会将这类浮点数对齐到16字节(128位)的内存边界。CPU访问对齐的数据时效率更高,能避免多次内存读取或对齐错误,因此编译器会自动填充48位的空数据,让整个变量占满16字节。
而16位整数能保持16位占用的原因很直接:
- 16位(2字节)本身就是x86架构的自然对齐单位,不需要额外填充就能满足CPU的对齐要求;
- 小整数的访问效率不会因为对齐到更大单位而提升,编译器没必要为其增加内存占用。
如果需要调整对齐规则,可以通过编译选项(比如-mno-align-long-double)或代码中的对齐属性修改,但默认情况下编译器会优先保证访问效率,所以会给80位浮点数做16字节对齐。
内容的提问来源于stack exchange,提问作者Ghorban M. Tavakoly
相关产品推荐
相关产品推荐

