# #c #intel #sse #intrinsics #sse2
Вопрос:
Есть ли какая — либо разница в точности или производительности между обычными sqrtps/pd или версией SVML:
__m128d _mm_sqrt_pd (__m128d a) [SSE2]
__m128d _mm_svml_sqrt_pd (__m128d a) [SSE?]
__m128 _mm_sqrt_ps (__m128 a) [SSE]
__m128 _mm_svml_sqrt_ps (__m128 a) [SSE?]
Я знаю, что встроенные функции SVML, такие как _mm_sin_ps
, на самом деле, функции, состоящие из потенциально нескольких инструкций asm, поэтому они должны быть медленнее, чем любое однократное умножение или даже деление. Однако мне любопытно, почему эти функции существуют, если доступны встроенные функции аппаратного уровня.
Были ли эти функции SVML созданы до SSE2? Или есть разница в точности?
Комментарии:
1. Если у вас есть компилятор, который поддерживает их, вы можете использовать его в
__m128 foo(__m128 v)
оболочке и посмотреть, соответствует ли онsqrtps xmm0,xmm0
/ret
или нет. IDK, в чем был бы смысл этих версий SVML.2. Трудно представить, что они предоставляют
__m128d
тип и sqrt для него на процессоре без SSE2. Большинство компиляторов даже не определяют,__m128d
включен ли SSE2 (попробуйте 32-разрядную сборку-mno-sse2
), или в компиляторах, таких как ICC и MSVC, использование__m128d
подразумевает использование SSE2. И было бы довольно бессмысленно поддерживать вектор SIMD для выполнения эмулированных sqrt с двойной точностью, но не добавлять / sub / mul / div, и эмуляция будет медленнее, чем просто использование x87 для 2 элементов отдельно. Поэтому я думаю, что мы можем исключить эту догадку.
Ответ №1:
Я проверил кодовое поколение в MSVC.
_mm_svml_sqrt_pd
компилируется в вызов функции; вызываемая функция состоит из одногоsqrtpd
, за которым следуетret
_mm_svml_sqrt_ps
компилируется в вызов функции; вызываемая функция состоит из одногоsqrtps
, за которым следуетret
_mm_sqrt_pd
и_mm_sqrt_ps
встроенные компоненты компилируются в встроенныеsqrtpd
иsqrtps
Возможное объяснение (просто угадайте): SVML предназначался для отправки ЦП, но в версии, скомпилированной для MSVC, эта отправка ЦП отключена. Цель может состоять в том, чтобы реализовать его по-другому для Xeon Phi, версия Xeon Phi может быть не включена в сборку MSVC SVML.
При использовании компилятора Intel он использует svml_dispmd.dll
, и есть фактическая функция отправки (реальный косвенный переход ff 25 42 08 00 00
), которая для меня заканчивается в v sqrtpd
Комментарии:
1. Является ли косвенный вызов функции просто обычным механизмом DLL, потому что код находится в библиотеке DLL SVML? Я предполагаю, что вы тестировали машину с AVX , и она все еще
sqrtpd
не работалаvsqrtpd
, так что похоже, что это действительно так глупо, и они никогда не должны были предоставлять эти функции.2. Хм, интересно, может ли версия Xeon Phi использовать AVX512ER
vrsqrt28ps
для получения приближения, для которого не требуется итерация Ньютона-Рафсона для одинарной точности? IIRC, фактические инструкции sqrt довольно медленные в KNL, и вы собираетесь использовать AVX512ERvfixupimmps
для обработки таких случаев, как 0.3. @PeterCordes, функции не находятся в DLL; даже несмотря на то , что я компилирую с
/MD
, так что время выполнения C находится в DLL, они статически связаны как exe. Возможно , я неправильно использовал косвенный термин: есть вызов функцииe8 af 0c 00 00
, затем по целевому адресу происходит переходe9 0b 00 00 00
, и по этому адресу происходит фактическая реализация.4. Ах, хорошо, это не совсем «косвенный вызов», как вы получили бы для динамического связывания DLL. (Может ли это разрешиться во время динамической связи на основе функций процессора, как это может сделать динамическая связь Linux? Вот как glibc разрешает memcmp и т. Д. к версиям для процессоров AVX2 или чего-либо еще без каких-либо накладных расходов на каждый вызов выше того, что уже накладывает динамическое связывание.)
call rel32
для ajmp rel32
больше похоже на заглушку / оболочку PLT Linux (хотя PLT обычно использует ajmp [mem]
). IDK, если бы SVML мог переписать этоjmp
на основе функций процессора; можете ли вы сказать, находится ли это на странице памяти, что в какой-то момент оно может переназначить чтение/запись?5. Возможно, дело действительно в том, чтобы использовать другую кодировку для Xeon Phi, но поскольку Visual Studio не пытается нацелиться на Xeon Phi, в версии библиотеки SVML, поставляемой вместе с ней, опущена отправка, но рудиментарные функции отправки все еще присутствуют, поэтому я вижу этот относительный jmp; Я добавил скриншот к ответу