Использование инструкций AVX отключает оптимизацию exp ()? - PullRequest
6 голосов
/ 02 мая 2011

Я пишу сеть прямой связи в VC ++ с использованием встроенных функций AVX. Я вызываю этот код через PInvoke в C #. Моя производительность при вызове функции, которая вычисляет большой цикл, включая функцию exp (), составляет ~ 1000 мс при размере петли 160 МБ. Как только я вызываю любую функцию, которая использует встроенные функции AVX, а затем впоследствии использую exp (), моя производительность падает до ~ 8000 мсек для той же операции. Обратите внимание, что функция, вычисляющая 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

Я заблудился относительно того, какой возможный механизм здесь происходит, или как заняться солнцем. Я на Intel 2500K CPU \ Win 7. Экспресс версии VS.

Спасибо.

1 Ответ

10 голосов
/ 05 мая 2011

Если вы используете какую-либо инструкцию AVX256, «верхнее состояние AVX» становится «грязным», что приводит к большой остановке, если вы впоследствии используете инструкции SSE (включая скалярную плавающую точку, выполняемую в регистрах xmm).Это описано в Руководстве по оптимизации Intel, которое вы можете скачать бесплатно (и его обязательно нужно прочитать, если вы выполняете такую ​​работу):

Инструкция AVXвсегда изменяет верхние биты регистров YMM, а инструкции SSE не изменяют верхние биты.С аппаратной точки зрения верхние биты коллекции регистров YMM можно рассматривать как находящиеся в одном из трех состояний:

• Очистить: все старшие биты YMM равны нулю.Это состояние, когда процессор запускается из RESET.

• Изменено и сохранено в регионе XSAVE Содержимое старших битов регистров YMM соответствует сохраненным данным в регионе XSAVE.Это происходит, когда после выполнения XSAVE / XRSTOR.

• Изменено и несохранено: выполнение одной инструкции AVX (256-битной или 128-битной) изменяет старшие биты целевого YMM.

Штраф перехода AVX / SSE применяется, когда состояние процессора «Изменено и Не сохранено».Используя VZEROUPPER, переведите состояния процессора в «Очистить» и избегайте штрафа за переход.

Ваша процедура B( ) загрязняет состояние YMM, поэтому код SSE в A( ) останавливается.Вставьте инструкцию VZEROUPPER между B и A, чтобы избежать проблемы.

...