融合乘加和默认舍入模式

2024-04-09

使用 GCC 5.3 可以编译以下代码-O3 -fma

float mul_add(float a, float b, float c) {
  return a*b + c;
}

产生以下程序集

vfmadd132ss     %xmm1, %xmm2, %xmm0
ret

我注意到海湾合作委员会这样做-O3已经在 GCC 4.8 中 https://stackoverflow.com/a/21650876/2542702.

铿锵 3.7 与-O3 -mfma产生

vmulss  %xmm1, %xmm0, %xmm0
vaddss  %xmm2, %xmm0, %xmm0
retq

但 Clang 3.7 带有-Ofast -mfma生成与 GCC 相同的代码-O3 fast.

我很惊讶 GCC 这样做-O3因为从这个答案 https://stackoverflow.com/a/15933677/2542702 it says

除非允许宽松的浮点模型,否则不允许编译器融合单独的加法和乘法。

这是因为 FMA 只有一次舍入,而 ADD + MUL 有两次舍入。因此编译器将通过融合违反严格的 IEEE 浮点行为。

然而,从这个链接 http://en.cppreference.com/w/c/types/limits/FLT_EVAL_METHOD it says

无论 FLT_EVAL_METHOD 的值如何,任何浮点表达式都可以收缩,即计算时就好像所有中间结果都具有无限范围和精度。

所以现在我很困惑也很担心。

  1. GCC 使用 FMA 是否合理-O3?
  2. 熔断是否违反严格的 IEEE 浮点行为?
  3. 如果熔断确实违反了 IEEE 浮点行为并且因为海湾合作委员会回报__STDC_IEC_559__ https://stackoverflow.com/questions/31181897/status-of-stdc-iec-559-with-modern-c-compilers这不是矛盾吗?

自 FMA可以在软件中模拟 https://stackoverflow.com/questions/28630864/how-is-fma-implemented/30121217#30121217似乎应该有两个针对 FMA 的编译器开关:一个告诉编译器在计算中使用 FMA,另一个告诉编译器硬件具有 FMA。


显然这可以通过选项来控制-ffp-contract。对于 GCC,默认值是-ffp-contract=fast而 Clang 则不然。其他选项例如-ffp-contract=on and -ffp-contract=off不产生FMA指令。

例如 Clang 3.7 与-O3 -mfma -ffp-contract=fast产生vfmadd132ss.


我检查了一些排列#pragma STDC FP_CONTRACT set to ON and OFF with -ffp-contract set to on, off, and fast。在所有情况下我也使用-O3 -mfma.

对于 GCC,答案很简单。#pragma STDC FP_CONTRACTON 或 OFF 没有区别。仅有的-ffp-contract很重要。

它使用的海湾合作委员会fma with

  1. -ffp-contract=fast(默认)。

与 Clang 一起使用fma

  1. with -ffp-contract=fast.
  2. with -ffp-contract=on(默认)和#pragma STDC FP_CONTRACT ON(默认为OFF).

换句话说,使用 Clang 你可以得到fma with #pragma STDC FP_CONTRACT ON (since -ffp-contract=on是默认值)或与-ffp-contract=fast. -ffast-math(因此-Ofast) set -ffp-contract=fast.


我研究了 MSVC 和 ICC。

对于 MSVC,它使用 fma 指令/O2 /arch:AVX2 /fp:fast。与 MSVC/fp:precise是默认值。

对于 ICC,它使用 fma-O3 -march=core-avx2(实际上-O1足够了)。这是因为默认情况下 ICC 使用-fp-model fast。但 ICC 即使使用 fma-fp-model precise。使用 ICC 禁用 fma-fp-model strict or -no-fma.

因此,默认情况下,当启用 fma 时,GCC 和 ICC 使用 fma(使用-mfma对于 GCC/Clang 或-march=core-avx2与 ICC),但 Clang 和 MSVC 没有。


它并不违反 IEEE-754,因为 IEEE-754 在这一点上遵循语言:

语言标准还应该定义并要求实现提供允许和禁止对块单独或共同进行值更改优化的属性。这些优化可能包括但不限于:

...

― 从乘法和加法合成 fusedMultiplyAdd 运算。

在标准 C 中,STDC FP_CONTRACTpragma 提供了控制这种改变值的优化的方法。因此,GCC 默认情况下被授权执行融合,只要它允许您通过设置禁用优化STDC FP_CONTRACT OFF。不支持就意味着不遵守 C 标准。

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

