首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在256位AVX矢量中找到水平最大值

如何在256位AVX矢量中找到水平最大值
EN

Stack Overflow用户
提问于 2012-03-21 05:48:59
回答 3查看 8.9K关注 0票数 16

我有一个包含四个64位浮点值的__m256d向量。

我需要找到向量元素的水平最大值,并将结果存储在双精度标量值中;

我的尝试最终都使用了大量的向量元素,使得代码不是很优雅,也不是很有效。此外,我发现只停留在AVX域是不可能的。在某些情况下,我不得不使用SSE 128位指令来提取最终的64位值。然而,我希望在这最后一句话上被证明是错误的。

因此,理想的解决方案是:

1)仅使用AVX指令。

2)最小化指令数量。(我希望不超过3-4条说明)

话虽如此,任何优雅/高效的解决方案都会被接受,即使它不遵守上面的指导方针。

谢谢你的帮助。

-Luigi

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-21 15:43:55

我不认为你能比4个指令做得更好:2个混洗和2个比较。

代码语言:javascript
复制
__m256d x = ...; // input

__m128d y = _mm256_extractf128_pd(x, 1); // extract x[2], and x[3]
__m128d m1 = _mm_max_pd(x, y); // m1[0] = max(x[0], x[2]), m1[1] = max(x[1], x[3])
__m128d m2 = _mm_permute_pd(m1, 1); // set m2[0] = m1[1], m2[1] = m1[0]
__m128d m = _mm_max_pd(m1, m2); // both m[0] and m[1] contain the horizontal max(x[0], x[1], x[2], x[3])

仅对256位向量进行简单的修改:

代码语言:javascript
复制
__m256d x = ...; // input

__m256d y = _mm256_permute2f128_pd(x, x, 1); // permute 128-bit values
__m256d m1 = _mm256_max_pd(x, y); // m1[0] = max(x[0], x[2]), m1[1] = max(x[1], x[3]), etc.
__m256d m2 = _mm256_permute_pd(m1, 5); // set m2[0] = m1[1], m2[1] = m1[0], etc.
__m256d m = _mm256_max_pd(m1, m2); // all m[0] ... m[3] contain the horizontal max(x[0], x[1], x[2], x[3])

(未测试)

票数 21
EN

Stack Overflow用户

发布于 2012-03-21 11:51:18

对向量v1 = [A, B, C, D]执行此操作的一般方法是

  1. Permute v1 to v2 = [C, D, A, B] (交换第0个和第二个元素,以及第一个和第三个元素)
  2. 取最大值;即v3 = max(v1,v2)。你现在有了[max(A,C), max(B,D), max(A,C), max(B,D)]
  3. Permute v3 to v4,交换了第0个和第1个元素,以及第2个和第3个元素。
  4. 再次取最大值,即v5 = max(v3,v4)。现在,v5的所有组件中都包含了水平最大值。

具体地,对于AVX,可以使用_mm256_permute_pd来完成排列,并且可以使用_mm256_max_pd来完成最大值。我手头没有确切的置换面具,但它们应该很容易弄清楚。

希望这能有所帮助。

票数 12
EN

Stack Overflow用户

发布于 2015-10-30 14:49:28

代码语言:javascript
复制
//Use the code to find the horizontal maximum
__m256 v1 = initial_vector;//example v1=[1 2 3 4 5 6 7 8]
__m256 v2 = _mm256_permute_ps(v1,(int)147);//147 is control code for rotate left by upper 4 elements and lower 4 elements separately v2=[2 3 4 1 6 7 8 5]
__m256 v3 = _mm256_max_ps(v1,v2);//v3=[2 3 4 4 6 7 8 8]
__m256 v4 = _mm256_permute_ps(v3,(int)147);//v4=[3 4 4 2 7 8 8 6]
__m256 v5 = _mm256_max_ps(v3,v4);//v5=[3 4 4 4 7 8 8 8]
__m256 v6 = _mm256_permute_ps(v5,(int)147);//v6=[4 4 4 3 8 8 8 7]
__m256 v7 = _mm256_max_ps(v5,v6);//contains max of upper four elements and lower 4 elements. v7=[4 4 4 4 8 8 8 8]

//to get max of this horizontal array. Note that the highest end of either upper or lower can contain the maximum
float ALIGN max_array[8];
float horizontal_max;
_mm256_store_ps(max_array, v7);
if(max_array[3] > max_array[7])
{
    horizontal_max = max_array[3];
}
else
{
    horizontal_max = max_array[7];
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9795529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档