Использование инструкций AVX отключает оптимизацию exp ()?
Я пишу фид-форвардную сеть в VC++, используя встроенные компоненты AVX. Я вызываю этот код через PInvoke в C#. Моя производительность при вызове функции, которая вычисляет большой цикл, включая функцию exp (), составляет ~1000 мс для loopsize 160M. Как только я позвоню любой функция, которая использует встроенные функции AVX, а затем впоследствии использует exp (), моя производительность падает до ~8000ms для той же операции. Обратите внимание, что функция, вычисляющая exp (), является стандартной C, и вызов, который использование встроенных компонентов AVX может быть полностью несвязанным с точки зрения обрабатываемых данных. Какой-то флаг получает споткнулся где-то во время выполнения.
другими словами,
A(); // 1000ms calculates 160M exp()
B(); // completely unrelated but contains AVX
A(); // 8000ms
или, как ни странно,
C(); // contains 128 bit SSE SIMD expressions
A(); // 1000ms
Я теряюсь в том, какой возможный механизм здесь происходит, или как преследовать sol'N. Я на Intel 2500K cpuWin 7. Экспресс-версии VS.
спасибо.
1 ответов
если вы используете любую инструкцию AVX256, "верхнее состояние AVX "становится " грязным", что приводит к большому стойлу, если вы впоследствии используете инструкции SSE (включая скалярную плавающую точку, выполняемую в регистрах xmm). Это описано в руководстве по оптимизации Intel, которое вы можете скачать бесплатно (и обязательно прочитайте, если вы делаете такую работу):
инструкция AVX всегда изменяет верхние биты регистров YMM и инструкции SSE делают не изменять верхние биты. С точки зрения аппаратного обеспечения верхние биты коллекции регистров YMM можно считать находящимися в одном из трех состояний:
• Clean: все верхние биты YMM равны нулю. Это состояние, когда процессор запускается из RESET.
• изменено и сохранено в область XSAVE содержимое верхних битов регистров YMM соответствует сохраненным данным в области XSAVE. Это происходит, когда после выполнения XSAVE/XRSTOR.
• изменено и Несохранено: Выполнение одной инструкции AVX (256-разрядной или 128-разрядной) изменяет верхние биты целевого YMM.
наказание перехода AVX/SSE применяется всякий раз, когда состояния процессора "изменены и Несохранены". Используя VZEROUPPER, переместите состояния процессора в "чистое" и избегайте штрафа за переход.
ваш режим B( )
загрязняет состояние YMM, поэтому код SSE в A( )
глохнет. Вставить VZEROUPPER
инструкция между B
и A
чтобы избежать проблема.