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

[讨论] 二进制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-5-7 23:32 , Processed in 0.069957 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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