Я пишу HLSL float4-совместимый тип на C++ с встроенными функциями SSE2/AVX, и на данный момент я реализую все операции с набором-swizzle, доступные для float4 в HLSL. Я пытаюсь найти оптимальную реализацию SSE2 для обработки операций set-swizzle с участием (swizzle), устанавливающих 2 или 3 компонента (поскольку 4-компонентные набор-swizzles тривиальны для реализации с помощью одного SSE shuffle op). Например, я не могу понять, лучший способ реализовать сказать set_wxy без по крайней мере, 4/5 SSE перетасовка опса т.д .:Лучшая реализация SSE2 для float4 :: set_wxy (и других опций set-swizzle)?
inline/__forceinline void float4::set_wxy(const float4& x)
{
float4 tmp2 = *this;
tmp2.set_wxyz(x); // set_wxyz = 1 x _mm_shuffle_ps
const __m128 xyw_tmp = tmp2.zxyw().data; // zxyw() = 1 x _mm_shuffle_ps
const __m128 z_tmp = zxyw().data; // zxyw() = 1 x _mm_shuffle_ps
tmp2 = _mm_move_ss(xyw_tmp, z_tmp);
set_zxyw(tmp2); // set_zxyw() = 1 x _mm_shuffle_ps
}
Кто-нибудь есть какие-либо идеи для более эффективной реализации без использования операций за SSE2? поскольку я знаю _mm_blend_ps в SSE4/AVX, для которого я буду использовать, когда доступен через условные обозначения препроцессора, но я хочу поддерживать хотя бы один кодовый путь SSE2. Заранее спасибо!
EDIT: пример поведения этой функции:
float4 k(5,5,5,5);
k.set_wxy(float4(1,2,3,4));
// now k == (2, 3, 5, 1)
В основном set_wxy устанавливает W, X, Y компоненты, используя аргументы х, у, г в этом порядке, первоначальное значение г сохраняется.
Что именно должно установить set_wxy? Я попытался вывести его из кода, но слишком много его скрыто. – harold
@harold Хорошо. Я только что добавил дополнительную информацию о поведении этих функций. Надеюсь, это немного облегчит ситуацию. Спасибо за прочтение. –
взгляните на источник DirectXMath в SDK Windows 8 ('DirectXMath.h'), он имеет очень быстрые SSE2-операции для swizzles и т. Д. (И его запись должна соответствовать DX & HLSL). TBH, вы, вероятно, могли бы использовать математику DX прямо, сэкономить усилия – Necrolis