В настоящее время я пробую свои силы в создании собственной векторной математической библиотеки C++, и я заинтересован в ее оптимизации с помощью SSE. Для моих типов данных vec2 и vec3 я не могу хранить тип __m128 напрямую, так как они должны иметь ожидаемые размеры, но как насчет vec4? Предположим, мой тип vec4 выглядит примерно так (, игнорируя требование выравнивания по 16 -байтам для простоты обсуждения):
union vec4 {
struct {float x, y, z, w;};
__m128 sse;
}
vec4 operator+(const vec4& left, const vec4& right) {
vec4 result;
result.sse = _mm_add_ps(left.sse, right.sse);
return result;
}
Это предлагаемый способ сделать это или есть какая-то веская причина, о которой я не могу думать? То есть, должен ли я сделать это вместо этого:
struct vec4 {
float x, y, z, w;
};
vec4 operator+(const vec4& left, const vec4& right) {
__m128 leftSSE = _mm_load_ps(reinterpret_cast<const float*>(&left));
__m128 rightSSE = _mm_load_ps(reinterpret_cast<const float*>(&right));
__m128 resultSSE = _mm_add_ps(leftSSE, rightSSE);
vec4 result;
_mm_store_ps(reinterpret_cast<float*>(&result), resultSSE);
return result;
}
И пока мы на этом, как насчет моих теоретических типов vec2 и vec3? Было бы быстрее сначала преобразовать их в vec4, а затем использовать SIMD-инструкции или просто обрабатывать их скалярные элементы по отдельности?