- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究四元数 SSE 实现以了解它们的工作原理(因为我正在实现自己的实现)并且我遇到了这个用于四元数乘法的 Bullet 实现:
VECTORMATH_FORCE_INLINE const Quat Quat::operator *( const Quat &quat ) const
{
__m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3;
__m128 product, l_wxyz, r_wxyz, xy, qw;
ldata = mVec128;
rdata = quat.mVec128;
tmp0 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,0,2,1) );
tmp1 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,1,0,2) );
tmp2 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,1,0,2) );
tmp3 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,0,2,1) );
qv = vec_mul( vec_splat( ldata, 3 ), rdata );
qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv );
qv = vec_madd( tmp0, tmp1, qv );
qv = vec_nmsub( tmp2, tmp3, qv );
product = vec_mul( ldata, rdata );
l_wxyz = vec_sld( ldata, ldata, 12 );
r_wxyz = vec_sld( rdata, rdata, 12 );
qw = vec_nmsub( l_wxyz, r_wxyz, product );
xy = vec_madd( l_wxyz, r_wxyz, product );
qw = vec_sub( qw, vec_sld( xy, xy, 8 ) );
VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff};
return Quat( vec_sel( qv, qw, sw ) );
}
我关心的是这两行:
l_wxyz = vec_sld( ldata, ldata, 12 );
r_wxyz = vec_sld( rdata, rdata, 12 );
宏实现:
#define _mm_ror_ps(vec,i) \
(((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec))
#define vec_sld(vec,vec2,x) _mm_ror_ps(vec, ((x)/4))
如果我理解正确,对于不能被 4 整除的数字(3 不是 [12/4 = 3]),vec_sld 宏将简化为:
l_wxyz = ldata;//vec_sld( ldata, ldata, 12 );
r_wxyz = rdata;//vec_sld( rdata, rdata, 12 );
实际上什么都不做。
如果该值可以被 4 整除:
q = vec_sld( x, x, 16 );
宏将缩减为:
q = _mm_shuffle_ps( x, x, _MM_SHUFFLE(3,2,1,0) );
同样,这就像什么都不做,因为 _MM_SHUFFLE(3,2,1,0) 将 x、y、z 和 w 留在它们当前的位置。
如果 vec_sld 没有做任何事情,它的目的是什么?
我错过了什么吗?
编辑:这是源代码来自的两个文件
最佳答案
我认为您在这里感到困惑的地方是,当 i
不是 的倍数时,((i)%4)
的计算结果为 TRUE 4,所以你得到一个 _mm_shuffle_ps
对于非 4 的倍数,否则你只得到原始向量(因为旋转 4 的倍数是空操作)。
一些可能有用的背景:
vec_XXX
宏表明此代码最初是从 PowerPC/AltiVec 移植的。 vec_sld
是一个 AltiVec 内在函数,它将一对向量移动给定的 字节数。在此上下文中,vec_sld
似乎被用于旋转单个矢量,因为两个输入矢量相同,而且 12 似乎作为 byte 传递移位(即旋转 3 个 float )。
所以 vec_sld(v, v, 12)
被翻译成 _mm_ror_ps(v, 12/4)
= _mm_ror_ps(v, 3)
然后扩展为:
_mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 1, 0, 3);
所以看起来代码确实在做正确的事情。
关于math - Bullet Physics 四元数 sse 实现疑惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19158976/
我是一名优秀的程序员,十分优秀!