C ++, как написать код, который компилятор может легко оптимизировать для SIMD? - PullRequest
7 голосов
/ 26 октября 2010

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

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

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

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

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?

спасибо!

Ответы [ 3 ]

5 голосов
/ 26 октября 2010

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

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

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

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

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

3 голосов
/ 27 октября 2010

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

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

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

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

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

0 голосов
/ 26 октября 2010

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

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

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

...