我们·来看·看英文版翻译
1.6 DIRECTX数学矢量
对于Windows 8及更高版本,DirectX Math是Direct3D应用程序的3D数学库,它是Windows SDK的一部分。该库使用SSE2(流式SIMD扩展2)指令集。对于128位宽的SIMD( 单指令多数据)寄存器,SIMD指令可以在一条指令的四个32位浮点数或整数值上运行。这对矢量计算非常有用;例如,如果你看看矢量加法:我们看到我们只是添加相应的组件。 通过使用SIMD,我们可以用一个SIMD指令而不是四个标量指令来完成4D矢量加法。如果我们只需要3D工作的三个坐标,我们仍然可以使用SIMD,但我们会忽略第四个坐标;同样,对于2D,我们将忽略第三个和第四个坐标。
我们对DirectX Math库的报道并不全面,我们只涵盖了本书所需的关键部分。对于所有的细节,我们推荐在线文档[DirectXMath]。对于希望了解SIMD矢量库如何得到最佳开发的读者,或许可以了解为什么DirectX
数学库做出了一些设计决定,我们推荐使用[Oliveira2010]设计快速跨平台SIMD矢量库的文章。 要使用DirectX Math库,您需要#include <DirectXMath.h>,并且对于某些其他数据类型#include <DirectXPackedVector.h>。没有额外的库文件,因为所有代码都是在头文件中内联实现的。 DirectXMath.h代码位于DirectX命名空间和DirectXPackedVector.h中
代码位于DirectX :: PackedVector命名空间中。另外,对于x86平台,您应该启用SSE2(项目属性>配置属性> C / C ++>代码生成>启用增强指令集),并且对于所有平台,您应启用快速浮点模型/ fp:fast >配置属性> C / C ++>代码生成>浮点模型)。您无需为x64平台启用SSE2,因为所有x64 CPU都支持SSE2
1.6.1矢量类型
在DirectX Math中,核心向量类型是XMVECTOR,它映射到SIMD硬件寄存器。 这是一个128位的类型,可以用一条SIMD指令处理四个32位浮点数。 当SSE2可用时,其定义如下适用于x86和x64平台:
typedef __m128 XMVECTOR;
其中__m128是一种特殊的SIMD类型。 在进行计算时,向量必须是这种类型才能利用SIMD。 如前所述,我们仍然使用这种类型的2D和3D向量来利用SIMD,但我们只是将未使用的组件清零并忽略它们.XMVECTOR需要16字节对齐,并且这对于本地和全局自动完成变量。 对于类数据成员,建议使用XMFLOAT2(2D),XMFLOAT3(3D)和XMFLOAT4(4D)。 这些结构定义如下:
struct XMFLOAT2
{
float x;
float y;
XMFLOAT2() XM_CTOR_DEFAULT
XM_CONSTEXPR XMFLOAT2(float _x, float _y) : x(_x), y(_y) {}
explicit XMFLOAT2(_In_reads_(2) const float *pArray) : x(pArray[0]), y(pArray[1]) {}
XMFLOAT2& operator= (const XMFLOAT2& Float2) { x = Float2.x; y = Float2.y; return *this; }
};
// 2D Vector; 32 bit floating point components aligned on a 16 byte boundary
__declspec(align(16)) struct XMFLOAT2A : public XMFLOAT2
{
XMFLOAT2A() XM_CTOR_DEFAULT
XM_CONSTEXPR XMFLOAT2A(float _x, float _y) : XMFLOAT2(_x, _y) {}
explicit XMFLOAT2A(_In_reads_(2) const float *pArray) : XMFLOAT2(pArray) {}
XMFLOAT2A& operator= (const XMFLOAT2A& Float2) { x = Float2.x; y = Float2.y; return *this; }
};
但是,如果我们直接使用这些类型进行计算,那么我们将不会利用SIMD。 为了使用SIMD,我们需要将这些类型的实例转换为XMVECTOR类型。 这是通过DirectX Math加载功能完成的。
相反,DirectX Math提供了用于将数据从XMVECTOR转换为上述XMFLOATn类型的存储功能。
总而言之,
1.对本地或全局变量使用XMVECTOR。
2.对类数据成员使用XMFLOAT2,XMFLOAT3和XMFLOAT4。
3.在进行计算之前,使用加载函数将XMFLOATn转换为XMVECTOR。
4.使用XMVECTOR实例进行计算。
5.使用存储功能将XMVECTOR转换为XMFLOATn。