_mm_max_ss 在 clang 和 gcc 之间有不同的行为

2024-05-22

我正在尝试使用 clang 和 gcc 交叉编译一个项目,但在使用时发现一些奇怪的差异_mm_max_ss e.g.

__m128 a = _mm_set_ss(std::numeric_limits<float>::quiet_NaN());
__m128 b = _mm_set_ss(2.0f);
__m128 c = _mm_max_ss(a,b);
__m128 d = _mm_max_ss(b,a);

现在我期望std::max涉及 NaN 时的类型行为,但 clang 和 gcc 给出不同的结果:

Clang: (what I expected)
c: 2.000000 0.000000 0.000000 0.000000 
d: nan 0.000000 0.000000 0.000000 

Gcc: (Seems to ignore order)
c: nan 0.000000 0.000000 0.000000 
d: nan 0.000000 0.000000 0.000000 

当我使用 _mm_max_ps 时,它会执行预期的操作。我尝试过使用-ffast-math, -fno-fast-math但似乎没有效果。有什么想法可以使编译器之间的行为相似吗?

神箭链接here https://godbolt.org/z/7jTbPP


我的理解是 IEEE-754 要求:(NaN cmp x)回来false for all cmp运营商{==, <, <=, >, >=}, 除了{!=}返回true。一个实现max()函数可以根据任何不等式运算符来定义。

那么,问题是,如何_mm_max_ps实施的?和{<, <=, >, >=},或者有点比较?

有趣的是,当禁用优化您的链接,相应的maxssgcc 和 clang 都使用指令。两者产量:

2.000000 0.000000 0.000000 0.000000 
nan 0.000000 0.000000 0.000000

这表明,鉴于:max(NaN, 2.0f) -> 2.0f, that: max(a, b) = (a op b) ? a : b, where op是其中之一:{<, <=, >, >=}。根据 IEEE-754 规则,此比较的结果始终为 false,因此:

(NaN op val) is always错误,返回(val),
(val op NaN) is always错误,返回(NaN)

启用优化后,编译器可以自由地进行预计算(c) and (d)在编译时。看来 clang 将结果评估为maxss指令将 - 纠正“假设”行为。 GCC 要么依靠另一种实现max()- 它使用 GMP 和 MPFR 库进行编译时数字 - 或者只是不小心_mm_max_ss语义。

GCC 在 godbolt 上的 10.2 和 trunk 版本上仍然出现错误。所以我认为你发现了一个错误!我还没有回答第二部分,因为我想不出可以有效解决这个问题的万能黑客。


来自 Intel 的 ISA 参考:

如果被比较的值都是 0.0s(任一符号),则该值 返回第二个源操作数。如果第二个值 源操作数是一个 SNaN,该 SNaN 会原封不动地返回到 目的地(即不返回 SNaN 的 QNaN 版本)。

如果该指令只有一个值为 NaN(SNaN 或 QNaN),则 第二个源操作数,可以是 NaN 或有效的浮点值, 被写入结果。如果不是这种行为,而是需要 返回来自任一源操作数的 NaN,操作 可以使用一系列指令来模拟 MAXSS,例如 比较后跟 AND、ANDN 和 OR。

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

_mm_max_ss 在 clang 和 gcc 之间有不同的行为 的相关文章

