假设我只使用具有明确宽度的类型,例如没有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
答案 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台机器 位字节和浮点数。
当然,如果您只关心一个或两个处理器, 然后你可以很容易地找出他们的编译器。 (除了对齐之外:英特尔架构有否 对齐约束,但大多数编译器强制执行它们 表现原因。性能最佳排列 已经改变了,并且在新版本的时候继续改变 芯片出现。)