当index = 0和XMVectorSetX时,XMVectorSetByIndex有什么区别?

时间:2016-08-21 09:21:39

标签: directx directx-11 directxmath

我阅读了DirectXMath库的源代码,发现XMVectorSetByIndexXMVectorSetX的实现完全不同。为什么XMVectorSetX只返回XMVectorSetByIndex(index = 0)?

1 个答案:

答案 0 :(得分:2)

XMVectorSetX实际上可以使用SSE或ARM-NEON内在函数,而XMVectorSetByIndex必须“溢出”到内存' (即它根本不是SIMD)。

// Set a single indexed floating point component
inline XMVECTOR XM_CALLCONV XMVectorSetByIndex(FXMVECTOR V, float f, size_t i)
{
    assert( i < 4 );
    _Analysis_assume_( i < 4 );
#if defined(_XM_NO_INTRINSICS_)
    XMVECTOR U;
    U = V;
    U.vector4_f32[i] = f;
    return U;
#elif defined(_XM_ARM_NEON_INTRINSICS_)
    XMVECTOR U = V;
    U.n128_f32[i] = f;
    return U;
#elif defined(_XM_SSE_INTRINSICS_)
    XMVECTOR U = V;
    U.m128_f32[i] = f;
    return U;
#endif
}       

VS

// Sets the X component of a vector to a passed floating point value
inline XMVECTOR XM_CALLCONV XMVectorSetX(FXMVECTOR V, float x)
{
#if defined(_XM_NO_INTRINSICS_)
    XMVECTOR U;
    U.vector4_f32[0] = x;
    U.vector4_f32[1] = V.vector4_f32[1];
    U.vector4_f32[2] = V.vector4_f32[2];
    U.vector4_f32[3] = V.vector4_f32[3];
    return U;
#elif defined(_XM_ARM_NEON_INTRINSICS_)
    return vsetq_lane_f32(x,V,0);
#elif defined(_XM_SSE_INTRINSICS_)
    XMVECTOR vResult = _mm_set_ss(x);
    vResult = _mm_move_ss(V,vResult);
    return vResult;
#endif
}

查看XMVectorSetY案例以及/arch:AVX/arch:AVX2能够使用SSE4指令的_mm_insert_ps inline XMVECTOR XM_CALLCONV XMVectorSetY(FXMVECTOR V, float y) { #if defined(_XM_NO_INTRINSICS_) XMVECTOR U; U.vector4_f32[0] = V.vector4_f32[0]; U.vector4_f32[1] = y; U.vector4_f32[2] = V.vector4_f32[2]; U.vector4_f32[3] = V.vector4_f32[3]; return U; #elif defined(_XM_ARM_NEON_INTRINSICS_) return vsetq_lane_f32(y,V,1); #elif defined(_XM_SSE4_INTRINSICS_) XMVECTOR vResult = _mm_set_ss(y); vResult = _mm_insert_ps( V, vResult, 0x10 ); return vResult; #elif defined(_XM_SSE_INTRINSICS_) // Swap y and x XMVECTOR vResult = XM_PERMUTE_PS(V,_MM_SHUFFLE(3,2,0,1)); // Convert input to vector XMVECTOR vTemp = _mm_set_ss(y); // Replace the x component vResult = _mm_move_ss(vResult,vTemp); // Swap y and x again vResult = XM_PERMUTE_PS(vResult,_MM_SHUFFLE(3,2,0,1)); return vResult; #endif } 否则它必须做一些相当的工作才能获得SIMD代码而不必泄漏到内存中。

<action android:name="android.intent.action.QUICKBOOT_POWERON" />
  

请注意,DirectXMath现在可在GitHub上使用。