D3DX Math (1): CPU Optimization
来源:互联网 发布:java天气预报接口api 编辑:程序博客网 时间:2024/06/10 01:16
对D3DX的数学函数比较好奇,所以用windbg一探究竟。
先从一个简单的D3DX导出函数D3DXVec4Cross开始吧。
0:000> u d3dx10_42!D3DXVec4Cross
d3dx10_42!D3DXVec4Cross:
697b0276 ff2554637f69 jmp dword ptr [d3dx10_42!g_D3DXFastTable+0x44 (697f6354)]
697b027c cc int 3
697b027d cc int 3
697b027e cc int 3
697b027f cc int 3
697b0280 cc int 3
这个函数通过函数表g_D3DXFastTable的0x44项跳转到了真正的初始化代码。
0:000> dd d3dx10_42!g_D3DXFastTable+0x44
697f6354 697b025e 697afaaa 697b0eaf 697b24a5
697f6364 697b2565 697b2b0d 697b2be4 697b20e8
697f6374 697b214e 697b2389 697b1362 697b20a2
697f6384 697b20c5 697b22f3 697b13ef 697b148f
697f6394 697b1531 697b12d5 697b2e10 697b27f1
697f63a4 697b2a37 697b0b92 697b1714 697b1878
697f63b4 697b1838 697b18de 697b15d1 697b2970
697f63c4 697b2588 697b2a14 697afa87 697afb9a
0:000> u 697b025e
d3dx10_42!init_D3DXVec4Cross:
697b025e 8bff mov edi,edi
697b0260 55 push ebp
697b0261 8bec mov ebp,esp
697b0263 6a01 push 1 ;TRUE, 开启CPU优化
697b0265 e8b9520000 call d3dx10_42!D3DXCpuOptimizations (697b5523)
697b026a 5d pop ebp
697b026b ff2554637f69 jmp dword ptr [d3dx10_42!g_D3DXFastTable+0x44 (697f6354)]
697b0271 cc int 3
查MSDN可以知道,D3DXCpuOptimizations的作用是开启或者关闭CPU的浮点计算优化。
D3DXCpuOptimizations
Enables or disables CPU optimizations.
D3DX_CPU_OPTIMIZATION D3DXCpuOptimizations( BOOL Enable);
Parameters
- Enable
- [in] TRUE to enable CPU optimizations; otherwise FALSE.
Return Values
Returns the type of CPU detected, and for which optimizations exist (see D3DX_CPU_OPTIMIZATION).
init_D3DXVec4Cross在调用完这个函数以后,又跳转回函数表g_D3DXFastTable+0x44项。此时这个值已经不再是init_D3DXVec4Cross的地址了,具体是什么值,根据CPU决定。现在我们先看看D3DXCpuOptimizations的代码。
0:000> u d3dx10_42!D3DXCpuOptimizations L50
d3dx10_42!D3DXCpuOptimizations:
697b5523 8bff mov edi,edi
697b5525 55 push ebp
697b5526 8bec mov ebp,esp
697b5528 51 push ecx
697b5529 56 push esi
697b552a 57 push edi
697b552b e8c8b40300 call d3dx10_42!D3DX10Debug::D3DX10CheckNewDelete (697f09f8) ;d3dx DLL使用了C++的new&delete操作符,这个函数检查内存分配行为是否符合C++标准,我们可以无视
697b5530 837d0800 cmp dword ptr [ebp+8],0 ;参数是否为0?
697b5534 751e jne d3dx10_42!D3DXCpuOptimizations+0x31 (697b5554)
697b5536 c70564657f69ffff0000 mov dword ptr [d3dx10_42!g_CpuOptimization (697f6564)],0FFFFh ;设置全局变量g_CpuOptimization为-1,表示优化暂时关闭
697b5540 6a4a push 4Ah
697b5542 59 pop ecx
697b5543 be38647f69 mov esi,offset d3dx10_42!g_D3DXFastTableC (697f6438) ;未优化函数表
697b5548 bf10637f69 mov edi,offset d3dx10_42!g_D3DXFastTable (697f6310)
697b554d f3a5 rep movs dword ptr es:[edi],dword ptr [esi] ;拷贝未优化的函数表
697b554f e9bc000000 jmp d3dx10_42!D3DXCpuOptimizations+0xed (697b5610) ;返回
697b5554 813d64657f69ffff0000 cmp dword ptr [d3dx10_42!g_CpuOptimization (697f6564)],0FFFFh ;优化是否已经开启?
697b555e 0f85ac000000 jne d3dx10_42!D3DXCpuOptimizations+0xed (697b5610) ;返回
697b5564 832564657f6900 and dword ptr [d3dx10_42!g_CpuOptimization (697f6564)],0
697b556b 6a4a push 4Ah
697b556d 59 pop ecx
697b556e be38647f69 mov esi,offset d3dx10_42!g_D3DXFastTableC (697f6438)
697b5573 bf10637f69 mov edi,offset d3dx10_42!g_D3DXFastTable (697f6310)
697b5578 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] ;拷贝未优化的函数表,回到初始状态
697b557a 6810637f69 push offset d3dx10_42!g_D3DXFastTable (697f6310)
697b557f e8c4fc0000 call d3dx10_42!x86_D3DXInitFastTable (697c5248) ;针对x86CPU的优化,即使只使用x87 FPU,还是有几个重要的函数用手动汇编代码提高效率,如D3DXMatrixMultiply和D3DXVec3Transform
697b5584 6a04 push 4
697b5586 8d45fc lea eax,[ebp-4]
697b5589 50 push eax
697b558a 6834427969 push offset d3dx10_42!`string' (69794234) ;”DisableD3DX10PSGP”
697b558f 6a04 push 4
697b5591 e829feffff call d3dx10_42!c_D3DXQuaternionSquadSetup+0x499 (697b53bf) ;这个函数符号有错,功能主要是查注册表Software/Microsoft/Direct3D下当前exe文件的键的DisableD3DX10PSGP的值,PSGP表示Processor Specific Geometry Pipeline。这个键值也是一个开关,决定这个exe文件执行的时候DirectX 10是否开启CPU的SIMD指令集,具体逆向代码就不分析了。
697b5596 85c0 test eax,eax ;非0表示键值存在
697b5598 7504 jne d3dx10_42!D3DXCpuOptimizations+0x7b (697b559e)
697b559a 8365fc00 and dword ptr [ebp-4],0
697b559e 837dfc00 cmp dword ptr [ebp-4],0
697b55a2 7402 je d3dx10_42!D3DXCpuOptimizations+0x83 (697b55a6)
697b55a4 eb6a jmp d3dx10_42!D3DXCpuOptimizations+0xed (697b5610) ;返回
697b55a6 837dfc02 cmp dword ptr [ebp-4],2
697b55aa 7422 je d3dx10_42!D3DXCpuOptimizations+0xab (697b55ce)
697b55ac 6a07 push 7 ;PF_3DNOW_INSTRUCTIONS_AVAILABLE=7, IsProcessorFeaturePresent的参数
697b55ae e839ffffff call d3dx10_42!c_D3DXQuaternionSquadSetup+0x5c6 (697b54ec) ;符号又有错。此函数调用IsProcessorFeaturePresent API来判断指令集是否存在
697b55b3 85c0 test eax,eax
697b55b5 7417 je d3dx10_42!D3DXCpuOptimizations+0xab (697b55ce)
697b55b7 6810637f69 push offset d3dx10_42!g_D3DXFastTable (697f6310)
697b55bc e8c5c60200 call d3dx10_42!amd_D3DXInitFastTable (697e1c86) ;使用3D Now指令集优化
697b55c1 59 pop ecx
697b55c2 c70564657f6901000000 mov dword ptr [d3dx10_42!g_CpuOptimization (697f6564)],1
697b55cc eb42 jmp d3dx10_42!D3DXCpuOptimizations+0xed (697b5610) ;返回
697b55ce 6a0a push 0Ah ;PF_XMMI64_INSTRUCTIONS_AVAILABLE=10
697b55d0 e817ffffff call d3dx10_42!c_D3DXQuaternionSquadSetup+0x5c6 (697b54ec)
697b55d5 85c0 test eax,eax
697b55d7 7417 je d3dx10_42!D3DXCpuOptimizations+0xcd (697b55f0)
697b55d9 6810637f69 push offset d3dx10_42!g_D3DXFastTable (697f6310)
697b55de e8e77c0300 call d3dx10_42!intelsse2_D3DXInitFastTable (697ed2ca) ;使用SSE2指令集优化
697b55e3 59 pop ecx
697b55e4 c70564657f6902000000 mov dword ptr [d3dx10_42!g_CpuOptimization (697f6564)],2
697b55ee eb20 jmp d3dx10_42!D3DXCpuOptimizations+0xed (697b5610)
697b55f0 6a06 push 6 ;PF_XMMI_INSTRUCTIONS_AVAILABLE=6
697b55f2 e8f5feffff call d3dx10_42!c_D3DXQuaternionSquadSetup+0x5c6 (697b54ec)
697b55f7 85c0 test eax,eax
697b55f9 7415 je d3dx10_42!D3DXCpuOptimizations+0xed (697b5610)
697b55fb 6810637f69 push offset d3dx10_42!g_D3DXFastTable (697f6310)
697b5600 e858540300 call d3dx10_42!intelsse_D3DXInitFastTable (697eaa5d) ;使用SSE指令集优化
697b5605 59 pop ecx
697b5606 c70564657f6903000000 mov dword ptr [d3dx10_42!g_CpuOptimization (697f6564)],3
697b5610 a164657f69 mov eax,dword ptr [d3dx10_42!g_CpuOptimization (697f6564)]
697b5615 5f pop edi
697b5616 5e pop esi
697b5617 c9 leave
697b5618 c20400 ret ;以下无视
697b561b cc int 3
697b561c cc int 3
697b561d cc int 3
697b561e cc int 3
697b561f cc int 3
d3dx10_42!D3DX10Math::CMatrixStack::AddRef:
697b5620 8bff mov edi,edi
697b5622 55 push ebp
697b5623 8bec mov ebp,esp
697b5625 8b4508 mov eax,dword ptr [ebp+8]
intelsse_D3DXInitFastTable intelsse2_D3DXInitFastTable amd_D3DXInitFastTable三个函数所做的事情无非就是一长串mov操作,把对应的函数地址放入函数表g_D3DXFastTable。具体代码就不再分析了。
现在再看看运行完D3DXCpuOptimizations之后,函数表g_D3DXFastTable第0x44项的值是什么:
0:000> dd d3dx10_42!g_D3DXFastTable+0x44
697f6354 697ed8ac 697eb5f1 697ed5ff 697ebd68
697f6364 697eb204 697ed558 697eb782 697b210b
697f6374 697b2171 697ede60 697b13a2 697eda66
697f6384 697edb63 697b2326 697b141f 697b14bf
697f6394 697b1561 697b1315 697eacb2 697b2827
697f63a4 697b2a78 697b0bb5 697b1737 697b4528
697f63b4 697b44e8 697b1917 697b1604 697b29ac
697f63c4 697edde5 697b4f26 697edcfb 697eb35e
0:000> u 697ed8ac
d3dx10_42!intelsse2_D3DXVec4Cross:
697ed8ac 8bff mov edi,edi
697ed8ae 53 push ebx
697ed8af 8bdc mov ebx,esp
697ed8b1 51 push ecx
697ed8b2 51 push ecx
697ed8b3 83e4f0 and esp,0FFFFFFF0h
697ed8b6 83c404 add esp,4
697ed8b9 55 push ebp
这就是在INTEL Q6600 CPU上面的运行结果:使用SSE2指令集优化。
好了,这次就写到这里,下次再分析具体的运算代码。
- D3DX Math (1): CPU Optimization
- 我的D3DX开发经验(1)
- .net runtime optimization services cpu居高不下
- optimization
- optimization
- Optimization
- optimization
- optimization
- Hotspots, FLOPS, and uOps: To-The-Metal CPU Optimization
- open source optimization in the linux base arm cpu
- 【D3DX日记】D3D与D3DX的区别
- D3DX向量函数
- D3DX向量函数
- D3DX矩阵函数
- D3DX颜色函数
- D3DX Utility library
- D3DX Concrete Types
- D3DX Helper Objects
- Qt多线程学习-用例子来理解多线程
- 新浪围脖开放平台五"string的替代品"
- USB枚举过程
- ubuntu-10.10中安装net-snmp-5.5
- poj1753 Flip Game
- D3DX Math (1): CPU Optimization
- 学习正则(一)
- Linux程序开发:QT中的多线程编程
- 学习正则(二)
- 学习正则(三)
- 设置MyEclipse编码方式
- CentOS中Cacti的安装过程
- 表变量与临时表使用注意
- swing 反射Annotation方式添加事件Listener