热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么icc会为简单的主要部件生成奇怪的装配?

如何解决《为什么icc会为简单的主要部件生成奇怪的装配?》经验,为你挑选了1个好方法。

我有一个简单的程序:

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

Peter Cordes.. 6

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

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

那很有意思.L2缓存有一个相邻行预取器,它喜欢将成对的行(在一个128字节的对齐组中)拉成L2.但是主要的堆栈帧通常不会被大量使用.在某些程序中可能会分配重要的变量.(这也解释了设置rbp,以保存旧的RSP,以便它可以在ANDing之后返回.gcc也使用RBP在堆栈框架中使用RBP来协调该堆栈.)


其余的是因为main()特殊,ICC -ffast-math默认启用.(这是英特尔"肮脏"的小秘密之一,让它可以开箱即用自动矢量化更多浮点代码.)

这包括在顶部添加代码以main设置MXCSR(SSE状态/控制寄存器)中的DAZ/FTZ位.有关这些位的更多信息,请参阅英特尔的x86手册,但它们并不复杂:

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

FTZ:平为零:当舍入的结果的SSE/AVX指令的,将次正规结果被刷新到零.

相关:SSE"denormals是零"选项

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


这里使用非正规作为次正规的同义词:具有最小指数的FP值和隐含前导位为0而不是1的有效数.即,幅度小于FLT_MINDBL_MIN的值,或者是最小的可表示的标准化浮点数/双精度值.

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


产生子正常结果的指令可能慢得多:优化延迟,某些硬件中的快速路径假定规范化结果,如果结果无法规范化,则采用微代码辅助.使用perf stat -e fp_assist.any计数这样的事件.

来自布鲁斯道森的优秀系列FP文章:这不正常 - 奇怪花车的表现.也:

为什么将0.1f改为0会使性能降低10倍?

避免在C++中使用非正规值

Agner Fog做了一些测试(参见他的microarch pdf),以及Haswell/Broadwell的报告:

下溢和次正常

当浮点运算接近下溢时,会出现次正规数.在某些情况下,处理次正规数非常昂贵,因为次正规结果由微代码异常处理.

Haswell和Broadwell在正常数字运算产生低于正常结果的所有情况下都会有大约124个时钟周期的代价.无论结果是正常还是低于正常,对于正常数和次正规数之间的乘法都存在类似的惩罚.无论结果如何,添加正常数和次正规数都不会受到惩罚.溢出,下溢,无穷大或非数字结果不会受到惩罚.

如果在MXCSR寄存器中设置"清零到零"模式和"非正规为零"模式,则可以避免对次正规数的处罚.

所以在某些情况下,现代英特尔CPU即使在低于正常值的情况下也可以避免惩罚,但是



1> Peter Cordes..:

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

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

那很有意思.L2缓存有一个相邻行预取器,它喜欢将成对的行(在一个128字节的对齐组中)拉成L2.但是主要的堆栈帧通常不会被大量使用.在某些程序中可能会分配重要的变量.(这也解释了设置rbp,以保存旧的RSP,以便它可以在ANDing之后返回.gcc也使用RBP在堆栈框架中使用RBP来协调该堆栈.)


其余的是因为main()特殊,ICC -ffast-math默认启用.(这是英特尔"肮脏"的小秘密之一,让它可以开箱即用自动矢量化更多浮点代码.)

这包括在顶部添加代码以main设置MXCSR(SSE状态/控制寄存器)中的DAZ/FTZ位.有关这些位的更多信息,请参阅英特尔的x86手册,但它们并不复杂:

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

FTZ:平为零:当舍入的结果的SSE/AVX指令的,将次正规结果被刷新到零.

相关:SSE"denormals是零"选项

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


这里使用非正规作为次正规的同义词:具有最小指数的FP值和隐含前导位为0而不是1的有效数.即,幅度小于FLT_MINDBL_MIN的值,或者是最小的可表示的标准化浮点数/双精度值.

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


产生子正常结果的指令可能慢得多:优化延迟,某些硬件中的快速路径假定规范化结果,如果结果无法规范化,则采用微代码辅助.使用perf stat -e fp_assist.any计数这样的事件.

来自布鲁斯道森的优秀系列FP文章:这不正常 - 奇怪花车的表现.也:

为什么将0.1f改为0会使性能降低10倍?

避免在C++中使用非正规值

Agner Fog做了一些测试(参见他的microarch pdf),以及Haswell/Broadwell的报告:

下溢和次正常

当浮点运算接近下溢时,会出现次正规数.在某些情况下,处理次正规数非常昂贵,因为次正规结果由微代码异常处理.

Haswell和Broadwell在正常数字运算产生低于正常结果的所有情况下都会有大约124个时钟周期的代价.无论结果是正常还是低于正常,对于正常数和次正规数之间的乘法都存在类似的惩罚.无论结果如何,添加正常数和次正规数都不会受到惩罚.溢出,下溢,无穷大或非数字结果不会受到惩罚.

如果在MXCSR寄存器中设置"清零到零"模式和"非正规为零"模式,则可以避免对次正规数的处罚.

所以在某些情况下,现代英特尔CPU即使在低于正常值的情况下也可以避免惩罚,但是


推荐阅读
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
author-avatar
手机用户2502855767
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有