编译器如何处理SSE(或任何)内部函数
How compilers treat SSE (or any) intrinsic functions?
前段时间我在某个地方读到SSE内部函数编译成高效的机器码,因为编译器将它们与普通函数区别对待。我在想编译器实际上是如何做到这一点的,C程序员可以做些什么来促进这个过程。是否有任何指导方针,说明如何使用内在函数,使编译器更容易生成高效的机器码?
谢谢。
与Necrolis所写的相反,intrinsic 可能会或可能不会编译为它们所表示的指令。对于像_mm_load_pd
这样的复制或加载指令尤其如此,因为在使用intrinsic时,编译器仍然负责寄存器的分配和赋值。这意味着如果两个位置可以用同一个寄存器表示,则可能根本不需要将值从一个位置复制到另一个位置。在这种情况下,编译器可能会选择删除该副本。如果结果从未被使用,它也可以选择删除其他指令。
查看这篇博客文章,其中比较了不同编译器在实践中的行为。这是2009年的,所以细节可能不再适用。然而,较新的编译器可能会更多地优化代码,而不是更少。
至于真正有效地使用内在属性,答案与所有其他性能优化一样:测量,测量和测量。确保你正在处理一段热门的代码,找出它慢的原因,然后改进它。您很可能会发现,改进内存访问模式比使用intrinsic更重要。
这些intrinsic编译成它们所表示的指令,这是否有效取决于它们是如何被使用的。
同时,每个编译器对内在特性的处理都有一点不同(也就是它的具体实现),但是GCC是开源的,所以你可以看到它们是如何对待SSE的,open Watcom*, LCC, PCC和TCC*都是开源的C编译器,尽管它们没有SSE内在特性,但它们仍然应该有内在特性,你可以看到它们是如何处理它们的。
我想你读到的是关于代码的自动矢量化,这是GCC和ICC都很擅长的,但是它们不如手工优化的代码好,至少现在还没有
*可能已经更新为支持SSE,最近没有检查…
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何在不产生任何垃圾的情况下获得C中的像素
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- C++映射有2个键,这样任何1个键都可以用来获取值
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- RtlCaptureStackBackTrace未捕获任何帧
- 链表c++插入,所有情况都已检查,但没有任何工作
- C++模板函数,用于比较任何无符号整数和有符号整数
- Arduino millis() - millis() 怎么能等于 0 以外的任何东西?
- 尝试摆脱任何堆内存分配
- 是否有任何C++功能可以对地图进行排序?
- 打印时有二叉树问题.用户输入不打印任何内容
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 在C++行尾写一个分号或多个分号是否会改变任何内容
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- C++ 将 CIN 值存储到任何类型的数组中
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- 执行 SSE 内存复制导致的堆损坏 - CRT 检查找不到任何内容
- 编译器如何处理SSE(或任何)内部函数