随机推荐

  • 从代码访问 WPF 控件验证规则

    XAML
  • 使用 Youtube API 播放音频

    我们是几个软件开发人员 计划制作一些商业扩展程序或一些网站 使互联网连接速度慢或数据有限的用户可以通过 YouTube 的 API 播放几乎任何视频 尽管在浏览 API 文档时 我们看到了以下部分 Your API Client will
  • Spring cron 表达式每 30 分钟一次

    Java spring 我有以下 cron 作业的 cron 表达式 0 0 35 但上面提到的 cron 表达式每小时触发一次 如下所示 1 35 2 35 3 35 4 35 我想每 35 分钟触发一次 而不是一小时触发一次 有什么快速
  • 在 NumberPicker 中显示更多数字

    我有两个问题 第一个问题是删除 NumberPicker 中的分隔线 我在 Android 中扩展 NumberPicker 来解决这个问题 如下所示 import android content Context import androi
  • python中的unicode错误[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 在下面的代码中我收到错误mailSe
  • C#:使用 System.Text 和 System.Text.RegularExpressions 之间的区别

    在 ASP NET C 应用程序中 我注意到为了使用 Regex 和 StringBuilder 我必须将两者都放在 using System Text using System Text RegularExpressions 从简单的角度
  • 未安装 Apple 的全球开发者关系 (WWDR) 中间证书

    我今天无法通过 Appcelerator Titanium 发布我的应用程序 AdHoc 我开始收到此错误 错误 未安装 Apple 的全球开发者关系 WWDR 中间证书 错误 这将阻止您为 iOS 设备构建应用程序或用于分发的软件包 我上
  • Hibernate - 如何通过 Hibernate 将 java.net.URL 存储到数据库中

    我有一块田地URL countryURL in a Country班级 我想将其数据存储到COUNTRY通过 Hibernate 将表存储在数据库中 哪个休眠type我应该在休眠映射文件中使用
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • 如何在 CoreOS 中重启后自动重启 Docker 容器?

    假设当操作系统重新启动时 Docker 守护进程由任何 init d 或 systemd 之类的进程自动重新启动 那么重新启动一个或多个 Docker 容器的首选方法是什么 例如 我可能在反向代理或数据库服务器后面有许多 Web 服务器 如
  • 从 mongodb 集合中查找前 20 个文档

    我想在一个 Jframe 上显示集合中的前 20 条记录 在另一个框架上显示接下来的 20 条记录 我是 MongoDB 的新手 请提出查询以查找前 20 个和后 20 个文档 在 MongoDB shell 上您可以执行以下操作 db c
  • 如何在不使用reinterpret_cast的情况下使用dlsym()加载函数?

    我正在尝试使用 clang tidy 来强制执行 C 核心指南 虽然它确实有很多有效点 但有一件事我无法真正解决 dlsym 返回一个void 我需要以某种方式将其转换为正确的函数指针 为此 我使用reinterpret cast 由于指南
  • 如何使用“downloadHandler”在闪亮的可反应内部创建下载按钮?

    我创建downloadlinksa 的行内reactable 我这样做是为了DT datatable and a reactable reactable 我还创建了相应的output downloadHandler在 ids 上使用 app
  • 如何在 CAST/CONVERT 之前检查 VARCHAR(n) 的 XML 格式是否正确

    我的公司有一个日志表 其中包含VARCHAR N 放置字符串的列 即supposed是 XML 但事实证明它并不总是格式良好的 为了对日志记录进行分析 以确定错误趋势等 我一直在使用LIKE陈述 然而 这非常慢 最近 我发现SQL Serv
  • App_offline.htm、CSS、图像和 aspnet_isapi.dll

    因此 我正在开发的网站正在使用 urlrewriting 与 aspnet isapi dll 配合 所有内容都映射到它 我放置了 app offline htm 文件 所有文本均显示 但是 CSS 或图像未提供 我猜测由于通配符映射而不是
  • for 循环 - 没有效果的语句

    由于某种原因 我收到错误 statement with no effect关于这个声明 for j idx j lt iter j increment printf from loop idx i int idx punc ctxt j 你
  • Vue.js - 以编程方式设置槽内容

    有什么办法可以从组件内部设置 覆盖插槽的内容吗 喜欢 模板 div div
  • jQuery.ajax() 记录 HTTP 请求

    我有一个发送 HTTP POST 请求的函数 我想记录它以进行调试 这是函数 function serverRequest URL DATA callback ajax url URL type POST dataType text con
  • 按正确的顺序在字符串数组中查找常见字符

    我花了几天时间研究一个函数 以正确的顺序获取字符串数组中的常见字符 以创建通配符 这是一个解释我的问题的例子 我做了大约3个函数 但是当每个字母的绝对位置不同时 我总是遇到一个错误 我们假设 是 通配符 Array 0 gt 48ca135
  • _mm_max_ss 在 clang 和 gcc 之间有不同的行为

    我正在尝试使用 clang 和 gcc 交叉编译一个项目 但在使用时发现一些奇怪的差异 mm max ss e g m128 a mm set ss std numeric limits