Использование инструкций AVX отключает оптимизацию exp()?
-
27-10-2019 - |
Вопрос
Я пишу сеть прямой трансляции на 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.
Спасибо.
Решение
Если вы используете какую-либо инструкцию AVX256, "верхнее состояние AVX" становится "грязным", что приводит к большому зависанию, если вы впоследствии используете инструкции SSE (включая скалярные операции с плавающей запятой, выполняемые в регистрах xmm).Это задокументировано в руководстве Intel по оптимизации, которое вы можете скачать бесплатно (и обязательно прочтите, если вы выполняете такого рода работу):
Инструкция AVX всегда изменяет старшие биты регистров YMM, а инструкции SSE не изменяют старшие биты.С точки зрения аппаратного обеспечения, можно считать, что старшие биты коллекции регистров YMM находятся в одном из трех состояний:
• Чистый:Все старшие биты YMM равны нулю.Это состояние, в котором процессор запускается после сброса.
• Изменено и сохранено в области XSAVE Содержимое старших битов регистров YMM соответствует сохраненным данным в области XSAVE.Это происходит при выполнении after XSAVE/XRSTOR.
• Измененные и несохраненные:Выполнение одной команды AVX (либо 256-битной, либо 128-битной) изменяет старшие биты YMM назначения.
Штраф за переход AVX / SSE применяется всякий раз, когда состояние процессора является “Измененным и несохраненным“.Используя VZEROUPPER, переведите состояния процессора в “Чистое“ положение и избегайте штрафа за переход.
Ваш распорядок дня B( )
загрязняет состояние YMM, поэтому код SSE в A( )
стойла.Вставить VZEROUPPER
инструкция между B
и A
чтобы избежать этой проблемы.