【问题标题】:Safe assumption regarding size and alignment of datatypes on different platforms?关于不同平台上数据类型的大小和对齐的安全假设?
【发布时间】:2013-09-10 09:58:53
【问题描述】:

假设我只会使用具有明确宽度的类型,例如没有 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

【问题讨论】:

  • 抱歉,您的问题似乎自相矛盾:首先您说您将只使用具有明确宽度的类型,然后您询问“An int 将始终占用 32 位...” .
  • @LorenzoDonati - 在明确声明我不会使用没有明确宽度的类型之后,int 是如何模棱两可的?它在问题的开头声明并且在其整个范围内有效,这就是为什么 int 暗示 32 位 int 的原因,顺便说一句,即使不使用显式宽度,大多数现代编译器也是如此。
  • @user2341104 如果你不打算使用int,为什么要问int?而且我相信long int 在 Windows 上是 32 位的。
  • @Angew - 我只是按升序列出它们,名称无关紧要,因为这不是代码并且问题的上下文已经定义。我想知道为什么所有这些吹毛求疵...
  • @user2341104 这不是吹毛求疵,这个问题就目前而言没有意义。当您说short 时,您实际上是指int16_t 吗?

标签: types alignment portability sizeof


【解决方案1】:

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

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 字节。所以我想说,只要你使用某种保证宽度的库,你就是安全的——不是标准要求的最小值,而是绝对宽度。

【讨论】:

    【解决方案2】:

    至少这个断言

    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 位边界对齐显然是有益的。

    【讨论】:

    • 所以如果我在 64 位边界上对齐 double 不会出错?这才是我真正感兴趣的。我正在编写一个小型编译器,需要性能和可移植性保证。
    • @user2341104 您需要与其他编译器生成的代码互操作吗?如果是这样,您将需要遵循您平台的既定 ABI。否则,即使您使用的是 32 位 CPU,您现在也肯定希望将 double 与 64 位对齐。
    【解决方案3】:

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

    如果我们将您的选择限制为 ARM 和 x86,那么您的大小是正确的,除了 MS 编译器出于 hysterical历史原因使用 32 位 long 这一事实。

    缓存“行大小”并不总是 32 字节。我曾在具有 16 字节缓存对齐的旧处理器上工作过。您可以确定它始终是 2n,而 32 字节现在肯定很常见。

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

    【讨论】:

    • 由于它使用 GUI 编辑器,我只需要对齐,因此我可以将数据类型“对齐”到对齐网格中的最佳位置,而不是使用额外的说明符,按下 CTRL 会覆盖对齐功能,允许在需要时使用非最佳单字节对齐方式。
    【解决方案4】:

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

    其次,您的任何假设都不成立。我知道机器 9 位字节,36 位短整型、长整型和浮点型,以及 72 有点双。以及具有 48 位 short、int、long 和 浮点数和 96 位双精度数。我听说过 32 的机器 位字节和浮点数。

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

    【讨论】:

    • 我没有要求好的做法。我特意专注于一组有限的数据类型,宽度为 8 到 64 位,没有外来或特定于实现的类型。我还指定了我感兴趣的所有架构。这使得大约 2/3 或您的答案与问题无关。如果您真的想提供帮助,请重新访问它。
    • 另外,针对二进制不兼容进行配置是一种不好的做法吗?你的意思是我应该使用平台变化的宽度类型来存储我的数据?那将是非常不负责任的IMO。它会使数据与不同平台上的同一程序不兼容。
    • @user2341104 - 它还将强制使用比二进制效率更低的存储格式 - 例如 XML 或 JSON。它会使您的数据更大,读取速度更慢。
    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 2020-02-05
    • 2011-11-11
    相关资源
    最近更新 更多