如何控制C数学是否使用SSE2?(How to control whether C math use

2019-08-17 10:50发布

我在FP踏进的C库的超越数学函数的组件,MSVC:严格模式。 他们似乎都遵循相同的模式,下面是发生了什么sin

首先是来自一个名为“disp_pentium4.inc”文件中的调度程序。 它检查如果变量___use_sse2_mathfcns已被设置; 如果是这样,来电__sin_pentium4 ,否则调用__sin_default

__sin_pentium4 (在“sin_pentium4.asm”)开始由参数从的x87 FPU转移到XMM0注册,进行使用SSE2指令的计算中,并且将结果早在FPU。

__sin_default (在“sin.asm”)保持x87堆栈上可变和简单地调用fsin

因此,在这两种情况下,操作数推x87堆栈上和它返回为好,使之透明的来电,但如果___use_sse2_mathfcns定义,在SSE2而不是的x87实际执行的操作。

这种行为是对我来说很有趣,因为的x87超越函数是臭名昭著的具有取决于实施的行为稍有不同,而SSE2的给定代码块要经常给重现的结果。

有没有一种方法来确定肯定的,无论是在编译或运行时,该SSE2代码路径将被使用? 我不精通写作组装,因此,如果这涉及编写任何组件,代码示例将不胜感激。

Answer 1:

我发现通过math.h中的缜密侦查答案 这是通过一个称为方法控制_set_SSE2_enable 。 这是记录一个公共符号在这里 :

启用或禁用使用SIMD流技术扩展2(SSE2)在CRT数学例程指令。 (因为SSE2默认情况下启用此功能不可用在x64架构。)

这使得aforementionned ___use_sse2_mathfcns标志被设置为所提供的值,从而有效地使能或禁止使用_pentium4 SSE2例程。

说明文档中提到这只会影响某些超越函数,但是看一下拆卸,这似乎影响到他们的每一个人。

编辑:步入每个函数显示,他们都可以在SSE2,除了以下:

  • FMOD
  • 天生
  • 护身用手杖
  • 开方

开方是最大的罪犯,但它的琐碎使用内部函数在SSE2来实现。 对于其他人,有可能除了使用第三方库没有简单的解决办法,但我可能可以不用。



Answer 2:

为什么不使用自己的库,而不是C运行的? 这将提供一致性的多台电脑甚至更有力的保证(大概是C运行时提供了一个DLL,可能在时间上略有变化)。

我会建议CRlibm 。 如果您已经针对SSE2,只要你不打算改变FPU的舍入模式,你是在理想的条件下使用它,你不会找到一个更准确的实现。



Answer 3:

简短的回答是,你不能告诉你的代码的某些东西的图书馆将做,除非你还涉及库实现的具体细节。 这会使代码完全不可移植的 - 即使是两个不同的构建相同的编译器可能会改变图书馆的内部。

当然,如果便携性不是问题,然后使用extern <type> ___use_sse2_mathfcns; 并检查它是否真正显然会工作。

我预计,如果该处理器具有SSE2和你使用的是现代的足够图书馆,它将使用SSE2尽可能。 但是要说可以肯定的是一个不同的问题。

如果这是你的关键代码,然后实现自己的超越函数,并使用这些 - 这是保证相同的结果的唯一途径。 或者,使用一些合适的联汇编器(或超越)代码来计算所选sincos等的值,并比较这些与sin()cos()函数库提供。



文章来源: How to control whether C math uses SSE2?