融合乘加和默认舍入模式 的相关文章

  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • gcc 与 clang:符号剥离

    gcc 和 AMD Open64 opencc 都有一个 s选项 剥离符号表和重定位信息 到目前为止我还没能在 Clang LLVM 中找到相同的选项 它存在吗 您可以使用stripbinutils 中的实用程序 实际上 llvm ld 有
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • 首先在子级的父级上关闭alertDialog Android removeView()

    我想关闭 关闭警报对话框 但是当我单击按钮时valider我遇到了这个错误 我不知道哪些视图给我带来了问题 即使我的视图中没有方法删除视图 layout or v java lang IllegalStateException The sp
  • Imagick PHP 扩展 -- Montage 有帮助吗?

    我在使用 Imagick PHP 扩展生成图像时遇到了一些问题 一切工作正常 除了我的以下 蒙太奇 有白色背景 因此我不能将其覆盖在其他东西之上 如何生成具有透明背景的蒙太奇 Montage Icons gt montageImage ne
  • 如何在多租户系统中的 RabbitMQ 中使队列私有/安全?

    我已阅读开始使用 http www rabbitmq com getstarted htmlRabbitMQ 提供的指南 甚至还贡献了第六个示例暴风雨 amqp https github com paolo losi stormed amq
  • 如何计算不在列表中的日期

    我有一个位于客户的两个日期 date1 date2 之间的数据框以及到达日期 date1 lt 2019 07 29 date2 lt 2019 08 08 clients lt data frame id c 1 10 arrive c
  • 在 Python 中使用多个列表的 For 循环[重复]

    这个问题在这里已经有答案了 我正在寻找解决我的问题的方法 目前我有两个元素列表 column width 3 3 6 8 4 4 4 4 fade 100 200 300 我想要实现的是创建 for 循环 它将给出以下输出 column 3
  • 随机生成密码 Rails 3.1

    为了开发一个新的网络应用程序 我的注册页面 仅限管理员 只需要一个电子邮件字段 问题是我对 Rails 完全陌生 所以即使是像这样的基础知识对我来说也非常困难 我使用 Railscast 270 创建了我的身份验证 它使用有安全密码方法 现
  • Java 中最快的循环同步是什么(ExecutorService、CyclicBarrier、X)?

    哪种 Java 同步结构可能提供最好的 并发 迭代处理场景的性能 像下面概述的那样固定数量的线程 实验后 我自己呆了一段时间 使用 ExecutorService 和 CyclicBarrier 并且 对结果有些惊讶 我会感激一些 专家建议
  • 比较对象 - 单独的侧列

    是否可以显示PowerShell的结果Compare Object在两列中显示参考对象与差异对象的差异 例如使用我当前的命令行 Compare Object Base Test Gives InputObject SideIndicator
  • 在电子邮件中嵌入图片

    我目前有一个程序 可以从列表中随机选择报价并通过电子邮件发送 我现在也尝试在电子邮件中嵌入图像 我遇到了一个问题 我可以附加电子邮件 但我的报价不再有效 我在网上研究过 但解决方案对我不起作用 请注意 我使用的是 Python 3 2 2
  • 发现循环依赖问题

    我正在设计一个系统 其中有两个模块 一个用于管理文件 另一个用于用户 对于某些逻辑运算 它们需要彼此提供的服务 每个模块都由一个单例表示 该单例实现一个相互提供一些服务的接口 并通过抽象工厂来提供它们 如下所示 public class U
  • 如何使 Pinia 商店热重载更改?

    import defineStore acceptHMRUpdate from pinia import v4 as uuidv4 from uuid export const useStoreNotes defineStore store
  • 解耦与 YAGNI

    他们矛盾吗 解耦是一件伟大但很难实现的事情 然而 在大多数应用程序中 我们并不真正需要它 所以我可以设计高度耦合的应用程序 它几乎不会改变任何明显的副作用 例如 你不能分离组件 单元测试是痛苦的 屁股 等 你怎么认为 您是否总是尝试解耦并处
  • 在python中添加小时到unix时间戳

    我需要在某个 UNIX 时间戳上添加 5 小时 就像游戏的开始和停止时间一样 所以我知道比赛的开始时间和持续时间 我需要设置结束时间 这如何在 python 中完成 UNIX 时间戳以秒为单位 end timestamp start tim
  • Gradle 额外属性在子项目中定义的自定义任务中不可见

    我正在尝试在多个 Gradle 任务之间重用通用逻辑 类似于中建议的内容这个答案 https stackoverflow com a 13072481 但我遇到了额外项目属性不可见的问题 归根结底 问题就在这里 假设我有一个根 Gradle
  • 如何在haskell中反转整数?

    我需要有关如何逆转的帮助Integer在 Haskell 中具有以下类型签名 reverseInt Integer gt Integer reverseInt a undefined help here 我需要Integer输入要反转的数字
  • 具有多个条目的 Rails 嵌套形式

    我有一个Sezzion model attr accessible description has many session instructors dependent gt destroy has many instructors thr
  • Apache 和 PHP 的默认 Windows 用户

    查看 Windows XP 上运行的进程 发现 Apache httpd exe 在 SYSTEM 用户下运行 但我不知道什么 User 用于运行 PHP 脚本 这是使用 Xampp 的基本安装 我试图在目录上设置正确的权限 即 Modif
  • 附加 mdf 文件时 SQL Server 版本错误

    标题 Microsoft SQL Server Management Studio 服务器 DESKTOP MR6JCUA 附加数据库失败 微软 SqlServer Smo 附加信息 执行 Transact SQL 语句或批处理时发生异常
  • 如何在 Interface Builder 中创建许多溢出到 xib 之外的元素

    我有一个 UIView 其中有很多元素 如文本字段 日期选择器和选择器视图 可以将数据添加到我的应用程序 这不会出现在 Interface Builder 的屏幕中 在我看来 用户将向下滚动以插入它们 有办法实现这一点吗 Thanks 如何
  • 融合乘加和默认舍入模式

    使用 GCC 5 3 可以编译以下代码 O3 fma float mul add float a float b float c return a b c 产生以下程序集 vfmadd132ss xmm1 xmm2 xmm0 ret 我注意