Подтвердить что ты не робот

Как современные компиляторы используют инструкции mmx/3dnow/sse?

Я читал в расширениях набора инструкций x86, и они кажутся полезными только в некоторых довольно специфических обстоятельствах (например, HADDPD - (Horizontal-Add-Packed-Double) в SSE3). Для них требуется определенная макет реестра, которая должна быть либо преднамеренно настроена, либо из серии инструкций перед ней. Как часто компиляторы общего назначения, такие как gcc, действительно используют эти инструкции (или их подмножество), или они в основном используются в ассемблере с ручным кодированием? Как компилятор обнаруживает, где целесообразно использовать инструкции SIMD?

4b9b3361

Ответ 1

Как правило, несколько компиляторов используют их. GCC и Visual Studio обычно не могут использовать инструкции SIMD. Если вы включите SSE в качестве флага компилятора, он будет использовать скалярные инструкции SSE для регулярных операций с плавающей запятой, но, как правило, не ожидайте, что векторизованные будут использоваться автоматически. Недавние версии GCC могли бы использовать их в некоторых случаях, но в последнее время я не работал. Компилятор Intel С++ - единственный крупный компилятор, который я знаю о том, что он способен автоматически векторизовать некоторые циклы.

В общем, вам придется использовать их самостоятельно. Либо в исходном ассемблере, либо с использованием встроенных функций компилятора. В общем, я бы сказал, что intrinsics - лучший подход, поскольку они лучше позволяют компилятору понять код и, таким образом, планировать и оптимизировать, но на практике я знаю, что MSVC по крайней мере не всегда генерирует очень эффективный код из intrinsics, так что простой asm может быть лучшим решением. Эксперимент, посмотрите, что работает. Но не ожидайте, что компилятор будет использовать эти инструкции для вас, если вы 1) не воспользуетесь правильным компилятором и 2) напишите довольно простые циклы, которые могут быть тривиально пронумерованы.

Обновление 2012
Хорошо, прошло три года с тех пор, как я написал этот ответ. В течение нескольких лет GCC удалось авто-векторизовать (простой) код, а в VS2012 MSVC, наконец, получает ту же возможность. Конечно, основная часть моего ответа по-прежнему применяется: компиляторы все еще могут только векторизовать довольно тривиальный код. Для чего-то более сложного вы застряли в игре с intrinsics или inline asm.

Ответ 2

Моно может использовать расширения SIMD, пока вы используете его классы для векторов. Вы можете прочитать об этом здесь: http://tirania.org/blog/archive/2008/Nov-03.html

GCC должен выполнить некоторую автоматическую векторию, если вы используете -O3 или определенный флаг. У них есть информационная страница здесь: http://gcc.gnu.org/projects/tree-ssa/vectorization.html

Ответ 3

Вопрос о том, как использовать SSE и другие малые векторные единицы автоматически (без направления от программиста в виде специальных языковых конструкций или специально блаженного компилятора "intrinsics" ), в течение некоторого времени был темой исследований компилятора. Большинство результатов, похоже, специализируются на конкретной проблемной области, например обработка цифрового сигнала. Я не поддерживал литературу по этой теме, но то, что я прочитал, предполагает, что использование блока вектора (SSE) по-прежнему является предметом исследования, и что у него должны быть низкие ожидания от компиляторов общего назначения, обычно используемых в этой области.

Предлагаемый поисковый запрос: векторный компилятор

Ответ 4

Если вы используете векторный компилятор pascal, вы получите эффективный код SIMD для типов, для которых SIMD дает преимущество. В основном это что-то длиной менее 64 бит. (для 64-битных реалов это фактически медленнее, чем SIMD). Последние версии компилятора также автоматически будут параллельны всем ядрам

Ответ 5

Я бы, вероятно, не использовал их, если мог. Остерегайтесь несовместимости Intel/AMD. Это может быть устаревшим советом сейчас, или это может быть не так. Я не могу сказать.

EDIT: устаревший, возможно, очень долгое время.