Проблема может быть описана следующим образом.
Входные данные
__m256d a, b, c, d
Выходные данные
__m256d s = {a[0]+a[1]+a[2]+a[3], b[0]+b[1]+b[2]+b[3],
c[0]+c[1]+c[2]+c[3], d[0]+d[1]+d[2]+d[3]}
Работа, которую я проделал до сих пор
Это казалось достаточно простым: два VHADD с некоторой перетасовкой между ними, но на самом деле объединение всех перестановок, представленных AVX, не может создать необходимую перестановку. для достижения этой цели. Позвольте мне объяснить:
VHADD x, a, b => x = {a[0]+a[1], b[0]+b[1], a[2]+a[3], b[2]+b[3]}
VHADD y, c, d => y = {c[0]+c[1], d[0]+d[1], c[2]+c[3], d[2]+d[3]}
Мог ли я переставить x и y таким же образом, чтобы получить
x1 = {a[0]+a[1], a[2]+a[3], c[0]+c[1], c[2]+c[3]}
y1 = {b[0]+b[1], b[2]+b[3], d[0]+d[1], d[2]+d[3]}
, а затем
VHADD s, x1, y1 => s1 = {a[0]+a[1]+a[2]+a[3], b[0]+b[1]+b[2]+b[3],
c[0]+c[1]+c[2]+c[3], d[0]+d[1]+d[2]+d[3]}
, что и является тем результатом, которого я хотел.
Таким образом, мне просто нужно найти, как выполнить
x,y => {x[0], x[2], y[0], y[2]}, {x[1], x[3], y[1], y[3]}
К сожалению, я пришел к выводу, что это доказуемо невозможно, используя любую комбинацию VSHUFPD, VBLENDPD, VPERMILPD, VPERM2F128, VUNPCKHPD, VUNPCKLPD. Суть дела в том, что нельзя поменять местами u[1] и u[2] в экземпляре u из __m256d.
Вопрос
Неужели это тупик? Или я пропустил инструкцию перестановки?