找回密码
 欢迎注册
楼主: 无心人

[讨论] 二进制32位整数快速平方根

[复制链接]
 楼主| 发表于 2009-2-18 11:53:15 | 显示全部楼层
  1. __declspec(naked)
  2. DWORD __fastcall iSqrt_FPU1_yaos(DWORD n)
  3. {
  4. __asm
  5. {
  6. push ecx
  7. sub esp, 4
  8. mov word ptr [esp], 0x0E60
  9. fnstcw word ptr [esp + 2]
  10. fldcw word ptr [esp] //提前设定截断加64位
  11. xor eax, eax
  12. shld eax, ecx, 1 //修改
  13. fld qword ptr [b32 + eax * 8]
  14. fild dword ptr [esp + 4]
  15. faddp st(1), st
  16. fsqrt
  17. fistp dword ptr [esp + 4]
  18. fldcw word ptr [esp + 2]
  19. mov eax, [esp + 4]
  20. add esp, 8
  21. ret
  22. }
  23. }
复制代码
继续优化, 通过测试 重大改进,执行时间在Core2上有大幅度减少 减少44% !!!!! =========================== 呵呵, 明白问题在哪里了 是使用了32位精度浮点了 ========================== 马上进行全数字检测!!!! 不行!!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-18 15:18:14 | 显示全部楼层
考虑楼上的低精度平方根后的一次纠正是否合算 在计算是否比正确值最多少1
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-18 15:44:22 | 显示全部楼层
目前看,仅2^32-1不行 其他都可计算出正确值
  1. __declspec(naked)
  2. DWORD __fastcall iSqrt_FPU4(DWORD n)
  3. {
  4. __asm
  5. {
  6. push ecx
  7. sub esp, 4
  8. mov word ptr [esp], 0x0C60
  9. fnstcw word ptr [esp + 2]
  10. fldcw word ptr [esp]
  11. mov eax, ecx
  12. shr eax, 31
  13. fld qword ptr [b32 + eax * 8]
  14. fild dword ptr [esp + 4]
  15. faddp st(1), st
  16. fsqrt
  17. fistp dword ptr [esp + 4]
  18. fldcw word ptr [esp + 2]
  19. mov eax, [esp + 4]
  20. add eax, 1
  21. mul eax
  22. mov edx, eax
  23. xor eax, eax
  24. cmp edx, ecx
  25. setbe al
  26. add eax, [esp + 4]
  27. add esp, 8
  28. ret
  29. }
  30. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-18 15:55:48 | 显示全部楼层
  1. __declspec(naked)
  2. DWORD __fastcall iSqrt_FPU4(DWORD n)
  3. {
  4. __asm
  5. {
  6. push ecx
  7. sub esp, 4
  8. mov word ptr [esp], 0x0C60 //单精度截断方式
  9. fnstcw word ptr [esp + 2]
  10. fldcw word ptr [esp]
  11. mov eax, ecx
  12. shr eax, 31
  13. fld qword ptr [b32 + eax * 8]
  14. fild dword ptr [esp + 4]
  15. faddp st(1), st
  16. fsqrt
  17. fistp dword ptr [esp + 4]
  18. fldcw word ptr [esp + 2]
  19. mov eax, [esp + 4]
  20. add eax, 1
  21. mul eax
  22. mov edx, eax
  23. xor eax, eax
  24. cmp edx, ecx
  25. setbe al
  26. add eax, [esp + 4]
  27. add esp, 8
  28. mov edx, eax
  29. shr edx, 16 //测试是否大于等于65536
  30. sub eax, edx //纠正2^32-1时计算错误
  31. ret
  32. }
  33. }
复制代码
这样就正常了 两位测试下,这个函数在你们机器的执行时间
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-18 16:04:40 | 显示全部楼层
FPU Version: 3609.623 ms FPU1 Version: 3606.396 ms FPU2 Version: 3593.823 ms FPU4 Version: 2623.458 ms 在我机器上是非常快的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-18 16:12:46 | 显示全部楼层
在我的 AMD 3200+ CPU 上, 测试 n: 0-2^28 56# 需要 5s / 124# 需要 23s 看来 iSqrt_FPU4 对 CPU 比较挑
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-18 16:28:10 | 显示全部楼层
如果能去掉那个乘法就好了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-18 16:34:36 | 显示全部楼层
可以考虑单精度下的浮点纠正 加或者减一个小数 不过, 具体如何做,在尝试
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-18 16:51:59 | 显示全部楼层

回复 125# 无心人 的帖子

PIV 2.6 测试结果 n: 0-0x10000 iSqt_ref#: 0.00306 s iSqt_c1_lbc#: 0.00137 s iSqt_c2_lbc#: 0.00151 s iSqt_FPU1_lbc#: 0.00095 s iSqt_FPU2_lbc#: 0.00189 s iSqt_FPU3_lbc#: 0.00127 s iSqt_FPU_yaos#: 0.00230 s iSqt_FPU1_yaos#: 0.00220 s iSqt_FPU2_yaos#: 0.00255 s iSqt_FPU4_124#: 0.00843 s (124楼函数) iSqt_gxq_c#: 0.00176 s iSqt_GxQ_asm#: 0.00448 s iSqt_gxq_90#: 0.00434 s iSqt_16#: 0.00384 s n: 0-0x10000000 iSqt_ref#: 13.66799 s iSqt_c1_lbc#: 9.00341 s iSqt_c2_lbc#: 11.29242 s iSqt_FPU1_lbc#: 4.39066 s iSqt_FPU2_lbc#: 8.79425 s iSqt_FPU3_lbc#: 6.42752 s iSqt_FPU_yaos#: 10.13491 s iSqt_FPU1_yaos#: 9.89024 s iSqt_FPU2_yaos#: 10.96591 s iSqt_FPU4_124#: 37.71079 s (124楼函数) iSqt_gxq_c#: 8.64673 s iSqt_GxQ_asm#: 20.26102 s iSqt_gxq_90#: 19.40886 s iSqt_16#: 16.53817 s 测试结果表明:在PIV上运行,124楼的版本出奇的慢,运行时间是 iSqt_FPU1_lbc 的8倍多,看来确实如gxq如言,这个版本很挑CPU
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-18 16:55:51 | 显示全部楼层
宝宝 考虑下128#的建议 不过,我想这个理论上容易 实际上很不好处理
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 00:20 , Processed in 0.024448 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表