c/c++语言开发共享确定__m256值的SIMD通道的最小值

我知道通常应避免跨SIMD通道的操作。 但是,有时必须这样做。

我正在使用AVX2内在函数,并在__m256中有8个浮点值。

我想知道这个向量中的最低值,并使问题复杂化:也就是在哪个插槽中。

我目前的解决方案是内存往返,我不喜欢:

float closestvals[8]; _mm256_store_ps( closestvals, closest8 ); float closest = closestvals[0]; int closestidx = 0; for ( int k=1; k<8; ++k ) { if ( closestvals[k] < closest ) { closest = closestvals[ k ]; closestidx = k; } } 

没有去往/从记忆中这样做的好方法是什么?

    你可以试试这个:

     #include  #include  #include  /* gcc -O3 -Wall -m64 -march=haswell hor_min.c */ int print_vec_ps(__m256 x); int main() { float x[8]={1.2f, 3.6f, 2.1f, 9.4f, 4.0f, 0.1f, 8.9f, 3.3f}; /* Note that the results are not useful if one of the inputs is a 'not a number'. The input below leads to indx = 32 (!) */ // float x[8]={1.2f, 3.6f, 2.1f, NAN, 4.0f, 2.0f , 8.9f, 3.3f}; __m256 v0 = _mm256_load_ps(x); /* _mm256_shuffle_ps instead of _mm256_permute_ps is also possible, see Peter Cordes' comments */ __m256 v1 = _mm256_permute_ps(v0,0b10110001); /* swap floats: 0<->1, 2<->3, 4<->5, 6<->7 */ __m256 v2 = _mm256_min_ps(v0,v1); __m256 v3 = _mm256_permute_ps(v2,0b01001110); /* swap floats */ __m256 v4 = _mm256_min_ps(v2,v3); __m256 v5 = _mm256_castpd_ps(_mm256_permute4x64_pd(_mm256_castps_pd(v4),0b01001110)); /* swap 128-bit lanes */ __m256 v_min = _mm256_min_ps(v4,v5); __m256 mask = _mm256_cmp_ps(v0,v_min,0); int indx = _tzcnt_u32(_mm256_movemask_ps(mask)); printf(" 7 6 5 4 3 2 1 0n"); printf("v0 = ");print_vec_ps(v0 ); printf("v1 = ");print_vec_ps(v1 ); printf("v2 = ");print_vec_ps(v2 ); printf("nv3 = ");print_vec_ps(v3 ); printf("v4 = ");print_vec_ps(v4 ); printf("nv5 = ");print_vec_ps(v5 ); printf("v_min = ");print_vec_ps(v_min ); printf("mask = ");print_vec_ps(mask ); printf("indx = ");printf("%dn",indx); return 0; } int print_vec_ps(__m256 x){ float v[8]; _mm256_storeu_ps(v,x); printf("%5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2fn", v[7],v[6],v[5],v[4],v[3],v[2],v[1],v[0]); return 0; } 

    输出:

     ./a.out 7 6 5 4 3 2 1 0 v0 = 3.30 8.90 0.10 4.00 9.40 2.10 3.60 1.20 v1 = 8.90 3.30 4.00 0.10 2.10 9.40 1.20 3.60 v2 = 3.30 3.30 0.10 0.10 2.10 2.10 1.20 1.20 v3 = 0.10 0.10 3.30 3.30 1.20 1.20 2.10 2.10 v4 = 0.10 0.10 0.10 0.10 1.20 1.20 1.20 1.20 v5 = 1.20 1.20 1.20 1.20 0.10 0.10 0.10 0.10 v_min = 0.10 0.10 0.10 0.10 0.10 0.10 0.10 0.10 mask = 0.00 0.00 -nan 0.00 0.00 0.00 0.00 0.00 indx = 5 

    在此答案的先前版本中,128位通道与_mm256_permute2f128_ps交换。 在这个更新的答案中, _mm256_permute2f128_ps被替换为_mm256_permute4x64_pd ,这在AMD CPU和Intel KNL上更快,请参阅@Peter Cordes的评论。 但请注意, _mm256_permute4x64_pd需要AVX2,而AVX足够_mm256_permute2f128_ps

    另请注意,如果其中一个输入值为“非数字”(NAN),则此代码的结果无效。

      以上就是c/c++开发分享确定__m256值的SIMD通道的最小值相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/560436.html

      (0)
      上一篇 2021年1月28日
      下一篇 2021年1月28日

      精彩推荐