为什么 icc 为一个简单的 main 生成奇怪的程序集?

2024-02-27

我有一个简单的program https://godbolt.org/z/3KD2CM:

int main()
{
    return 2*7;
}

GCC 和 clang 都开启了优化,很乐意生成 2 个指令二进制文件,但 icc 给出了奇怪的输出。

     push      rbp                                           #2.1
     mov       rbp, rsp                                      #2.1
     and       rsp, -128                                     #2.1
     sub       rsp, 128                                      #2.1
     xor       esi, esi                                      #2.1
     mov       edi, 3                                        #2.1
     call      __intel_new_feature_proc_init                 #2.1
     stmxcsr   DWORD PTR [rsp]                               #2.1
     mov       eax, 14                                       #3.12
     or        DWORD PTR [rsp], 32832                        #2.1
     ldmxcsr   DWORD PTR [rsp]                               #2.1
     mov       rsp, rbp                                      #3.12
     pop       rbp                                           #3.12
     ret

我不知道为什么ICC选择将堆栈对齐2个缓存行:

and       rsp, -128                                     #2.1
sub       rsp, 128                                      #2.1

那很有意思。 L2 高速缓存有一个相邻行预取器,喜欢将行对(在 128 字节对齐组中)拉入 L2。但 main 的栈帧通常不会被大量使用。也许在某些程序中重要的变量被分配在那里。 (这也解释了设置rbp,保存旧的 RSP,以便它可以在 AND 运算后返回。 gcc 在函数中使用 RBP 制作堆栈帧,并在其中对齐堆栈。)


剩下的就是因为main()很特殊,ICC使-ffast-math默认情况下。 (这是英特尔的“肮脏”小秘密之一,让它自动矢量化更多开箱即用的浮点代码。)

这包括将代码添加到顶部main设置 MXCSR(SSE 状态/控制寄存器)中的 DAZ/FTZ 位。有关这些位的更多信息,请参阅 Intel 的 x86 手册,但它们实际上并不复杂:

  • DAZ:非正规数为零:作为 SSE/AVX 指令的输入,非正规数被视为零。

  • FTZ:刷新至零:舍入时result如果执行 SSE/AVX 指令,次正常结果将被刷新为零。

有关的:SSE“非正规数为零”选项 https://stackoverflow.com/questions/37886551/sse-denormals-are-zeros-option

(ISO C++ 禁止程序回调main(),因此编译器可以将运行一次的内容放入main本身而不是 CRT 启动文件中。 gcc/clang 与-ffast-math指定用于设置 MXCSR 的 CRT 启动文件中的链接。但是,当使用 gcc/clang 编译时,它只会影响允许优化的代码生成。即,将 FP add/mul 视为关联,而不同的临时值意味着它实际上不是关联。这与设置DAZ/FTZ完全无关)。


非正规在这里被用作次正规的同义词:具有最小指数和有效数字的 FP 值,其中隐式前导位为 0 而不是 1。即,幅度小于的值FLT_MIN or DBL_MIN https://stackoverflow.com/questions/39746861/is-dbl-min-the-smallest-positive-double,最小的可表示的归一化浮点数/双精度。

https://en.wikipedia.org/wiki/Denormal_number https://en.wikipedia.org/wiki/Denormal_number.


产生次正常结果的指令可以是much较慢:为了优化延迟,某些硬件中的快速路径假定标准化结果,如果结果无法标准化,则采用微代码辅助。使用perf stat -e fp_assist.any来计算此类事件。

来自 Bruce Dawson 的优秀 FP 文章系列:这不正常——奇数浮点数的表现 https://randomascii.wordpress.com/2012/05/20/thats-not-normalthe-performance-of-odd-floats/. Also:

  • 为什么将 0.1f 更改为 0 会使性能降低 10 倍? https://stackoverflow.com/questions/9314534/why-does-changing-0-1f-to-0-slow-down-performance-by-10x
  • 避免 C++ 中的非正规值 https://stackoverflow.com/questions/2487653/avoiding-denormal-values-in-c/2487733#2487733

