Я вступил в сборку трансцендентных математических функций библиотеки C с MSVC в режиме fp: strict. Все они, похоже, следуют одной и той же схеме, вот что происходит для 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? Я не владею письменной сборкой, поэтому, если это связано с написанием какой-либо сборки, будет оценен пример кода.