我正在尝试向量化一些代码。 想法:我们有一个像素(__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/