c - SSE:有条件地替换像素

标签 c gcc gnu sse

我正在尝试向量化一些代码。 想法:我们有一个像素(__m128 in),如果它的任何元素大于upper,用不同的像素(__m128 upper_color)替换entier像素

有效的非向量化代码:

if(inp[0] >= upper || inp[1] >= upper || inp[2] >= upper)
{
  outp[0] = upper_color[0];
  outp[1] = upper_color[1];
  outp[2] = upper_color[2];
}

到目前为止我想到了以下内容,但(我相信如此)它不会替换整个像素,而只会替换那些比上部大的组件:

  const __m128 pixel = _mm_load_ps(in);
  const __m128 isoe = _mm_cmpge_ps(pixel, upper);
  __m128 result = _mm_or_ps(_mm_andnot_ps(isoe, pixel),
                            _mm_and_ps(isoe, upper_color));
  _mm_stream_ps(out, result);

让我们假设 upper = 1,1,1 和 upper_color = 1,0,0

第四 channel 是 alpha,所以我不关心它。

结果:

IN:   0.5 0.3 0.7
OUT:  0.5 0.3 0.7 (Expected)
OUT:  0.5 0.3 0.7 (Recieved)

IN:   1.5 1.1 0.7
OUT:  1   0   0   (Expected)
OUT:  1   0   0.7 (Recieved)

也许有人可以帮助我?这可能吗?

最佳答案

您需要计算水平或。 SSE 中没有水平 OR 指令,但是可以使用 2x UNPACK + 垂直 OR 来模拟这种操作。

const __m128 pixel = _mm_load_ps(in);
/* (p3, p2, p1, p0 ) */
__m128 isoe = _mm_cmpge_ps(pixel, upper);
/* (p3|p1, p2|p0, p3|p1, p2|p0) */
isoe = _mm_or_ps(_mm_unpacklo_ps(isoe, isoe), _mm_unpackhi_ps(isoe, isoe));
/* (p3|p2|p1|p0, p3|p2|p1|p0, p3|p2|p1|p0, p3|p2|p1|p0) */
isoe = _mm_or_ps(_mm_unpacklo_ps(isoe, isoe), _mm_unpackhi_ps(isoe, isoe));
__m128 result = _mm_or_ps(_mm_andnot_ps(isoe, pixel), _mm_and_ps(isoe, upper_color));
_mm_stream_ps(out, result);

关于c - SSE:有条件地替换像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23049600/

相关文章:

无法正确打印 txt 文件

c - 为什么每次迭代都会打印两次消息?

c - 防止启动程序时弹出终端窗口

c++ - 在多核 (linux) 中运行进程的命令行参数是什么

c++ - GCC:如何只生成行号调试信息?

c++ - 编辑距离递归算法——Skiena

c - 使用 Apache/FastCGI 生成多个 C 可执行进程

assembly - 如何防止 GNU ld 对目标文件重新排序?

makefile - Autotools 库和目标文件输出控制

gcc - 我如何编译*不*启用各种指令集?