A Simple Wrapper of DirectX Math

A Simple Wrapper of DirectX Math

关于DirectX Math
DirectX Math最初叫做XNA Math,是一个跨平台的C++数学库,全SIMD指令优化,目前的版本是3.03,支持x86,x64和arm平台,用于代替DX 9/10中的数学库。

为什么使用DirectX Math
如果你有足够的时间,精力和知识,并且坚定的认为自己写的数学库才是最好,那么可以忽略此文:)。根据gamasutra技术控做的细介,基本上很难再比DXM的实现好了,并且它是完全跨平台的,只包含.h和.inl文件,就算是OpenGL程序也可以用,最后,DXM非常全面,实现了大部分常见的3D计算,甚至还包括了一个简单的碰撞检测库。

 正确使用DXM
        首先,用 #define _XM_NO_INTRINSICS_ 宏可以取消SIMD加速,生成普通指令,除非希望兼容非常,非常老的CPU,否则不应该使用该宏。虽然DXM对SIMD指令做了封装,你还是需要了解一点相关知识(请仔细阅读DXM文档)。DXM定义了大量常见的数据类型,但只为XMVECTOR 和XMMATRIX定义了各种数学操作。DXM所有的计算都基于XMVECTOR 和XMMATRIX。对x86平台,XMVECTOR的定义如下:
typedef __m128 XMVECTOR;

         而XMMATRIX则是一组(4个) XMVECTOR。由于__m128在内存中需要严格的16 byte对齐,因此并不建议直接在程序中使用这两种类型保存数据,比如

Class Camera
{
      XMVECTOR position;
      XMMATRIX viewMatrix;
}

         上面的代码基本上不会成功运行,32位下new并不保证16byte对齐,而且由于类成员布局的关系,其中的XMVECTOR也不一定是16byte对齐,访问以上数据,程序可能直接崩溃。因此,DXM定义了大量用来储存数据的类型,比如XMFLOAT4,XMFLOAT3,XMFLOAT4X4等:

Class Camera
{
    XMFLOAT3 position;
    XMFLOAT4X4 viewMatrix;
}

         这些类型大部分只是float数组而已,因此不用考虑对齐问题,在需要计算时,再把他们转换为于XMVECTOR 或者XMMATRIX,比如:

XMFLOAT3 position;
XMVECTOR myVector = XMLoadFloat3(position)   //load to mmx register
//perform calculate with SIMD …..
//
XMStoreFloat4(&position,myVector);           //save to memory

         显然,这种load/store模式确实很麻烦,简单计算两个向量的和也需要编写4,5行代码,于是DX开发组的程序写了一个名为SimpleMath的简单wrapper包含在DirectX Tool Kit中,为普通类型添加计算功能。然而,SimpleMath只是简单的包装了load,store而已:

struct Vector2 : public XMFLOAT2
{
    //......other member function
    float Dot( const Vector2& V ) const
    float LengthSquared() const;
    //…..other member function
}


inline float Vector2::Dot( const Vector2& V ) const
{
    using namespace DirectX;
    XMVECTOR v1 = XMLoadFloat2( this );
    XMVECTOR v2 = XMLoadFloat2( &V );
    XMVECTOR X = XMVector2Dot( v1, v2 );
    return XMVectorGetX( X );
}
 

         这样的实现对于Float4来说也许有意义,但对于Float2来说就太笨重了,把2个Float2复制到mmx寄存器相加以后再保存到普通内存位置也许比直接用非SIMD指令相加还慢!此外对于SIMD计算来说,应该尽量减少load和unload,尽量把数据保存在寄存器中,比如在计算前把数据load为XMVECTOR,执行完一系列计算,最后再保存到普通位置,而不是每执行一次计算,就load/store一次

case 1:
Load to XMVECTOR
perform calc 1
perform calc 1
..
Perform calc n
Store to Float4

 
case 2
Load to XMVECTOR
Perform calc 1
Store to Float4
Load to XMVECTOR
Perform calc 2
Store to Float4
…

两种不同写法,如果编译器没有特别优化的情况下,效率相差会很明显。因此,好的数学库还要有正确的使用方法,才会得到最好的性能。

 

FlameMath
         FlameMath保留了SimpleMath的接口,但改进了一部分性能问题,替换了部分函数的实现,对于简单类型和轻量级计算,直接用普通指令,对于matrix等复杂计算,再使用SIMD。

