使用SSE的水平最小和最大 [英] Horizontal minimum and maximum using SSE

查看:151
本文介绍了使用SSE的水平最小和最大的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用SSE进行很多工作的函数,分析器向我显示,我用来计算水平最小和最大水平的代码部分大部分时间都在消耗.

I have a function using SSE to do a lot of stuff, and the profiler shows me that the code portion I use to compute the horizontal minimum and maximum consumes most of the time.

例如,我一直在使用以下实现作为最低要求:

I have been using the following implementation for the minimum for instance:

static inline int16_t hMin(__m128i buffer) {
    buffer = _mm_min_epi8(buffer, _mm_shuffle_epi8(buffer, m1));
    buffer = _mm_min_epi8(buffer, _mm_shuffle_epi8(buffer, m2));
    buffer = _mm_min_epi8(buffer, _mm_shuffle_epi8(buffer, m3));
    buffer = _mm_min_epi8(buffer, _mm_shuffle_epi8(buffer, m4));
    return ((int8_t*) ((void *) &buffer))[0];
}

如您所见,我需要计算16个1字节整数的最小值和最大值.

I need to compute the minimum and the maximum of 16 1-byte integers, as you see.

任何好的建议都会受到高度赞赏:)

Any good suggestions are highly appreciated :)

谢谢

推荐答案

我建议进行两项更改:

  • _mm_cvtsi128_si32替换((int8_t*) ((void *) &buffer))[0].
  • _mm_shuffle_epi32/_mm_shufflelo_epi16替换_mm_shuffle_epi8,它们在最新的AMD处理器和Intel Atom上具有较低的延迟,并且可以节省内存加载操作:

  • Replace ((int8_t*) ((void *) &buffer))[0] with _mm_cvtsi128_si32.
  • Replace _mm_shuffle_epi8 with _mm_shuffle_epi32/_mm_shufflelo_epi16 which have lower latency on recent AMD processors and Intel Atom, and will save you memory load operations:

static inline int16_t hMin(__m128i buffer)
{
    buffer = _mm_min_epi8(buffer, _mm_shuffle_epi32(buffer, _MM_SHUFFLE(3, 2, 3, 2)));
    buffer = _mm_min_epi8(buffer, _mm_shuffle_epi32(buffer, _MM_SHUFFLE(1, 1, 1, 1)));
    buffer = _mm_min_epi8(buffer, _mm_shufflelo_epi16(buffer, _MM_SHUFFLE(1, 1, 1, 1)));
    buffer = _mm_min_epi8(buffer, _mm_srli_epi16(buffer, 8));
    return (int8_t)_mm_cvtsi128_si32(buffer);
}

这篇关于使用SSE的水平最小和最大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