DirectX 12 持续整理 ——1. 向量

跳过线性代数的数学概念部分。
绝大部分内容来自于《Introduction to 3D Game Programming with DirectX12 Frank D. Luna》


1.编译环境

  在Windows 8以及更高版本的操作系统中,DirectX Math 是一个用于 Direct3D 的 3D 数学库,它已经是Windows SDK的一部分了,并且使用了 SSE2 指令集。

SSE2是什么?
http://share.onlinesjtu.com/mod/tab/view.php?id=303


单指令流多数据流(SIMD)是一种实现数据级并行的技术,其典型代表是向量处理器(Vector Processor)和阵列处理器(Array Processor)。

SIMD技术最初主要应用在大规模的超级计算机中,但是近些年来,小规模SIMD技术也开始在个人计算机上得到广泛应用。

SIMD技术的关键是在1条单独的指令中同时执行多个运算操作,以增加处理器的吞吐量。为此,SIMD结构的CPU有多个执行部件,但都在同一个指令部件的控制之下,中央控制器向各个处理单元发送指令,整个系统只要求有一个中央控制器,只要求存储一份程序,所有的计算都是同步的。

为了了解SIMD在性能上的优势,我们以加法指令为例进行说明:

单指令流单数据流(SISD)型CPU对加法指令译码后,执行部件先访问主存,取得第一个操作数,之后再一次访问主存,取得第二个操作数,随后才能进行求和运算;而在SIMD型CPU中,指令译码后,几个执行部件同时访问主存,一次性获得所有操作数进行运算。

这一特点使得SIMD技术特别适合于多媒体应用等数据密集型运算。

1.MMX技术

MMX(Multi-Media
Extension,多媒体扩展)是Intel设计的一种SIMD多媒体指令集。作为一种多媒体扩展技术,MMX大大提高了计算机在多媒体和通信应用方面的能力,带有MMX技术的CPU适合于数据量很大的图形、图像数据处理,从而使三维图形、动画、视频、音乐合成、语音识别、虚拟现实等数据处理的速度有了很大提高。

MMX技术的优点是增加了多媒体处理能力,可以一次处理多个数据,缺点则是仅仅只能处理整型数,并且由于占用浮点数寄存器进行运算,以至于MMX指令集与x87浮点运算指令不能够同时执行,必须做密集的切换才可以正常执行,这种情况势必造成整个系统运行质量的下降。

2.SSE技术

1999年,Intel在其Pentium III微处理器中集成了SSE(Streaming SIMD
Extensions)技术,有效增强了CPU浮点运算的能力。

SSE兼容MMX指令,可以通过SIMD和单时钟周期并行处理多个浮点数据来有效提高浮点运算速度,对图像处理、浮点运算、3D运算、视频处理、音频处理等诸多多媒体应用起到全面强化作用。

具有SSE指令集支持的处理器有8个128位的寄存器,每一个寄存器可以存放4个单精度(32位)浮点数。SSE同时提供了一个指令集,其中的指令允许把浮点数加载到这些128位寄存器中,这些数就可以在这些寄存器中进行算术逻辑运算,然后把结果送回主存。也就是说,SSE中的所有计算都可以针对4个浮点数一次性完成,这种批处理带来了效率的提升。

例如,考虑下面这个任务:计算一个很长的浮点型数组中每一个元素的平方根。

实现这个任务的算法一般可以写为:

for each f in array

{

把f从主存加载到浮点寄存器

计算平方根

再把计算结果从寄存器中取出写入主存

}

而在采用SSE技术后,算法可以改写为:

for each 4 members in array //对数组中的每4个元素

{

把数组中的这4个数加载到一个128位的SSE寄存器中

在一个CPU指令执行周期中完成计算这4个数的平方根的操作

把所得的4个结果取出写入主存

}

3.SSE2技术

2001年,Intel配合其Pentium 4微处理器,推出了SSE2(Streaming SIMD Extensions
2)指令集,扩展了SSE指令集,并可完全取代MMX。

SSE2指令集是Intel公司在SSE指令集的基础上发展起来的。相比于SSE,SSE2使用了144个新增指令,扩展了MMX技术和SSE技术,提高了诸如MPEG-2、MP3、3D图形等应用程序的运行性能。

在整数处理方面,随MMX技术引进的SIMD整数指令从64位扩展到了128
位,使SIMD整数类型操作的执行效率成倍提高;在浮点数处理方面,双精度浮点SIMD指令允许以
SIMD格式同时执行两个浮点操作,提供双精度操作支持有助于加速内容创建、财务、工程和科学应用。除SSE2指令之外,最初的SSE指令也得到增强,通过支持多种数据类型(例如双字、四字)的算术运算,支持灵活、动态范围更广的计算功能。

4.SSE3技术

2004年,Intel在其基于Prescott核心的新款Pentium 4处理器中,开始使用SSE3(Streaming SIMD
Extensions 3)技术。

SSE3指令集是Intel公司在SSE2指令集的基础上发展起来的。相比于SSE2,SSE3在SSE2的基础上又增加了13条SIMD指令,以提升Intel超线程(Hyper-Threading)技术的效能,最终达到提升多媒体和游戏性能的目的。


  为了能够使用 DirectX Math 类库,需要包含头文件:

 #include <DirectXMath.h>

  对于一些其它的数据类型,还需要类似于下面的头文件:

#include <DirectXPackedVector.h>

  前者位于DirectX命名空间中;后者位于DirectX::PackedVector命名空间中。

  另外说一句,x64的CPU是默认支持SSE2的,而x86平台下,需要对项目额外的设置来使能SSE2:

Project Properties > Configuration Properties > C/C++ > Code Generation > Enable Enhanced Instruction Set

  在所有平台下,需要以下设置来启动快速浮点模型:

Project Properties > Configuration Properties > C/C++ > Code Generation > Floating Point Model > /fp:fast

2.向量类型


2.1 XMVECTOR & XMFLOATn

  在DirectX Math中,向量的核心类型是 XMVECTOR,此类型与SIMD硬件寄存器直接映射。它是一个128位的数据类型,能够在一个SIMD指令下处理4个32位的浮点数。
  如果SSE2处于使能状态,XMVECTOR 类型一般被定义成下面这个样子:

typedef __m128 XMVECTOR;

我们来看看这个__m128到底是什么?

typedef union __declspec(intrin_type) _CRT_ALIGN(16) __m128 {
     float               m128_f32[4];
     unsigned __int64    m128_u64[2];
     __int8              m128_i8[16];
     __int16             m128_i16[8];
     __int32             m128_i32[4];
     __int64             m128_i64[2];
     unsigned __int8     m128_u8[16];
     unsigned __int16    m128_u16[8];
     unsigned __int32    m128_u32[4];
 } __m128;

  一个联合类型,里面装了一堆数组,并且按照 16 Byte(=16x4x2 =128bit) 对齐。换句话说,XMVECTOR是一个能够装4个32位数的数组,可以使用它的2个,3个或者4个32位,不使用的尽管忽略掉。
  但是,XMVECTOR与寄存器向映射,利于运算并不善于存储,所以,应该使用其它类型来用于存储数据。
  来看看XMFLOATn的定义:

struct XMFLOAT2
{
    float x;
    float y;
    XMFLOAT2() {}
    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; 
    }
};

struct XMFLOAT3
{
    float x;
    float y;
    float z;
    XMFLOAT3() {}
    XMFLOAT3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
    explicit XMFLOAT3(_In_reads_(3) const float *pArray) : x(pArray[0]), y(pArray[
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值