如何访问256位ps向量的组件

时间:2012-10-21 17:31:42

标签: c sse intrinsics avx

如何有效地访问256位向量的元素?例如,我用

计算了点积
c = _mm256_dp_ps(a, b, 0xff);

如何访问c中的值呢?我需要同时获得高部分和低部分,我是否正确理解我首先需要提取这样的128位部分:

r0 = _mm256_extractf128_ps(c,0);
r1 = _mm256_extractf128_ps(c,1);

然后才提取漂浮物:

_MM_EXTRACT_FLOAT(fr0, r0, 0);
_MM_EXTRACT_FLOAT(fr1, r1, 0);

return fr0 + fr1;

2 个答案:

答案 0 :(得分:4)

好吧,你可以存储到内存然后使用标量:

float v[8];
*(__m256)(v) = _mm256_dp_ps(a, b, 0xff);
float result = v[0] + v[4];

您也可以将256位寄存器的顶部交换到下半部分并添加,如下所示:

__m256 c = _mm256_dp_ps(a, b, 0xff);
__m256 d = _mm256_permute2f128_ps(c, c, 1);
__m256 result = _mm256_add_ps(c, d);

比任何一个选项都快得多,一次做4x 8宽点产品并将它们减少在一起。草图:

d0 = _mm256_dp_ps(a[0], b[0], 0xff);
d1 = _mm256_dp_ps(a[1], b[1], 0xff);
d2 = _mm256_dp_ps(a[2], b[2], 0xff);
d3 = _mm256_dp_ps(a[3], b[3], 0xff);

d01 = _mm256_permute_ps(d0, d1, ...);
d23 = _mm256_permute_ps(d2, d3, ...);
d0123 = _mm256_permute_ps(d01, d23, ...);

d0123upper = _mm256_permute2f128_ps(d0123, d0123, 1);
d = _mm256_add_ps(d0123upper, d0123); // lower 128 bits contain the results of 4 8-wide dot products

答案 1 :(得分:-1)

没有有效的方法可以做到这一点。 dp_ps操作本身很慢,后续提取很慢。除非可以批处理更多数据,否则使用SSE4指令计算点积并使用128位比使用256位更快。