SSE2 有符号整数溢出未定义吗?

2023-11-22

有符号整数溢出在 C 和 C++ 中未定义。但是,有符号整数在单个字段内溢出又如何呢?__m128i?换句话说,这种行为是在英特尔标准中定义的吗?

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <emmintrin.h>

union SSE2
{
    __m128i m_vector;
    uint32_t m_dwords[sizeof(__m128i) / sizeof(uint32_t)];
};

int main()
{
    union SSE2 reg = {_mm_set_epi32(INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX)};
    reg.m_vector = _mm_add_epi32(reg.m_vector, _mm_set_epi32(1, 1, 1, 1));

    printf("%08" PRIX32 "\n", (uint32_t) reg.m_dwords[0]);
    return 0;
}
[myria@polaris tests]$ gcc -m64 -msse2 -std=c11 -O3 sse2defined.c -o sse2defined
[myria@polaris tests]$ ./sse2defined
80000000

请注意,SSE2 的 4 字节大小的字段__m128i被视为已签署。


  1. 您询问的是特定的实施问题(使用 SSE2),而不是标准。您已经回答了自己的问题“C 中未定义有符号整数溢出”。

  2. 当您处理 C 内在函数时,您甚至不是在用 C 进行编程!这些是在行中插入汇编指令。它以某种可移植的方式执行此操作,但您的数据不再是有符号整数。它是传递给 SSE 内在函数的向量类型。然后,您将其转换为整数并告诉 C 您希望查看该操作的结果。当你进行强制转换时,无论出现什么字节,你都会看到什么,与 C 标准中的有符号算术无关。

如果编译器插入 SSE 指令(比如在循环中),情况会有所不同。现在编译器保证结果与带符号的 32 位操作相同...除非存在未定义的行为(例如溢出),在这种情况下它可以做任何它喜欢的事情。

另请注意,未定义并不意味着意外...您观察到的自动矢量化行为可能是一致且可重复的(也许它总是包装在您的机器上...这可能不适用于周围代码的所有情况,或者或者,如果编译器根据 SSSE3、SSE4 或 AVX* 的可用性选择不同的指令,甚至可能不是所有处理器(如果它为不同的指令集(使用或不使用带符号的指令集)做出不同的代码生成选择溢出为 UB)。

EDIT:

好吧,现在我们正在询问“英特尔标准”(该标准不存在,我认为您指的是 x86 标准),我可以在我的答案中添加一些内容。事情有点复杂。

首先,内在的 _mm_add_epi32 定义为微软以匹配 Intel 的内在函数 API 定义(https://software.intel.com/sites/landingpage/IntrinsicsGuide/以及 Intel x86 汇编手册中的内在注释)。他们巧妙地将其定义为对__m128ix86也是一样的PADDD指令对 XMM 寄存器执行操作,无需更多讨论(例如,它是 ARM 上的编译错误还是应该对其进行模拟?)。

其次,PADDD不仅仅是一个签名补充!它是一个 32 位二进制加法。 x86 对有符号整数使用二进制补码,将它们相加与无符号基数 2 的二进制运算相同。So yes, paddd保证包裹。所有 x86 指令都有一个很好的参考here.

那么这意味着什么:同样,您问题中的假设是有缺陷的,因为甚至没有任何溢出。所以你看到的输出应该是定义的行为。请注意,它是由 Microsoft 和 x86 定义的(而不是由 C 标准定义的)。

其他x86编译器也以同样的方式实现Intel的intrinsic API,所以_mm_add_epi32可移植地保证只是包装。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SSE2 有符号整数溢出未定义吗? 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new

随机推荐