Я недавно прочитал это о NaN
значения в арифметических операциях SSE:
Результат арифметических операций, действующих на два не числовых (NAN) аргумента, не определен. Следовательно, операции с плавающей точкой, использующие аргументы NAN, не будут соответствовать ожидаемому поведению соответствующих инструкций сборки.
Источник: http://msdn.microsoft.com/en-us/library/x5c07e2a(v=vs.100).aspx
Означает ли это, что, скажем, добавление двух __m128
значения могут преобразовывать NaN
к реальному?
Если расчет основывался на NaN
значение, мне нужен конечный результат, чтобы быть NaN
также. Есть какой-либо способ сделать это?
Когда я интерпретирую этот текст, он говорит о том, что компилятор предлагает различные встроенные функции, которые примерно соответствуют инструкциям SSE. Как правило, вы можете ожидать, что компилятор будет использовать инструкции SSE для реализации встроенных функций. Однако это не строгое. Внутренние сущности фактически определяют операции в некоторой абстрактной модели вычислений; они не указывают инструкции SSE напрямую. В этой абстрактной модели результат работы с двумя NaN (странно, что кажется, что он не учитывает один NaN и одно число) не определен. Следовательно, результат, который вы получите, например, от добавления двух NaN, может не быть NaN.
В частности, операции в абстрактной модели будут подвергаться оптимизации компилятора, и эти оптимизации могут привести к другим вещам, кроме инструкций SSE (вычисления во время компиляции, пропущенные инструкции, если компилятор может сделать вывод, что присутствуют NaN, поэтому ему не нужно на самом деле выполнить дополнение, и так далее).
Кажется, что если вы хотите гарантировать семантику, указанную для инструкций SSE, вам, возможно, придется писать на ассемблере, а не использовать встроенные функции в компиляторе Microsoft.
Мне бы очень хотелось, чтобы поставщики перестали уделять внимание семантике с плавающей точкой. Сложно заниматься проектированием из-за отсутствия четко определенного поведения.
Других решений пока нет …