Встроенное расширение векторного типа Clang: вопрос выравнивания и проверка того, что оно действительно работает
Я заинтересован в использовании расширения вектора clang, такого как:
typedef float vec3 __attribute__((ext_vector_type(3)));
У меня есть 2 вопроса:
Как вы можете видеть в примере выше и ниже, меня в первую очередь интересует использование их для манипулирования вектором vec3 (xyz). Насколько я понимаю, обычно размер модуля SIMD составляет 128 бит. Если бы я использовал vec3, это заняло бы 96 бит. Поэтому мне интересно, есть ли наказание за неиспользование ровно 128 бит или если бы я использовал vec2, может быть, компилятор смог бы упаковать два vec2 в единицу? Должен ли я вместо этого использовать vec4, даже если в большинстве случаев я не буду использовать четвертый элемент? Это лучше с точки зрения выравнивания/производительности?
Я хотел бы в конечном итоге «измерить», насколько эффективнее использование этих расширений по сравнению с использованием стандартных структур. Кроме запуска их в цикле большое количество раз (и измерения времени), я не знаю другого способа, но это кажется очень наивным. Это даже не очень информативно в случае с небольшим примером, который я привожу ниже, потому что, когда я компилирую его с
-O3
код работает очень быстро в любом случае. Могу ли я также как-то сказать, что они оптимизированы, глядя на сгенерированный код ASM (я пробовал, и хотя код довольно короткий, код, сгенерированный ASM, уже довольно длинный, и помимо понимания основ это немного подавляет)? Предложения будут очень признательны, если моя цель важна, чтобы доказать себе), что использование этих расширений создает исполняемый файл, который работает быстрее.
typedef float vec3 __attribute__((ext_vector_type(3)));
struct vec3f { float x, y, z; };
int main(int argc, char **argv)
{
for (unsigned long i = 0; i < 1e12; ++i) {
for (unsigned long j = 0; j < 1e12; ++j) {
#if 1
vec3 a = {1, 0, 0};
vec3 b = {0, 1, 0};
vec3 lhs = a.yzx * b.zxy;
vec3 rhs = a.zxy * b.yzx;
vec3 c = lhs - rhs;
#else
vec3f a = {1, 0, 0};
vec3f b = {0, 1, 0};
vec3f c;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
#endif
//printf("%f %f %f\n", c.x, c.y, c.z);
}
}
return EXIT_SUCCESS;
}