c ++ как написать код, который компилятор может легко оптимизировать для SIMD?

Я работаю в Visual Studio 2008, и в настройках проекта я вижу параметр «активировать расширенный набор инструкций», который я могу установить на None, SSE или SSE2

Значит, компилятор попытается объединить инструкции вместе, чтобы использовать инструкции SIMD?

Есть ли какие-то правила, которым можно следовать, чтобы оптимизировать код, чтобы компилятор мог создавать эффективный ассемблер, используя эти расширения?

Например, сейчас я работаю над трассировщиком лучей. Шейдер принимает некоторые входные данные и вычисляет выходной цвет, например:

PixelData data = RayTracer::gatherPixelData(pixel.x, pixel.y);
Color col = shadePixel(data);

Было бы, например, полезно написать шейдерный код таким образом, чтобы он затенял 4 разных пикселя в одном вызове инструкции? что-то вроде этого:

PixelData data1 = RayTracer::gatherPixelData(pixel1.x, pixel1.y);
...
shadePixels(data1, data2, data3, data4, &col1out, &col2out, &col3out, &col4out);

для одновременной обработки нескольких единиц данных. Было бы полезно заставить компилятор использовать инструкции SSE?

Благодарность!


person Mat    schedule 26.10.2010    source источник


Ответы (3)


Я работаю в Visual Studio 2008, и в настройках проекта я вижу параметр для активации расширенного набора инструкций, который я могу установить на None, SSE или SSE2

Значит, компилятор попытается объединить инструкции вместе, чтобы использовать инструкции SIMD?

Нет, компилятор не будет использовать векторные инструкции самостоятельно. Он будет использовать скалярные инструкции SSE вместо x87.

То, что вы описываете, называется автоматической векторизацией. Компиляторы Microsoft этого не делают, компиляторы Intel этого не делают.

В компиляторе Microsoft вы можете использовать встроенные функции для ручной оптимизации SSE.

person Suma    schedule 26.10.2010
comment
Итак, чтобы использовать векторные инструкции, нужно написать ассемблер? - person Mat; 27.10.2010
comment
Я думаю, Suma означает одно из следующих: software.intel.com/en-us / article / intel-compilers - person Matt K; 27.10.2010
comment
@Mat - вы можете использовать встроенные функции компилятора для написания кода SIMD. См. msdn.microsoft.com/en-us/library /y0dh78ez%28VS.71%29.aspx - person celion; 27.10.2010
comment
Этот ответ, конечно, был совершенно верен для VS 2008, но стоит отметить, что MS Visual Studio на данный момент поддерживает автоматическую векторизацию с VS 2012. - person ; 15.09.2013

Три наблюдения.

  1. Наилучшее ускорение достигается не за счет оптимизации, а за счет хороших алгоритмов. Так что сначала убедитесь, что вы правильно поняли эту часть. Часто это означает просто использование правильных библиотек для вашего конкретного домена.

  2. Как только вы разберетесь со своими алгоритмами, пора измерить. Часто действует правило 80/20. 20% вашего кода займет 80% времени выполнения. Но для того, чтобы найти эту часть, вам понадобится хороший профилировщик. Intel VTune может предоставить вам профиль выборки из каждой функции и красивые отчеты которые определяют убийц производительности. Другой бесплатной альтернативой является AMD CodeAnalyst, если у вас процессор AMD.

  3. Возможность автовекторизации компилятора - не серебряная пуля. Хотя это будет очень стараться (особенно Intel C ++), вы все равно часто нужно помочь ему, переписав алгоритмы в векторном виде. Часто можно добиться гораздо лучших результатов, вручную создавая небольшие фрагменты кода узкого места для использования инструкций SIMD. Вы можете сделать это в коде C (см. Ссылку VJo выше), используя встроенные функции или встроенную сборку.

Конечно, части 2 и 3 образуют повторяющийся процесс. Если вы действительно серьезно относитесь к этому, то есть несколько хороших книг по этой теме от сотрудников Intel, таких как Поваренная книга по оптимизации программного обеспечения и справочные руководства по процессору.

person renick    schedule 26.10.2010

Компилятор не такой уж мощный, и у него есть некоторые ограничения. Если это возможно (и если ему переданы правильные флаги), он будет использовать инструкции SSE. Единственный способ увидеть, что он сделал, - это изучить код сборки, созданный компилятором.

Другой вариант - использовать инструкции C SSE / SSE2. Для окон вы можете найти их здесь:

http://msdn.microsoft.com/en-us/library/y0dh78ez%28VS.80%29.aspx

person BЈовић    schedule 26.10.2010