Насколько ускоряется преобразование 3D-математических данных в SSE или другой SIMD?

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

Вопрос

Я широко использую 3D-математику в своем приложении.Какого ускорения я могу добиться, преобразовав мою векторную/матричную библиотеку в SSE, AltiVec или аналогичный код SIMD?

Это было полезно?

Решение

По моему опыту, я обычно наблюдаю трехкратное улучшение при переходе алгоритма с x87 на SSE и лучше более чем пятикратное улучшение при переходе на VMX/Altivec (из-за сложных проблем, связанных с глубиной конвейера, планированием и т. д.).Но обычно я делаю это только в тех случаях, когда мне нужно оперировать сотнями или тысячами чисел, а не в тех случаях, когда я обрабатываю один вектор за раз.

Другие советы

Это еще не вся история, но с помощью SIMD можно получить дальнейшую оптимизацию. Посмотрите презентацию Мигеля о том, как он реализовал инструкции SIMD с помощью MONO, которую он провел на ПДК 2008,

SIMD beats doubles' ass in this particular configuration.
(источник: Тирания.орг)

Изображение из записи в блоге Мигеля.

Для некоторых очень приблизительных цифр:Я слышал, как некоторые люди ompf.org заявите о 10-кратном ускорении некоторых процедур трассировки лучей, оптимизированных вручную.У меня также было несколько хороших ускорений.По моим оценкам, я получил где-то от 2 до 6 раз в своих программах в зависимости от проблемы, и во многих из них было несколько ненужных магазинов и загрузок.Если ваш код имеет огромное количество ветвей, забудьте об этом, но для задач, которые естественным образом являются параллельными данными, вы можете неплохо справиться.

Однако я должен добавить, что ваши алгоритмы должны быть разработаны для параллельного выполнения данных.Это означает, что если у вас есть общая математическая библиотека, как вы упомянули, она должна использовать упакованные векторы, а не отдельные векторы, иначе вы просто потратите свое время.

Например.Что-то вроде

namespace SIMD {
class PackedVec4d
{
  __m128 x;
  __m128 y;
  __m128 z;
  __m128 w;

  //...
};
}

Большинство проблем где производительность имеет значение можно распараллелить, поскольку вы, скорее всего, будете работать с большим набором данных.Для меня ваша проблема звучит как случай преждевременной оптимизации.

При 3D-операциях остерегайтесь неинициализированных данных в вашем W-компоненте.Я видел случаи, когда операции SSE (_mm_add_ps) требовали в 10 раз больше обычного времени из-за неверных данных в W.

Ответ во многом зависит от того, что делает библиотека и как она используется.

Прирост может варьироваться от нескольких процентов до «в несколько раз быстрее». Области, наиболее подверженные появлению выигрыша, — это те, где вы имеете дело не с изолированными векторами или значениями, а с несколькими векторами или значениями, которые необходимо обрабатывать в так же.

Другая область — это когда вы достигаете пределов кэша или памяти, что, опять же, требует обработки большого количества значений/векторов.

Области, в которых выигрыш может быть наиболее значительным, вероятно, связаны с обработкой изображений и сигналов, вычислительным моделированием, а также общими трехмерными математическими операциями на сетках (а не на изолированных векторах).

В наши дни все хорошие компиляторы для x86 по умолчанию генерируют инструкции SSE для вычислений с плавающей запятой SP и DP.Почти всегда использовать эти инструкции быстрее, чем собственные, даже для скалярных операций, если вы правильно их планируете.Это станет неожиданностью для многих, кто в прошлом считал SSE «медленным» и считал, что компиляторы не могут генерировать быстрые скалярные инструкции SSE.Но теперь вам нужно использовать переключатель, чтобы отключить генерацию SSE и использовать x87.Обратите внимание, что x87 на данный момент фактически устарел и может быть полностью удален из будущих процессоров.Единственным недостатком этого является то, что мы можем потерять возможность выполнять 80-битную операцию с плавающей запятой DP в регистре.Но консенсус, похоже, заключается в том, что если вы зависите от 80-битных чисел с плавающей запятой вместо 64-битных для точности, вам следует искать более точный алгоритм, устойчивый к потерям.

Все вышеперечисленное стало для меня полной неожиданностью.Это очень противоречиво.Но данные говорят.

Скорее всего, вы увидите лишь очень небольшое ускорение, если оно вообще будет, и процесс окажется более сложным, чем ожидалось.Более подробную информацию см. Вездесущий векторный класс SSE статья Фабиана Гизена.

Вездесущий векторный класс SSE:Развенчание распространенного мифа

Не так важно

Прежде всего, ваш векторный класс, вероятно, не так важен для производительности вашей программы, как вы думаете (а если и так, то это скорее потому, что вы делаете что-то неправильно, чем потому, что вычисления неэффективны).Не поймите меня неправильно, вероятно, это будет один из наиболее часто используемых классов во всей вашей программе, по крайней мере, при работе с 3D-графикой.Но тот факт, что векторные операции будут распространены, не означает автоматически, что они будут доминировать во времени выполнения вашей программы.

Не так жарко

Не просто

Не сейчас

Никогда не

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