三维向量运算SSE/SSE2优化

减小字体 增大字体作者:chaos  来源:本站整理  发布时间:2009-12-04 15:49:00
    rsqrt =
_mm_mul_ss(
_mm_mul_ss( _05 , rsqrt ) ,
_mm_sub_ss( _3 , _mm_mul_ss( a , _mm_mul_ss( rsqrt , rsqrt ) ) ) );
    return rsqrt;
}

那么就可以轻松得出单位化向量的函数了:

// normalize & return value
__m128 _mm_normalize( const __m128 a ) {
    // get length square
    __m128 l = _mm_square_ps( a );
    // test if length is zero
    if( _mm_iszero_ss( l ) )
        return z;
    // length inverse
    l = _mm_rsqrt( l );
    // shuffle
    l = _mm_shuffle_ps( l , l , 0 );
    // multiply to vector
    return _mm_mul_ps( a , l );
}

SSE除了以上这些数学运算操作外,还提供了位运算。位运算?想到什么了吗?对!比较与选择。首先来看一个最简单的,求绝对值。通常我们会把 abs 写成非常简洁的形式:
float abs( float a ) {
    a >= 0 ? a : -a;
}

但当我们已经Pack了一个向量到__m128结构里,而又不希望Unpack他们进行浮点数的比较,那么就可以使用SSE的位操作。
/* abs */
__m128 _mm_abs_ps( __m128 a )
{
    static const union { int i[4]; __m128 m; } __mm_abs_mask_cheat_ps
= {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff};
    return _mm_and_ps( a, __mm_abs_mask_cheat_ps.m );
}

还记得单精度浮点数的符号存放在什么位上面吗?我们只需把它除掉,然后就可以很轻松地得到了正值了。

图形程序很多时候会用到32位浮点色彩,其值域通常为[0,1],所以clamp函数出现的频率也十分频繁。要将rgba的值同时clamp到值域内,毫无疑问,SSE的并行特性又得到了发挥的机会。先来看cut函数,它负责把超出值域的值干掉,但为了更灵活,我们一次只cut一边的区间,所以cut有两兄弟,分别是locut和hicut。
__m128 _mm_locut_ps( __m128 val , __m128 bound )
{
    __m128 mask = _mm_cmplt_ps( val , bound );
    return _mm_or_ps( _mm_and_ps( mask , bound ) , _mm_andnot_ps( mask , val ) );
}
__m128 _mm_hicut_ps( __m128 val , __m128 bound )
{
    __m128 mask = _mm_cmpgt_ps( val , bound );
    return _mm_or_ps( _mm_and_ps( mask , bound ) , _mm_andnot_ps( mask , val ) );
}

_mm_cmp**_ps是一系列的比较函数,非常丰富,也很好用,如果替换成相应的if-else,并行性将被大大削弱。不过_mm_cmp**_ps的最大缺点就是灵活度不够,返回值是一系列位标记,其具体的用法将在SSE汇编中讨论。有了这俩哥们,clamp变得非常简单:

__m128 _mm_clamp_ps( __m128 val , __m128 min , __m128 max )
{
    return _mm_locut_ps( _mm_hicut_ps( val , max ) , min );
}

以上只是一些很简单的实现,利用了SSE intrinsic对数学运算进行优化,并尽可能地不分拆向量,这样可以保证8个128位的xmm寄存器可以满足大部分运算。不过SSE intrinsic始终受编译器生成代码的质量好坏影响,没能真正发挥出SSE的全部威力,接下来我们将讨论SSE汇编的用法与优化。
 

上一页  [1] [2] [3] [4] [5] [6] 

  • 好的评价 如果您觉得此文章好,就请您
      100%(2)
  • 差的评价 如果您觉得此文章差,就请您
      0%(0)
   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论

用户名:   验证码:

分 值:100分 85分 70分 55分 40分 25分 10分 1分

内 容:

      若文章有错误,请将右边打钩通知管理员

关于本站 - 友情连接 - 网站地图 - 我要留言