Agner Fog 做了一些测试(参见他的微架构pdf https://agner.org/optimize/),以及 Haswell/Broadwell 的报告:

下溢和次正常

当浮点运算接近时,会出现次正规数 下溢。在某些情况下,处理次正规数的成本非常高 因为次正常结果是由微代码处理的情况 例外情况。

Haswell 和 Broadwell 的惩罚大约为 124 个时钟 在所有情况下循环,其中对正常数的运算给出 低于正常的结果。乘法也有类似的惩罚 介于正常数和次正常数之间,无论是否 结果正常或低于正常。添加正常值不会受到任何惩罚 和一个次正规数,无论结果如何。没有处罚 对于上溢、下溢、无穷大或非数字结果。

如果“清零”,则可以避免对次正规数的惩罚 模式和“非正规数为零”模式均在 MXCSR 中设置 登记。

因此,在某些情况下,现代英特尔 CPU 即使在次正常情况下也能避免处罚,但是

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

为什么 icc 为一个简单的 main 生成奇怪的程序集? 的相关文章

  • C# 静态类型不能用作参数

    public static void SendEmail String from String To String Subject String HTML String AttachmentPath null String Attachme
  • EntityHydrate 任务失败

    我最近安装了 Visual Studio 11 Beta 和 Visual Studio 2010 之后 我无法在 Visual Studio 2010 中构建依赖于 PostSharp 的项目 因此我卸载了 Visual Studio 1
  • Selenium - C# - Webdriver - 无法找到元素

    在 C 中使用 selenium 我试图打开浏览器 导航到 Google 并找到文本搜索字段 我尝试下面的 IWebDriver driver new InternetExplorerDriver C driver Navigate GoT
  • 混合模型优先和代码优先

    我们使用模型优先方法创建了一个 Web 应用程序 一名新开发人员进入该项目 并使用代码优先方法 使用数据库文件 创建了一个新的自定义模型 这 这是代码第一个数据库上下文 namespace WVITDB DAL public class D
  • Makefile 和 .Mak 文件 + CodeBlocks 和 VStudio

    我对整个 makefile 概念有点陌生 所以我对此有一些疑问 我正在 Linux 中使用 CodeBlocks 创建一个项目 我使用一个名为 cbp2mak 的工具从 CodeBlocks 项目创建一个 make 文件 如果有人知道更好的
  • JavaScript 错误:MVC2 视图中的条件编译已关闭

    我试图在 MVC2 视图页面中单击时调用 JavaScript 函数 a href Select a JavaScript 函数 function SelectBenefit id code alert id alert code 这里 b
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • 测量进程消耗的 CPU 时钟

    我用 C 语言编写了一个程序 它是作为研究结果创建的程序 我想计算程序消耗的确切 CPU 周期 精确的循环次数 知道我怎样才能找到它吗 The valgrind tool cachegrind valgrind tool cachegrin
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • 在 azure blob 存储中就地创建 zip 文件

    我将文件存储在 Blob 存储帐户内的一个容器中 我需要在第二个容器中创建一个 zip 文件 其中包含第一个容器中的文件 我有一个使用辅助角色和 DotNetZip 工作的解决方案 但由于 zip 文件的大小最终可能达到 1GB 我担心在进
  • 对于 C# Express 用户来说,有哪些好的工具可以识别可能重复的代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 也可以看看 有什么工具可以检查重复的 VB NET 代码吗 https stackoverflow c
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 调用 .ToArray() 时出现 ArgumentException

    我有一个经常被清除的列表 代码完全是这样的 VisitorAgent toPersist List
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 在 C# 的 WebAPI 中的 ApiController 上使用“传输编码:分块”提供数据

    我需要服务分块传输使用编码数据API控制器 因为我无权访问HttpContext or the Http请求 我有点不知道在哪里写入响应以及在哪里刷新它 设置如下 public class MyController ApiControlle
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • 如何获取带有某个属性注释的所有属性?

    我刚刚从 Roslyn 开始 我想找到所有用属性名称 OneToOne 注释的属性 我启动了 SyntaxVisualizer 并能够获取对该节点的引用 但我想知道是否有更简单的方法来实现此目的 这就是我所拥有的 var prop docu
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配
  • 如何为有时异步的操作创建和实现接口

    假设我有数百个类 它们使用 计算 方法实现公共接口 一些类将执行异步 例如读取文件 而实现相同接口的其他类将执行同步代码 例如将两个数字相加 为了维护和性能 对此进行编码的好方法是什么 到目前为止我读到的帖子总是建议将异步 等待方法冒泡给调

随机推荐

  • WCF 和 HTTP GET

    我的WCF服务公开了这个函数 public SerialNumberInfo GetSerialNumberInfo string serialNumber 有没有办法在我的 WCF 服务上启用 HTTP GET 例子 http local
  • 动态链接和 Python SWIG (C++) 在 C++ 中工作在 python 中失败

    我有一个库 我使用 SWIG 创建了一个 python 包装器 该库本身接受用户提供的函数 这些函数位于动态链接的 so 文件中 目前 我正在处理我自己创建的一个 并设法在 C 中使动态链接正常工作 当我尝试在 python 中运行它时 出
  • Ember.js 路由器入门

    我想在下一个项目中学习使用 Ember js 到目前为止我已经阅读了文档here http emberjs com documentation 但我没有看到有关路由器的解释 然后我读了指南here http emberjs com guid
  • 查找图像中一条线上的像素坐标

    我有一个表示为二维数组的图像 我想获取从点 1 到点 2 的直线上的像素坐标 例如 假设我有一张尺寸为 5x4 的图像 如下图所示 我有一条从坐标点 1 开始的线 0 2 到点 2 4 1 就像下图中的红线一样 所以在这里我想将蓝色像素的坐
  • 如何在 JPQL 中将日期时间转换为日期?

    这段代码有什么问题 Query value Select date ivd trnDatetime as date ivd binNo as bin ivd snNo as sn count ivd invoiceNo as totInvo
  • api 获取请求失败后重新调用 useEffect

    我正在执行 useEffect 以使用 JSON 数据更新状态 但是 获取请求有时会失败 因此如果发生这种情况 我想重新执行 useEffect 挂钩 import React useState useEffect from react i
  • 如何使用注释排除java类在maven中编译

    我已经有一个working解决方案 我可以使用 Maven 指定在使用特定 Maven 配置文件时不编译哪些类 但我想使用通用解决方案并使用注释代替 我目前的解决方案就像
  • 伪元素内容的数据内容中的 Unicode

    我想使用 JQuery 将 unicode 放入 data content 属性中 以便将其用于伪元素内容 但我找不到正确的格式 你如何显示unicode 下面只是显示 x25BC a after content attr data con
  • Vim 从光标上次消失的位置开始

    如何让 Vim 始终从我上次退出给定文件时所在的行开始 将其放入您的 vimrc 中 When editing a file always jump to the last cursor position au BufReadPost if
  • WinForms C# 中优雅的日志窗口

    我正在寻找一种有效的方法来实现 Windows 窗体应用程序的日志窗口 过去我已经使用 TextBox 和 RichTextBox 实现了几个 但我仍然对功能不完全满意 此日志旨在为用户提供各种事件的最新历史记录 主要用于数据收集应用程序
  • 如何测量在 ubuntu 上运行的 java 应用程序的 I/O 时间?

    我想收集我的应用程序等待 I O 的时间 我正在 ubuntu linux 上运行这个 java 应用程序 我正在使用 yourkit 分析器 建议是否有其他分析工具来测量 I O 时间 Youtkit 非常适合在您的应用中使用变焦显微镜
  • 在循环中使用node-mysql插入数据

    我的代码如下 var mysql require mysql var client mysql createClient user root password root host localhost client query USE sam
  • jqgrid 增加字体大小时每个单元格周围的间距

    我使用以下 css 增加了网格单元格的字体大小 ui jqgrid ui jqgrid view font size 14px 现在 每个单元格中文本周围的间距都很小 如何增加该空间 以便较大的文本能够在每个单元格中正确显示 预先致谢 更新
  • 如何在oracle中使用DBMS_CRYPTO.encrypt函数

    我想加密数据库中的密码列 并且我正在尝试使用内部存在的加密函数DBMS CRYPTO包 已从 sys 帐户向当前用户授予执行访问权限 但出现以下错误 请举例说明如何使用此功能 select DBMS CRYPTO encrypt 12345
  • Bootstrap:将输入与按钮对齐

    为什么按钮和输入在 Bootstrap 中不能很好地对齐 我尝试了一些简单的事情 例如
  • 如何使用 PowerShell 了解 IIS 中托管的特定网站的活动会话计数

    我问了一个关于了解 IIS 中正在运行的会话计数的问题 从 IIS 获取我托管的 Asp Net 网站的运行会话计数 https stackoverflow com questions 9734561 get running session
  • 在 MS SQL Server 中隐藏表中的列

    任何人都可以分享在 SQL Server 2012 中隐藏表中特定列的步骤 因为我不想删除该列 我所说的隐藏是指每当我对特定表使用选择查询时 它永远不应该显示该列 是否可以 我需要使该列隐藏 无论任何用户登录和我使用的任何查询 第三者编辑
  • Xcode 由于 swift 中的持久容器而崩溃

    我目前正在制作一个实施核心数据的应用程序 但是 当我构建时 它在这一行崩溃 线程 1 致命错误 未解决的错误 错误 Domain NSCocoaErrorDomain Code 134140 持久存储迁移 失败 缺少映射模型 UserInf
  • 在 UIScrollView 中加载 200 多个子视图图像时程序崩溃

    我正在使用 ALAssetLibrary 开发类似的程序 例如 iPhone 中的照片 我正在尝试在滚动视图中加载图像 当相册中的图片数量较少时 一切正常 但是当我尝试加载包含 200 多张照片的相册时 我的程序结束了 没有任何错误消息 有
  • 为什么 icc 为一个简单的 main 生成奇怪的程序集?

    我有一个简单的program https godbolt org z 3KD2CM int main return 2 7 GCC 和 clang 都开启了优化 很乐意生成 2 个指令二进制文件 但 icc 给出了奇怪的输出 push rb