Как контролировать, использует ли математика C SSE2?

Я вступил в сборку трансцендентных математических функций библиотеки C с MSVC в режиме fp: strict. Кажется, что все они следуют одной и той же схеме, вот что происходит для sin,

Сначала идет процедура отправки из файла с именем «disp_pentium4.inc». Проверяет, является ли переменная ___use_sse2_mathfcns был установлен; если так, звонит __sin_pentium4иначе звонит __sin_default,

__sin_pentium4 (в «sin_pentium4.asm») начинается с передачи аргумента из fpu x87 в регистр xmm0, выполняет вычисления с использованием инструкций SSE2 и загружает результат обратно в fpu.

__sin_default (в «sin.asm») хранит переменную в стеке x87 и просто вызывает fsin,

Таким образом, в обоих случаях операнд помещается в стек x87 и возвращается к нему, что делает его прозрачным для вызывающей стороны, но если ___use_sse2_mathfcns определяется, операция фактически выполняется в SSE2, а не в x87.

Это поведение очень интересно для меня, потому что трансцендентные функции x87 печально известны тем, что они немного отличаются в зависимости от реализации, в то время как данный фрагмент кода SSE2 всегда должен давать воспроизводимые результаты.

Есть ли способ точно определить, во время компиляции или во время выполнения, что будет использоваться путь кода SSE2? Я не опытный специалист по написанию ассемблера, поэтому, если для этого потребуется написать какую-либо сборку, будет полезен пример кода.

21

Решение

Я нашел ответ путем тщательного изучения математики. Это контролируется методом под названием _set_SSE2_enable, Это публичный символ документально Вот:

Включает или отключает использование Streaming SIMD Extensions 2 (SSE2)
инструкции по математике CRT. (Эта функция недоступна на
x64 архитектуры, потому что SSE2 включен по умолчанию.)

Это приводит к тому, что вышеупомянутому флагу ___use_sse2_mathfcns будет присвоено предоставленное значение, что эффективно разрешает или запрещает использование подпрограмм _pentium4 SSE2.

В документации упоминается, что это влияет только на некоторые трансцендентные функции, но, глядя на разборку, похоже, это затрагивает каждого из них.

Редактировать: вход в каждую функцию показывает, что все они доступны в SSE2, за исключением следующего:

  • FMOD
  • зп
  • сЬ
  • TANH
  • SQRT

Sqrt является крупнейшим нарушителем, но его легко реализовать в SSE2 с использованием встроенных функций. Для других нет простого решения, кроме, возможно, использования сторонней библиотеки, но я, вероятно, могу обойтись без.

9

Другие решения

Почему бы не использовать собственную библиотеку вместо среды выполнения C? Это обеспечило бы еще более надежную гарантию согласованности между компьютерами (предположительно, среда выполнения C предоставляется в виде DLL и может немного изменяться со временем).

Я бы посоветовал CRlibm. Если вы уже нацеливаетесь на SSE2, и если вы не намеревались менять режим округления FPU, вы находитесь в идеальных условиях для его использования и не найдете более точной реализации.

4

Короткий ответ заключается в том, что вы НЕ можете точно сказать В СВОЕМ КОДЕ, что будет делать библиотека, если только вы не задействуете специфические детали реализации библиотеки. Это сделало бы код полностью непереносимым — даже две разные сборки одного и того же компилятора могут изменить внутреннюю часть библиотеки.

Конечно, если переносимость не является проблемой, тогда использование extern <type> ___use_sse2_mathfcns; и проверка, правда ли это, будет работать.

Я ожидаю, что если процессор имеет SSE2 и вы используете достаточно современную библиотеку, он будет использовать SSE2 везде, где это возможно. Но сказать это наверняка — это другое дело.

Если это критично для вашего кода, то реализуйте свои собственные трансцендентные функции и используйте их — это единственный способ гарантировать тот же результат. Или используйте некоторый подходящий встроенный ассемблерный (или трансцендентный) код для вычисления выбранного sin, cosи т. д., и сравните их с sin() а также cos() функции, предоставляемые библиотекой.

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector