如何确保在使用SSE内在函数时传播NaN?

Inv*_*rse 6 c c++ floating-point sse nan

我最近读到了关于NaNSSE算术运算中的值:

作用于两个而不是数字(NAN)参数的算术运算的结果是未定义的.因此,使用NAN参数的浮点运算将与相应汇编指令的预期行为不匹配.

资料来源:http://msdn.microsoft.com/en-us/library/x5c07e2a(v = vs.100).aspx

这是否意味着,添加两个__m128值可能会将a转换NaN为真实?

如果计算依赖于某个NaN值,我也需要最终结果NaN.有没有办法做到这一点?

Eri*_*hil 5

当我解释该文本时,它所说的是编译器提供了大致对应于SSE指令的各种内在函数.通常,您可以期望编译器将使用SSE指令来实现内在函数.但是,这并不严格.内在函数实际上在一些抽象的计算模型中指定了操作; 他们没有直接指定SSE指令.在该抽象模型中,对两个NaN进行操作的结果(奇怪的是它似乎不允许一个NaN和一个数字)是未定义的.因此,您获得的结果(例如,添加两个NaN)可能不是NaN.

特别是,抽象模型中的操作将受到编译器优化的影响,并且这些优化可能会导致除SSE指令之外的其他事情(在编译时进行计算,如果编译器可以推断出NaN存在则省略指令,因此实际上不需要执行添加,等等.

似乎如果要保证为SSE指令指定的语义,您可能必须使用汇编语言而不是在Microsoft的编译器中使用内在函数.

我希望供应商不再对浮点语义进行简短的讨论.在缺乏明确行为的情况下很难进行工程设计.

  • @PatriciaShanahan:这似乎很可能.指令返回的两个输入NaN中的哪一个通常取决于操作数顺序,并且编译器可能无法保持从内在函数到指令的顺序.这将导致需要记录返回两个NaN中的哪一个是未定义的,并且对其的粗略处理可能导致文档声明在两个NaN上操作的结果未定义.尽管如此,文档说明了它的内容. (2认同)