Кто-нибудь знает, почему GCC / Clang не будет работать оптимистично test1 в приведенном ниже примере кода просто использовать инструкцию RCPPS при использовании опции fast-math? Есть ли другой флаг компилятора, который будет генерировать этот код?
typedef float float4 __attribute__((vector_size(16)));
float4 test1(float4 v)
{
return 1.0f / v;
}
Вы можете увидеть скомпилированный вывод здесь: https://goo.gl/jXsqat
Потому что точность RCPPS
это много ниже чем float
разделение.
Опция, позволяющая включить эту оптимизацию, не подходит в качестве части -ffast-math
,
Параметры цели x86 руководства gcc говорит, что на самом деле есть вариант, который (с -ffast-math
) действительно заставляет gcc использовать их (с итерацией Ньютона-Рафсона):
-mrecip
Эта опция позволяет использовать команды RCPSS и RSQRTSS (и их векторизованные варианты RCPPS и RSQRTPS) с дополнительным
Шаг Ньютона-Рафсона для повышения точности вместо DIVSS и SQRTSS
(и их векторизованные варианты) для плавающей запятой одинарной точности
аргументы. Эти инструкции генерируются только тогда, когда
-funsafe-math-optimizations включается вместе с -finite-math-only и -fno-trapping-math. Обратите внимание, что в то время как пропускная способность последовательности
выше, чем пропускная способность невзаимной инструкции,
Точность последовательности может быть уменьшена до 2 ulp (т.е.
обратное значение 1.0 равно 0.99999994).Обратите внимание, что GCC реализует 1.0f / sqrtf (x) в терминах RSQRTSS (или RSQRTPS), уже с -ffast-math (или вышеуказанной комбинацией опций),
и не нужно -mrecip.Также обратите внимание, что GCC испускает вышеуказанную последовательность с дополнительным шагом Ньютона-Рафсона для векторизованного однопоплавкового деления и
векторизованный sqrtf (x) уже с -ffast-math (или с вышеуказанным параметром
комбинация), и не нужно -mrecip.
-mrecip=opt
Эта опция контролирует, какие инструкции обратной оценки могут быть использованы. opt — список параметров, разделенных запятыми, которым может предшествовать
на ‘!’, чтобы инвертировать опцию:’all’ Enable all estimate instructions. ‘default’ Enable the default instructions, equivalent to -mrecip. ‘none’ Disable all estimate instructions, equivalent to -mno-recip. ‘div’ Enable the approximation for scalar division. ‘vec-div’ Enable the approximation for vectorized division. ‘sqrt’ Enable the approximation for scalar square root. ‘vec-sqrt’ Enable the approximation for vectorized square root.
Так, например, -mrecip = all,! Sqrt включает все обратные приближения, кроме квадратного корня.
Обратите внимание, что новый дизайн Intel Skylake еще больше улучшает производительность деления FP, с задержкой 8-11c, пропускная способность 1/3c. (Или один на 5c пропускной способности для 256b векторов, но такая же задержка для vdivps
). Они расширили разделители, поэтому AVX vdivps ymm
теперь та же задержка, что и для 128b векторов.
(SnB to Haswell сделал 256b div и sqrt с примерно вдвое большей задержкой / пропускной способностью, поэтому у них явно было только делители шириной 128b.) Skylake также конвейеризует обе операции больше, так что в полете может выполняться около 4 операций div. sqrt тоже быстрее.
Так что через несколько лет, когда Skylake получит широкое распространение, это будет стоить rcpps
если вам нужно разделить на одну и ту же вещь несколько раз. rcpps
и пара fma
может иметь немного более высокую пропускную способность, но худшую задержку. Также, vdivps
только один моп; поэтому больше ресурсов для выполнения будет доступно одновременно с делением.
Еще неизвестно, на что будет похожа первоначальная реализация AVX512. предположительно rcpps
и пара FMA для итераций Ньютона-Рафсона будет победой, если производительность деления FP является узким местом. Если пропускная способность Uop является узким местом, и есть много другой работы, пока подразделения находятся в полете, vdivps zmm
вероятно, все еще хорош (если, конечно, один и тот же делитель не используется повторно).