首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何控制C数学是否使用SSE2?

如何控制C数学是否使用SSE2?
EN

Stack Overflow用户
提问于 2013-03-10 02:32:37
回答 3查看 2.1K关注 0票数 23

我在fp:strict模式下用MSVC编写了C库的超越数学函数的程序集。它们似乎都遵循相同的模式,以下是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代码路径?我不精通编写汇编,所以如果这涉及到编写任何汇编,代码示例将不胜感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-10 04:46:44

我通过对math.h的仔细研究找到了答案。这由一个名为_set_SSE2_enable的方法控制。这是一个有文档记录的公共符号here

启用或禁用在CRT数学例程中使用数据流单指令多数据扩展指令集2 (SSE2)指令。(此功能在x64架构上不可用,因为默认情况下会启用SSE2。)

这会导致将上述___use_sse2_mathfcns标志设置为所提供的值,从而有效地启用或禁用_pentium4 SSE2例程的使用。

文档提到这只会影响某些超越的函数,但是看一下反汇编,这似乎会影响到它们中的每个人。

编辑:单步执行每个函数都会显示它们在SSE2中都可用,但以下情况除外:

  • sinh

  • cosh

  • tanh

  • sqrt

  • fmod

Sqrt是最大的违规者,但在SSE2中使用内部函数实现它是微不足道的。对于其他人,除了使用第三方库之外,没有简单的解决方案,但我可能没有第三方库。

票数 11
EN

Stack Overflow用户

发布于 2013-03-10 02:52:34

为什么不使用你自己的库而不是C运行时呢?这将为计算机之间的一致性提供更强有力的保证(假设C运行时是作为DLL提供的,并且可能会在时间上稍有变化)。

我推荐CRlibm。如果您已经以SSE2为目标,并且只要您不打算更改FPU的舍入模式,那么您就处于使用它的理想条件中,并且您将找不到更准确的实现。

票数 4
EN

Stack Overflow用户

发布于 2013-03-10 02:48:00

简短的答案是,你不能在你的代码中确定这个库将做什么,除非你还涉及到库实现的特定细节。这将使代码完全不可移植--即使是同一编译器的两个不同版本也可能改变库的内部结构。

当然,如果可移植性不是问题,那么使用extern <type> ___use_sse2_mathfcns;并检查它是否是真的显然是可行的。

我希望如果处理器有SSE2,并且您使用的是一个足够现代的库,那么它会尽可能地使用SSE2。但要说这一点是另一回事。

如果这对您的代码至关重要,那么实现您自己的超越函数并使用它们--这是保证相同结果的唯一方法。或者,使用一些合适的内联汇编(或超越)代码来计算选定的sincos等值,并将这些值与库提供的sin()cos()函数进行比较。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15314390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档