【问题标题】:How compilers treat SSE (or any) intrinsic functions?编译器如何处理 SSE(或任何)内在函数?
【发布时间】:2011-08-06 08:05:24
【问题描述】:

不久前,我在某处读到 SSE 内部函数编译成高效的机器代码,因为编译器对它们的处理与普通函数不同。我在徘徊编译器实际上是如何做的,以及 C 程序员可以做些什么来促进这个过程。有没有关于如何使用内在函数的指导方针,以使编译器更容易生成高效的机器代码。

谢谢。

【问题讨论】:

    标签: c++ c optimization sse intrinsics


    【解决方案1】:

    与 Necrolis 所写的相反,内在函数可能会或可能不会编译成它们所代表的指令。对于诸如_mm_load_pd 之类的复制或加载指令尤其如此,因为在使用内部函数时编译器仍然负责寄存器分配和赋值。这意味着如果两个位置可以由同一个寄存器表示,则可能根本不需要将值从一个位置复制到另一个位置。在这种情况下,编译器可能会选择删除副本。如果结果从未使用过,它也可以选择删除其他指令。

    查看this blog post,在实践中比较了不同编译器的行为。它是从 2009 年开始的,因此详细信息可能不再适用。但是,较新的编译器可能会更多地优化您的代码,而不是更少。

    至于实际有效地使用内在函数,答案与所有​​其他性能优化相同:测量、测量和测量。确保您实际上正在处理一段热门代码,找出它缓慢的原因,然后改进它。您很可能会发现改进内存访问模式比使用内部函数更重要。

    【讨论】:

    • 我完全同意你的看法。一个简单的例子是矩阵乘法,转置第一个矩阵可以大大增加内存访问。
    【解决方案2】:

    内在函数编译为表示的指令,这是否有效取决于它们的使用方式。

    此外,每个编译器对内在函数的处理方式略有不同(也就是特定于其实现),但GCC 是开源的,因此您可以看到它们如何处理 SSE、Open Watcom*、LCC、PCC 和 @987654323 @ 都是开源的 C 编译器,虽然没有 SSE 内部函数,但它们应该仍然有内部函数,你可以看到它们是如何处理它们的。

    我认为您阅读的内容与代码的自动矢量化有关,这是 GCC(参见 this)和 ICC 非常擅长的,但它们不如手动优化的代码,至少目前还没有

    *可能已经更新支持 SSE,最近没有检查...

    【讨论】:

    • 我的意思是 _mm_blah_blah 函数,而不是自动矢量化。我希望我能阅读 GCC 的源代码。
    • @pic11:那就忽略最后一点。我确实同意你的观点,不幸的是,从读者的角度来看,gcc 的源代码是一团糟(这就是为什么我建议使用更简单的 c 编译器),你可能会发现 LLVM(和 clang)也更容易挑选。不过,Gcc 和 llvm 有许多随附的论文,因此您可能会发现一些与 sse 相关的论文(有一篇很棒的 ssa register allocation 提到了 sse 的优化)。 msdn 视觉工作室博客有一些关于他们的 simd 内在函数的条目,但不幸的是它非常肤浅......
    • 尽管 gcc 是一团糟,而且编译起来确实很考验(编译编译器,而不是 with 编译器编译),但它是目前最令人惊叹的编译器之一。尤其是在内部函数内部和周围的优化方面,它在长度上击败了 MSVC。
    • 接受,即使它没有直接回答问题。看起来学习编译器在后台做了什么是理解内在函数如何工作的唯一方法。我希望有某种“Effective SSE”书(类似于“Effective C++”),它可以解释 SSE 内在函数,而不会打扰带有神秘编译器内部的普通 C 代码。
    猜你喜欢
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多