uint32_t * uint32_t = uint64_t умножение вектора с помощью gcc
Я пытаюсь перемножить векторы uint32_t
получение полного 64-битного результата в uint64_t
вектор в gcc. В результате, я ожидаю, что gcc выдаст одинVPMULUDQ
инструкция. Но то, что gcc выводит как код, ужасно перетасовывает индивидуумuint32_t
исходных векторов, а затем полное 64*64=64 умножение. Вот что я пробовал:
#include <stdint.h>
typedef uint32_t v8lu __attribute__ ((vector_size (32)));
typedef uint64_t v4llu __attribute__ ((vector_size (32)));
v4llu mul(v8lu x, v8lu y) {
x[1] = 0; x[3] = 0; x[5] = 0; x[7] = 0;
y[1] = 0; y[3] = 0; y[5] = 0; y[7] = 0;
return (v4llu)x * (v4llu)y;
}
Первый маскирует нежелательные части uint32_t
вектор в надежде, что gcc оптимизирует ненужные части умножения 64*64=64, а затем увидит, что маскирование также бессмысленно. Нет такой удачи.
v4llu mul2(v8lu x, v8lu y) {
v4llu tx = {x[0], x[2], x[4], x[6]};
v4llu ty = {y[0], y[2], y[4], y[6]};
return tx * ty;
}
Здесь я пытаюсь создать uint64_t
вектор с нуля с набором только использованных деталей. Опять же, gcc должен увидеть верхние 32 бита каждогоuint64_t
равны 0 и не выполняют полное умножение 64*64=64. Вместо этого происходит много извлечения и возврата значений, и 64*64=64 умножаются.
v4llu mul3(v8lu x, v8lu y) {
v4llu t = {x[0] * (uint64_t)y[0], x[2] * (uint64_t)y[2], x[4] * (uint64_t)y[4], x[6] * (uint64_t)y[6]};
return t;
}
Построим вектор результата, умножив части. Может быть, gcc видит, что может использоватьVPMULUDQ
чтобы добиться именно этого. Не повезло, он возвращается к 4IMUL
коды операций.
Есть ли способ сказать gcc, что я хочу, чтобы он делал (32*32=64 умножение, все размещено идеально)?
Примечание: встроенный asm или встроенный - это не ответ. Написание кода операции вручную, очевидно, работает. Но тогда мне пришлось бы писать разные версии кода для многих целевых архитектур и наборов функций. Я хочу, чтобы gcc понял проблему и создал правильное решение из единого исходного кода.
1 ответ
Как отмечено в комментариях chtz, mul1 и mul2 оптимизированы с помощью clang. Код, похожий на mul3, но с использованием цикла for, тоже будет оптимизирован (но не так хорошо).
Поэтому мне кажется, что синтаксис правильный, чтобы выразить то, что должен делать код, а gcc пока просто не хватает умов, чтобы оптимизировать это правильно.