GCC、SIMD Intrinsic 和 Fast-math 概念

12

大家好 :)
我正在努力理解有关浮点数、SIMD/数学内置函数和gcc的fast-math标志的一些概念。更具体地说,我在x86 cpu上使用带有gcc v4.5.0的MinGW。

我已经搜索了一段时间,现在我(认为自己)明白的是:

当我不使用任何标志进行编译时,任何fp代码都将是标准的x87,没有simd内置函数,并且math.h函数将从msvcrt.dll链接。

当我使用 mfpmathmssen 和/或 march 以便启用 mmx/sse/avx 代码时,gcc实际上只有在我还指定了一些优化标志,例如 Onftree-vectorize 时才使用simd指令。此时,intrinsics由gcc自动选择,某些数学函数(我仍然在谈论math.h上的标准数学函数)将变成内置函数或通过内联代码进行优化,其他一些将仍然来自 msvcrt.dll。如果我不指定优化标志,会发生任何变化吗?

当我使用特定的simd数据类型(那些作为gcc扩展名可用的,如 v4siv8qi)时,我有选择直接调用内置函数的选项,或者再次将自动决策留给gcc。如果我不通过适当的标志启用simd指令,gcc仍然可以选择标准的x87代码。同样,如果我不指定优化标志,会发生任何变化吗?

如果我的陈述中有任何错误,请纠正我 :p

现在是问题:

  1. 我是否必须包含 x86intrin.h 才能使用内置函数?
  2. 我是否必须链接 libm?
  3. fast-math 与任何事情有关吗?我了解它放松了IEEE标准,但是具体而言,它如何放松呢?使用其他标准函数?链接其他库?还是只设置了一些标志并且标准库的行为有所不同?


Translated:

大家好 :)
我正在努力理解浮点数、SIMD/数学内置函数和gcc的fast-math标志的相关概念。更具体地说,我在x86 cpu上使用带有gcc v4.5.0的MinGW。

我已经搜索了一段时间,现在我(认为自己)明白的是:

当我不使用任何标志进行编译时,任何fp代码都将是标准的x87,没有simd内置函数,并且math.h函数将从msvcrt.dll链接。

当我使用 mfpmathmssen 和/或 march 以便启用 mmx/sse/avx 代码时,gcc实际上只有在我还指定了一些优化标志,例如 Onftree-vectorize 时才使用simd指令。此时,intrinsics由gcc自动选择,某些数学函数(我仍然在谈论math.h上的标准数学函数)将变成内置函数或通过内联代码进行优化,其他一些将仍然来自 msvcrt.dll。如果我不指定优化标志,会发生任何变化吗?

当我使用特定的simd数据类型(那些

感谢任何愿意帮忙的人 :D


  1. 在这里查看一个例子:https://dev59.com/_W445IYBdhLWcg3wQoAj
- Anycorn
1个回答

6

如果你像我一样,对这些概念感到有些困惑,那么我会为大家解答。

Ox 优化适用于任何类型的代码,包括 fpu 或 sse。

fast-math 似乎只适用于 x87 代码。此外,它似乎不会改变 fpu 控制字 o_O。

内建函数始终被包含。使用某些标志(如 strict 或 no-builtins),可以避免某些内建函数的行为。

libm.a 用于一些未包含在 glibc 中的内容,但在 mingw 中它只是一个虚拟文件,所以目前将其链接是无用的。

仅当直接调用内部函数时,使用 gcc 的特殊向量类型才有用,否则代码将自动矢量化。

欢迎进行任何更正 :)

有用的链接:
fpu / sse 控制
gcc 数学
以及 "Vector Extensions"、"X86 Built-in functions" 和 "Other Builtins" 的 gcc 手册


由于gcc现在已经更新到v4.7,就像我在结尾写的那样,任何更正仍然受欢迎 :) - rocket441
对于32位x86上的gcc,您需要使用-msse2-march=whatever来启用SSE / SSE2数学功能。然后,为了让编译器实际使用它,您使用-mfpmath = sse。 x86-64上的gcc默认情况下已经使用SSE / SSE2处理浮点/双精度,因为ABI将float和double args传递并返回到XMM寄存器中,而不是x87堆栈。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接