Types 关于不同平台上数据类型的大小和对齐的安全假设?

Types 关于不同平台上数据类型的大小和对齐的安全假设?,types,alignment,portability,sizeof,Types,Alignment,Portability,Sizeof,假设我只使用显式宽度的类型,例如不使用int,但使用int32、uint16等。。。可以安全地假设: A byte will always take 8 bits and will be 8 bit aligned A short will always take 16 bits and will be 16 bit aligned An int will always take 32 bits and will be 32 bit aligned A long int will always

假设我只使用显式宽度的类型,例如不使用int,但使用int32、uint16等。。。可以安全地假设:

A byte will always take 8 bits and will be 8 bit aligned
A short will always take 16 bits and will be 16 bit aligned
An int will always take 32 bits and will be 32 bit aligned
A long int will always take 64 bits and will be 64 bit aligned
A float will always take 32 bits and will be 32 bit aligned
A double will always take 64 bits and will be 64 bit aligned
---另外,如果满足以下条件,这三种方法也可以发挥最佳效果:

A 64bit SIMD datatype will always be 8 byte aligned    
A 128bit SIMD datatype will always be 16 byte aligned
A 256bit SIMD datatype will always be 32 byte aligned
---最后:

A cache page will always be multiple of 32 bytes  // e.g. 32 or 64 bytes

当然,我并不是指所有的硬件平台,我只关心x86/x64和ARMV7/v8,首先,使用显式宽度的类型不是一个好的实践。 它将运行代码的机器限制为 实际上支持这些类型(不是很大的限制 今天,但仍然),它真的没有给你买任何东西

其次,你的任何假设都不成立。我认识机器 具有9位字节,36位短、int、long和float,以及72位 加倍。以及具有48位短、int、long和 浮点和96位双精度。我听说过有32台的机器 位字节和浮点

当然,如果你只关心一两个处理器, 然后您就可以很容易地找到它们的编译器的功能。 (除了对齐:英特尔体系结构没有 对齐约束,但对于 性能原因。以及性能的最佳调整 当新版本的
首先,使用具有显式宽度的类型不是一个好做法。 它将运行代码的机器限制为 实际上支持这些类型(不是很大的限制 今天,但仍然),它真的没有给你买任何东西

其次,你的任何假设都不成立。我认识机器 具有9位字节,36位短、int、long和float,以及72位 加倍。以及具有48位短、int、long和 浮点和96位双精度。我听说过有32台的机器 位字节和浮点

当然,如果你只关心一两个处理器, 然后您就可以很容易地找到它们的编译器的功能。 (除了对齐:英特尔体系结构没有 对齐约束,但对于 性能原因。以及性能的最佳调整 当新版本的
芯片出现。)

我想说只有在有担保的情况下才有担保,我的意思是:

typedef qint8
Typedef for signed char. This type is guaranteed to be 8-bit on all platforms supported by Qt.

typedef qint16
Typedef for signed short. This type is guaranteed to be 16-bit on all platforms supported by Qt.

typedef qint32
Typedef for signed int. This type is guaranteed to be 32-bit on all platforms supported by Qt.

typedef qint64
Typedef for long long int (__int64 on Windows). This type is guaranteed to be 64-bit on all platforms supported by Qt.

typedef quint8
Typedef for unsigned char. This type is guaranteed to be 8-bit on all platforms supported by Qt.

typedef quint16
Typedef for unsigned short. This type is guaranteed to be 16-bit on all platforms supported by Qt.

typedef quint32
Typedef for unsigned int. This type is guaranteed to be 32-bit on all platforms supported by Qt.

typedef quint64
Typedef for unsigned long long int (unsigned __int64 on Windows). This type is guaranteed to be 64-bit on all platforms supported by Qt.
这是从Qt文档中获取的。也就是说,还有其他保证数据类型宽度的库,例如ApachePortableRuntime库,它比Qt更精简。两者都支持x86和ARM体系结构。可能还有其他的


SIMD操作的校准似乎是为获得最佳性能而推荐的。缓存线的大小也似乎是正确的,因为x86处理器有64字节的缓存线,armv7有32字节,v8也向上移动到64字节。所以我想说,只要你使用某种能保证宽度的库,你就是安全的——不是标准要求的最小宽度,而是绝对宽度。

我想说,只有在有保证的情况下才有保证,我的意思是:

typedef qint8
Typedef for signed char. This type is guaranteed to be 8-bit on all platforms supported by Qt.

typedef qint16
Typedef for signed short. This type is guaranteed to be 16-bit on all platforms supported by Qt.

typedef qint32
Typedef for signed int. This type is guaranteed to be 32-bit on all platforms supported by Qt.

typedef qint64
Typedef for long long int (__int64 on Windows). This type is guaranteed to be 64-bit on all platforms supported by Qt.

typedef quint8
Typedef for unsigned char. This type is guaranteed to be 8-bit on all platforms supported by Qt.

typedef quint16
Typedef for unsigned short. This type is guaranteed to be 16-bit on all platforms supported by Qt.

typedef quint32
Typedef for unsigned int. This type is guaranteed to be 32-bit on all platforms supported by Qt.

typedef quint64
Typedef for unsigned long long int (unsigned __int64 on Windows). This type is guaranteed to be 64-bit on all platforms supported by Qt.
这是从Qt文档中获取的。也就是说,还有其他保证数据类型宽度的库,例如ApachePortableRuntime库,它比Qt更精简。两者都支持x86和ARM体系结构。可能还有其他的


SIMD操作的校准似乎是为获得最佳性能而推荐的。缓存线的大小也似乎是正确的,因为x86处理器有64字节的缓存线,armv7有32字节,v8也向上移动到64字节。所以我想说,只要你使用某种能保证宽度的库,你是安全的——不是像标准要求的最小宽度,而是绝对宽度。

至少这是一个断言

A double will always take 64 bits and will be 64 bit aligned
这是错误的。在Linux/x86上,由于历史原因,GCC只将
double
与32位边界对齐。(在80386年代,将其与64位边界对齐毫无意义,因为数据总线只有32位宽。)


在Linux/x86-64上,这是固定的,因为发明x86-64时,将
与64位边界对齐显然是有益的。

至少这一断言是正确的

A double will always take 64 bits and will be 64 bit aligned
这是错误的。在Linux/x86上,由于历史原因,GCC只将
double
与32位边界对齐。(在80386年代,将其与64位边界对齐毫无意义,因为数据总线只有32位宽。)


在Linux/x86-64上,这是固定的,因为当发明x86-64时,将
对齐到64位边界显然是有益的。

完全可以使用pragmas、编译器标志或指针算法来进入未正确对齐的情况

如果我们将您的选择限制在ARM和x86上,那么您的大小是正确的,除了MS编译器使用的
long
由于历史原因是32位之外

缓存“linesize”并不总是32字节。我在使用16字节缓存对齐的旧处理器上工作过。你可以很确定它总是2n,现在32字节肯定很常见


编辑:刚刚注意到你的一条评论说你正在编写一个编译器。我现在不会担心它(虽然你可能只是刚刚开始),但是在某个时候,你可能需要考虑<代码>第二属性(打包)< /> >或>代码>例如,BMP文件中使用了一些数据结构,这些数据结构需要这种打包来提供正确的布局,以便直接从文件中读取数据

完全有可能使用pragmas、编译器标志或指针算法来陷入无法正确对齐的情况

如果我们将您的选择限制在ARM和x86上,那么您的大小是正确的,除了MS编译器使用的
long
由于历史原因是32位之外

缓存“linesize”并不总是32字节。我