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

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

Ответы [ 4 ]

23 голосов
/ 18 мая 2009

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

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

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

9 голосов
/ 18 мая 2009

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

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

4 голосов
/ 18 мая 2009

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

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

0 голосов
/ 11 сентября 2009

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

...