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

时间:2013-09-10 09:58:53

标签: 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 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和ARM v7 / v8

4 个答案:

答案 0 :(得分:0)

我会说只有保证才有保证,这就是我的意思:

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文档。话虽这么说,还有其他库保证数据类型的宽度,例如Apache Portable Runtime库,它比Qt更精简。两者都支持x86和ARM架构。可能还有其他人。

SIMD操作的对齐似乎是建议用于获得最佳性能的对齐。高速缓存行大小似乎也是正确的,因为x86处理器有64字节高速缓存行,ARM v7有32字节,v8也高达64字节。所以我说你只要使用某种保证宽度的库是安全的 - 不是标准要求的最小值,而是绝对宽度。

答案 1 :(得分:0)

至少这个断言

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时,将double与64位边界对齐显然是有益的。

答案 2 :(得分:0)

完全可以使用编译指示,编译器标志或指针算法来进入未正确对齐事物的情况。

如果我们将您的选择限制为ARM和x86,那么除了MS编译器使用long 32位用于歇斯底里历史原因之外,您的大小是正确的。< / p>

缓存“linesize”并不总是32个字节。我曾经使用过16字节缓存对齐的旧处理器。您可以非常肯定它总是2 n ,而32字节现在肯定非常常见。

编辑:刚刚注意到你的一条评论说你正在编写一个编译器。我现在不担心(虽然你可能刚刚开始),但在某些时候,你可能需要考虑__attribute__(packed)#pragma pack(n)及相关位。例如,BMP文件中使用了一些数据结构,这些数据结构需要这种打包来提供正确的布局,以便直接从文件中读取数据。

答案 3 :(得分:-1)

首先,使用具有显式宽度的类型不是一个好习惯。 它限制了代码运行的机器 实际上支持这些类型(不是一个很大的限制 今天,但仍然),它真的不会给你买任何东西。

其次,您的假设都不会成立。我知道机器 9位字节,36位短,int,long和float,以及72 有点双。和48位短,int,长和 浮动,96位双。我听说有32台机器 位字节和浮点数。

当然,如果您只关心一个或两个处理器, 然后你可以很容易地找出他们的编译器。 (除了对齐之外:英特尔架构有 对齐约束,但大多数编译器强制执行它们 表现原因。性能最佳排列 已经改变了,并且在新版本的时候继续改变 芯片出现。)