繁体   English   中英

SSE到C ++代码

[英]SSE to C++ code

我试图将包含SSE指令的c ++源代码中的代码重写为仅c ++代码。 我知道我会失去表现,但它是一个实验,我正在努力表现。 我想知道是否存在与__mm_unpackhi_pd和__mm_unpacklo_pd相同的C ++等价物。 我对SSE一无所知。

我试图转换的代码片段供参考。 任何知识或提示都会有所帮助。 谢谢。

for (unsigned chunk = 0; chunk < chunks; chunk++)
{
  unsigned start = chunk * chunksize;
  unsigned end =
    std::min((chunk + 1) * chunksize, (unsigned)2 * w);
  __m128d a2b2 =
    _mm_load_pd(d_origx +
                ((2 * init_G_offset + start) & n2_m_1));
  unsigned i2_mod_B = 0;
  for (unsigned i = start; i < end; i += 2)
    {
      __m128d ab = a2b2;
      a2b2 =
        _mm_load_pd(d_origx +
                    ((origx_offset + i) & n2_m_1));
      __m128d cd = _mm_load_pd(d_filter + i);

      __m128d cc = _mm_unpacklo_pd(cd, cd);
      __m128d dd = _mm_unpackhi_pd(cd, cd);

      __m128d a0a1 = _mm_unpacklo_pd(ab, a2b2);
      __m128d b0b1 = _mm_unpackhi_pd(ab, a2b2);

      __m128d ac = _mm_mul_pd(cc, a0a1);
      __m128d ad = _mm_mul_pd(dd, a0a1);
      __m128d bc = _mm_mul_pd(cc, b0b1);
      __m128d bd = _mm_mul_pd(dd, b0b1);

      __m128d ac_m_bd = _mm_sub_pd(ac, bd);
      __m128d ad_p_bc = _mm_add_pd(ad, bc);

      __m128d ab_times_cd = _mm_unpacklo_pd(ac_m_bd, ad_p_bc);
      __m128d a2b2_times_cd =
        _mm_unpackhi_pd(ac_m_bd, ad_p_bc);

      __m128d xy = _mm_load_pd(d_x_sampt + i2_mod_B);
      __m128d x2y2 = _mm_load_pd(d_x_sampt + i2_mod_B + 2);

      __m128d st = _mm_add_pd(xy, ab_times_cd);
      __m128d s2t2 = _mm_add_pd(x2y2, a2b2_times_cd);

      _mm_store_pd(d_x_sampt + i2_mod_B, st);
      _mm_store_pd(d_x_sampt + i2_mod_B + 2, s2t2);

      i2_mod_B += 4;
    }
}

下面你会找到两个函数的描述,我还将每个函数链接到它的参考页面。 整个参考资料可在此处获取: https//software.intel.com/sites/landingpage/IntrinsicsGuide/

_mm_unpackhi_p

__m128d _mm_unpackhi_pd (__m128d a, __m128d b)

从a和b的高半部分解包并交错双精度(64位)浮点元素,并将结果存储在dst中。


_mm_unpacklo_pd

_m128d _mm_unpacklo_pd (__m128d a, __m128d b)

从a和b的低半部分解包并交错双精度(64位)浮点元素,并将结果存储在dst中。

具体如何实现它取决于你的表示,但基本上你返回一个新的值,由ab的高(或低)一半连接的高(或低)一半组成。 例如:

typedef double[2] __m128d;

__m128d _mm_unpackhi_pd(__m128d a, __m128d b) {
  __m128d res;
  res[0] = a[1];
  res[1] = b[1];
  return res;
}

__m128d _mm_unpacklo_pd(__m128d a, __m128d b) {
  __m128d res;
  res[0] = a[0];
  res[1] = b[0];
  return res;
}

关于这个问题的错误时机......我在为SIMDe实现这个功能时发现了这个问题,而且它只有17天了。 如果您想使用SIMDe作为参考,这些函数与sse2.h以及许多其他函数一起使用。 SIMDe中的代码比上面的代码复杂得多,但这主要是为了匹配其他_mm_unpack*函数的实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM