2016-05-22 3 views
0

Я хочу, чтобы SSE использовался для арифметики на моих 3D-плавающих векторах (96 бит). Однако я читал противоречивые мнения о том, что необходимо.SSE-выравнивание 3D-вектора

Некоторые статьи/сообщения говорят, что мне нужно использовать 4D-вектор и «игнорировать» 4-й элемент, некоторые говорят, что я должен украсить свой класс такими вещами, как __declspec(align(16)), и переопределить оператор new, а некоторые говорят, что компилятор достаточно умен, чтобы выровняйте вещи для меня (я действительно надеюсь, что это правда!).

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

Множество статей, которые я прочитал, уже несколько лет, поэтому я надеюсь, что современные компиляторы/версии SSE/процессоры могут просто выровнять данные для меня или работать с не согласованными по 16 байт данными. Любые современные знания об этом будут высоко оценены!

+3

Процессоры не могут просто уйти и начать выравнивать материал самостоятельно, они выполняют только то, что говорит код.Кроме того, если это возможно, остановите эту идею и вместо этого используйте SIMD по отдельным координатам, поэтому вам не нужно тратить 4-ю полосу (и, как правило, почти все работает лучше, так что векторы SIMD не предназначены для использования в качестве векторов linalg) – harold

+0

Спасибо за комментарий (не понимаю, почему этот вопрос был занижен ...). В любом случае, я не уверен, что вы подразумеваете под «использованием SIMD по отдельным координатам» - вы имеете в виду объемную обработку нескольких 3D-векторов (что было бы круто, если это возможно)? Я также только что открыл C++ 11 'alignas (16)' decorator. Я добавил его, чтобы обернуть свой универсальный векторный класс, и он не вызвал сбой, но, конечно, не используется доказательство SIMD. – Dave

+0

Да, массовая обработка, возможно, используйте 3 указателя (x, y, z) в блок, который вы получили с _aligned_malloc. Кроме того, при необходимости вы можете загрузить/сохранить неглавные. Вся эта декларативная процедура выравнивания не очень хорошо работает на всех материалах C++, например, если вы поместили этот тип в контейнер, он все равно сломается, если вы не используете пользовательский распределитель. – harold

ответ

1

Фактически мы используем SIMD на работе, и, возможно, я могу дать вам свои отзывы об этом. Согласование - это то, о чем вы должны заботиться при работе с SIMD, это для обеспечения выравнивания линии кэша. Однако я не уверен, будет ли он по-прежнему вызывать сбои, если он не выровнен или если процессор в состоянии управлять в любом случае (например, не выровненные скалярные типы в старое время, это вызывало крах, теперь процессор обрабатывает его, но он замедляется вниз). Возможно, вы можете посмотреть здесь SSE, intrinsics, and alignment Кажется, у вас есть хорошие ответы на вопрос о выравнивании вопроса.

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

Примечание: Я предполагаю, что 128 бит SIMD регистров, отображенные на 4 типа скалярных (INT или с плавающей точкой)

Например, если у вас есть 4 3D точки (или векторы), следуя пути, вы будете иметь 4 4D векторов, игнорирующих 4-й компонент каждой точки. В итоге вы получаете доступные 4 * 4 значения.

Используя SOA, вы будете иметь 3 SIMD 128 бит (12 значений), и вы сохраните свои очки следующим образом. SIMD

  • r1: х х х х
  • r2: у Y Y Y
  • r3: г г г Z

Таким образом, вы заполняете целые регистры SIMD и, следовательно, прибыль максимум преимуществ SIMD. Другое дело, что многие вычисления, которые вам нужно будет сделать (например, добавить 2 группы из 4 векторов), будут принимать только 3 SIMD-инструкции. Это немного сложно использовать и понимать, но когда вы это делаете, выигрыш велик.

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

+1

16 ** байт **. Unaligned может сбой, если вы используете '_mm_load_ps' (даже с AVX вместо SSE), но не если вы используете' _mm_loadu_ps'. –

+0

Скалярный неуравновешенный никогда не был неисправен на x86. Возможно, вы помните, что работали с другой архитектурой в прошлом. Для меня я помню, что у меня была ошибка кода в ящиках Solaris с процессорами SPARC в школе. –

+1

Да, еще лучше AoSoA. См. Http://compilers.cs.uni-saarland.de/papers/leissa_vecimp_tr.pdf –