Использование инструкций AVX отключает оптимизацию exp()?

StackOverflow https://stackoverflow.com/questions/5852182

  •  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 чтобы избежать этой проблемы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top