首页
社区
课程
招聘
[分享]Patch msvcrt.dll/ntdll.dll 提升系统浮点性能
发表于: 2009-10-5 10:33 7464

[分享]Patch msvcrt.dll/ntdll.dll 提升系统浮点性能

2009-10-5 10:33
7464

最近认真看了一下Intel的算术库,对其中的SSE2的运用印象深刻.
然后猛然想到 windows 2003在使用FPU87呢,还是SSE2呢?
经过调试,很遗憾,系统使用的是传统的FPU87的指令集,这实在是浪费CPU的能量啊.
于是操起OllyDbg,打开msvcrt.dll,ntdll.dll改写了一些代码.
1._ftol: VC7.1之前编译的函数按默认设置都会调用此函数进行浮点转整形,对于脚本引擎等涉及频繁浮点整形转化的程序很有意义
改写如下:
cvttsd2si eax, [esp+arg_0]
retn
2.fabs: VC未开启内联,或低于VC7.1时被调用,用于abs~
改写如下:
fld     qword ptr [esp+4]
fabs
retn
3.
其他浮点函数atan/ceil/exp/floor/log/log10/modf/pow
这些在msvcrt.dll是有开关函数的 _set_SSE2_enable,虽然MSDN说如果CPU支持会自动开启,但是其实是如果CPU支持将允许你启用,不等于自动开启
代码片段:
  77BE1499      8325 845DBF77 00         and     dword ptr [77BF5D84], 0
  77BE14A0      8325 805DBF77 00         and     dword ptr [77BF5D80], 0  // 直接都改成 or 1
  77BE14A7  |.  F645 EB 04               test    byte ptr [ebp-15], 4
  77BE14AB  |.  74 13                    je      short msvcrt.77BE14C0
  77BE14AD  |.  E8 4EFFFFFF              call    msvcrt.77BE1400  //进行无效指令计算
  77BE14B2  |.  85C0                     test    eax, eax
  77BE14B4  |.  74 0A                    je      short msvcrt.77BE14C0
  77BE14B6  |.  C705 845DBF77 01000000   mov     dword ptr [77BF5D84], 1 // 如果支持 77BF5D84 设为1,但是却没有把77BF5D80设为1
  77BE14C0  |>  8B4D FC                  mov     ecx, dword ptr [ebp-4]

OK,这就好办了
or    dword ptr [77BF5D80], 1
这样就强制开启了.
对于ntdll.dll,大部分函数没有SSE2的代码,只有ceil,floor,直接去掉头部的jmp即可.

额外的:
vcpkg5.5自带了这个patch,当VC6IDE加载vcpkg时自动patch msvcrt.dll,提升VC6的浮点性能.显然,内存patch仅作用于当前进程,对系统其他进程没有帮助,推荐patch系统文件,这样所有系统中运行的软件都会受益.

对于开发人员:
如果你在用 VC6或可能会调用msvcrt.dll中的浮点运算函数(就算你不调用,系统自身dll也会调用,因为它是 NT CRT DLL),那么显然我们不能去Patch用户计算机中的文件,启动时执行以下代码,有益于提高速度.
调用永远是安全的,因为这个函数会将设置与屏蔽位取与,所以,只有在SSE2指令集的计算机中在最终生效.
        typedef int (_cdecl *PFN_set_SSE2_enable)(int flag);
        PFN_set_SSE2_enable pfn_set_SSE2_enable;
        pfn_set_SSE2_enable=(PFN_set_SSE2_enable)GetProcAddress(GetModuleHandle(_T("msvcrt.dll")),"_set_SSE2_enable");
        if (pfn_set_SSE2_enable) pfn_set_SSE2_enable(1);

注意:
1.如果你要跟随这个修改,务必保证你的CPU支持SSE2指令集,否则,.....
2.关掉系统的SFC,否则,会被自动还原
3.ntdll.dll,这类系统dll的修改,记得替换前更新CheckSum,这是好习惯


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
2
不懂浮点 膜拜
2009-10-5 12:12
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
3
楼上的都来膜拜了

膜拜
2009-10-5 12:14
0
雪    币: 88
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
膜拜一下。。。。楼主真有耐心
2009-10-5 16:24
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我看这些操作SSE和x87 FP指令的性能应该差不多,SSEx的优势是SIMD,如果是一个数组需要ftol,的确是SSEx的指令快
2009-10-5 17:01
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
更正一下:

_ftol 的修正是错误的,原型是 __int64 _ftol(double x),我错当作 int _ftol(double x)
对于返回 __int64 的话,msvcrt.dll自带的代码就差不多了,无多大的改进必要
2009-10-5 17:29
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
第三点比较有意义
你看一下 atan/ceil/exp/floor/log/log10/modf/pow 的asm源代码,就会明白了,为什么它们用 SSE/SSE2 要更快.
2009-10-5 17:30
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
强淫!膜拜 !
2009-10-10 01:06
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
lz应该做个对比,同样的测试环境,path前后直观的让我等看看,膜拜下
2009-10-10 15:33
0
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
10
要看应用场合,如果你的程序有这样的性能需求,就不要去调用msvcrt.dll/ntdll.dll里的函数
普通程序没必要去为了一点点的性能提升去patch系统文件
2009-10-10 15:50
0
雪    币: 7309
活跃值: (3788)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
11
不支持SSE的CPU,被你改完后就不能用win2003了
要玩高速浮点运算,可以去玩玩CUDA
2009-10-10 16:13
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
高版本的VC有很多SSE方面的intrinsic,最适合不喜欢asm的TX了
intel,amd都有高性能运算库,我都下了,就是没看过
GPU的优势貌似也是并行能力,而且是比SSE高得多的并行度
2009-10-10 16:52
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
13
不要去patch,不要去调用,要自己编写浮点支持函数库
2009-10-10 22:43
0
游客
登录 | 注册 方可回帖
返回
//