Das Problem kann wie folgt beschrieben werden.
Entrada
__m256d a, b, c, d
Ausgabe
__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]}
Bisher geleistete Arbeit
Es schien einfach genug: zwei VHADD mit etwas Mischen dazwischen, aber tatsächlich kann die Kombination aller Permutationen, die AVX bietet, nicht genau die Permutation erzeugen, die nötig ist, um dieses Ziel zu erreichen. Lassen Sie mich das erklären:
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]}
Könnte ich x und y auf die gleiche Weise permutieren, um Folgendes zu erhalten
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]}
dann
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]}
Das ist das gewünschte Ergebnis.
Ich muss also nur herausfinden, wie ich die
x,y => {x[0], x[2], y[0], y[2]}, {x[1], x[3], y[1], y[3]}
Leider bin ich zu dem Schluss gekommen, dass dies mit jeder Kombination von VSHUFPD, VBLENDPD, VPERMILPD, VPERM2F128, VUNPCKHPD, VUNPCKLPD nachweislich unmöglich ist. Der springende Punkt ist, dass es unmöglich ist, u[1] und u[2] in einer Instanz u von __m256d zu vertauschen.
Frage
Ist das wirklich eine Sackgasse? Oder habe ich eine Permutationsanweisung übersehen?