inline float Float2::Dot( const Float2& V ) const
{
   return (x * V.x + y * V.y);
}

       但是,FlameMath仍然不能避免不同计算间反复load/store的问题。因此,最佳方案应该是使用Float3,Float4等类型保存数据,对于轻量级简单计算,直接用FloatX的成员函数进行,对于需要连续进行的复杂计算,则应该把数据load为XMVECTOR等类型,直接用DXM函数计算,最后再store到FloatX中。FloatMath中的FloatX对应DXM和SimpleMath中的标量数据类型,Vector4和Matrix4x4则相当于XMVECTOR 和XMMATRIX。所有DXM中的函数以SimdMath类静态函数的方式提供。

Simpe Usage:
Float2 v1;
Float2 v2;
Float2 result = v1 + v2;
//done

 
Advance usage
Float2 f1;
Float2 f2;
Vector4 v1 = SimdMath.LoadFloat2(f1);
Vector4 v2 = SimdMath.LoadFloat2(f2);
Vector4 v3 = SimdMath. Vector2Normalize (v1);
Vector4 v4 = SimdMath. Vector2Normalize (v2);
Vector4 v5 = SimdMath. Vector2AngleBetweenNormals(v3,v4);
Float result;
SimdMath. StoreFloat(&result,v5);
//done

 

ps:FlameMath所有代码都未经测试,使用时只需要包含FlameMath.h即可:)
http://files.cnblogs.com/clayman/FlameMath.rar

转载于:https://www.cnblogs.com/clayman/archive/2013/05/01/3053196.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你需要使用 Python 的 requests 库来发送 HTTP 请求并获取响应。具体步骤如下: 1.导入 requests 库: ```python import requests ``` 2.发送 GET 请求获取数据: ```python url = "https://fe-api.zhaopin.com/c/i/search/positions?MmEwMD=5C7h83EGgopRDqbqNm.je7mATkDTi5sJQTLlO5s2uukKlPbSHjy0Rk0bPfO7Yuve9.LB76I1mR.l33wK8wVYlfDYS7_o68chaKdR9Cbp0D7dRUIUWwHELnzgnagLP55DxM2I86kXPWbf.p.uBTsdzF_Lu0UpwPEDA8J1yJQyFjdhEHyATM2B8byol0zScluX1asenO.LPd_J1sB7LLOE9OJiLhQBxDQ4Fv1kuB4BHezD1SpEiShG3xyB4V4GdrP6uodc9n20c.HJlVRqnvaq8Tqa28Fg2RbhQv40_9EnbVev8HjGkQadM377iMZgjHKeHt8HNEMKGe8VWAm8PAm5INuKdhI8uR45iR3plUCwNBvZCuW8spm0hQscCw_dsE46C&c1K5tw0w6_=4Xze.jSPtZLoaxePOtvOffVeT5iDtnxQSUXF.VmPH6H1aBPf45Ht4Mpy90iIFckuqmWjGirB2jKuu6LN9cwS.bpxZPUffGk18dqPfg.On0tYfW.GNbnWVWp8B6_l73ImocVmT8kqz3U0QoW3pPqVqsdd30lwgJph5XQOMkqQeKkEx0Hzr6I4A738._aEEp2vdlAjr7KGImYm6R2f8cub9XXiHBQkqsY.K9KQerQgFifvkOAEi7.8IMVpLWwXOb42RndYOPqoD2UXmMYQYHJD07PFksAXQ0l2DjYZYApTNMHK0WbXuodd4AeKAmH8aQE5sKp5wKjuo2hmb4OnwtlNdbAc0mR.QE298ol8E7oysfAQmdgHIb6_L0u7oj9LE5bAHeJJIjKhdjPy12Tm9spDB_IAr198a2BEo7XAqCdz_vdbmxBoTkJdfpAK6EcDm_KlI1Jz3eHlV8EbE67Sta3tb4q" response = requests.get(url) ``` 3.获取响应数据: ```python data = response.json() ``` 这样你就可以将获取到的数据保存到一个变量中,接下来你可以对数据进行处理或者保存到文件中。请注意,在实际使用中,你可能需要添加一些请求头信息或者使用代理来发送请求,以避免被服务器识别为爬虫并被拒绝访问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值