Использование инструкций 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 чтобы избежать проблема.