问题可以描述如下。
输入
__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 的任何组合都证明是不可能的。问题的关键在于,在 __m256d 的实例 u 中交换 u[1] 和 u[2] 是不可能的。
问题
这真的是死胡同吗?还是我错过了排列指令?