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

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

[复制链接]
 楼主| 发表于 2009-2-11 17:43:27 | 显示全部楼层

  1. __declspec(naked)
  2. DWORD __fastcall iSqrt_SSE41(DWORD n)
  3. {
  4. __asm
  5. {
  6. mov eax, ecx
  7. and eax, 0x80000000
  8. movd xmm0, eax
  9.     psllq xmm0, 32
  10. mov eax, 0
  11. cvtsi2sd xmm1, eax
  12. movsd xmm2, qword ptr [b32]
  13. blendvpd xmm1, xmm2, xmm0
  14.     cvtsi2sd xmm0, ecx
  15. addsd xmm0, xmm1
  16. sqrtsd xmm0, xmm0
  17. cvttsd2si eax, xmm0
  18. ret
  19. }
  20. }
复制代码
SSE2的无跳转版本不如带跳转的
只好写SSE4.1的代码了
可惜,我查我服务器,只支持到SSSE3

谁可以帮测试下代码正确性?
================================
由于改进了SSE2版本
所以此版本作废
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-11 19:06:18 | 显示全部楼层

回复 18# 无心人 的帖子

fisttp 是SSE3指令,在我的VC6.0下不能通过编译,即使通过编译也不能运行。我的电脑是PIV2.6.
  以下的内容转自:http://blog.csdn.net/housisong/archive/2007/05/19/1616026.aspx

SSE3增加了一条FPU取整指令fisttp,和fistp指令功能几乎相同(我的电脑上经过测试速度也相同),但默认向0取整,和RC场设置无关,所以使用fisttp的代码就可以不管RC场了,有利于简化代码和优化性能


  在上文中,作者还是先了使用 fistp 指令的浮点转化整数的版本,无心人可否尝试一下。看看速度如何,另外,这样的版本也可以在我的PIV电脑上测试。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-11 19:20:03 | 显示全部楼层
呵呵

我没注意, 我还以为是P6以后都支持呢

另外,下午的程序写糊涂了

并没这么复杂
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-11 19:23:33 | 显示全部楼层

  1. double b32[] = {0.0, 4294967296.0};

  2. __declspec(naked)
  3. DWORD __fastcall iSqrt_SSE2(DWORD n)
  4. {
  5.         __asm
  6.         {
  7.         mov eax, ecx
  8.         and eax, 0x80000000
  9.         shr eax, 31
  10.         movsd xmm1, qword ptr [b32 + eax * 8]
  11.         cvtsi2sd xmm0, ecx
  12.         addsd xmm0, xmm1
  13.         sqrtsd xmm0, xmm0
  14.         cvttsd2si eax, xmm0
  15.         ret
  16.         }
  17. }
复制代码
这么做就能避免跳转了
至于fisttp,我想控制RC可能有点复杂, 呵呵
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-11 19:40:08 | 显示全部楼层
测试了3个版本:UintSqrt,iSqrt_FPU 和 sqrt_ref, 在我的电脑上运行2^28(从1到2&28-1)次,其速度如下

  iSqrt_FPU: 4375 ms
  UintSqrt:  8406 ms
  sqrt_ref: 16328 ms

说明:  
1. UintSqrt为我编写的使用bsr的c语言版本,略有修改
2. sqrt_ref的代码如下:
DWORD sqrt_ref(DWORD n)
{
        DWORD r=(DWORD)(sqrt(double(n)));
        return r;
}

3.iSqrt_FPU 函数修改了一条指令,将FISTTP 改为FISTP

  综上所述,
    1. 系统提供的函数最慢.
    2. iSqrt_FPU 目前是个错误的版本,将其修正,使其在PIV上正确运行,需要增加几条指令,将会使得速度变慢.
    3. 如果UintSqrt改为汇编优化,速度应可以提高,但提上的幅度应该不会太大.在2^28以内是否会超过修正后的iSqrt_FPU仍是个未知数.

另外,限于我的VC环境,你的使用 SSE2指令的版本在我的电脑上没有编译,也就没有办法测试了。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-11 19:41:12 | 显示全部楼层

  1. double b32[] = {0.0, 4294967296.0};

  2. __declspec(naked)
  3. DWORD __fastcall iSqrt_FPU_alpha(DWORD n)
  4. {
  5. __asm
  6. {
  7.    push ecx
  8.    mov eax, ecx   
  9.    and eax, 0x80000000
  10.    fld qword ptr [b32 + eax * 8]
  11.    fild dword ptr [esp]
  12.    faddp st(1), st
  13.    fsqrt
  14.    push 0
  15.    fnstcw word ptr  [esp]
  16.    mov edx, dword ptr [esp]
  17.    or dword ptr [esp], 0x0C00
  18.    fldcw word ptr [esp]
  19.    fistp dword ptr [esp + 4]
  20.    mov dword ptr [esp], edx
  21.    fldcw word ptr [esp]
  22.    add esp, 4
  23.    pop eax
  24.    ret
  25.    }
  26. }
复制代码


不用fisttp
多了9条指令
因为无法测试,特取名...FPU_alpha
明天有时间测试

不用__fastcall似乎能节约下ecx和一条指令
================================
似乎不用__fastcall也无法避免堆栈上占用两个双字
所以,还是用__fastcall
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-11 23:29:53 | 显示全部楼层
终于将C版改为汇编语言版本了,测试发现,速度仅仅提高约10%,计算2^28次平方根,用时从 7902.3ms 提高到7192.7 ms。

函数原型:
extern "C" DWORD __fastcall UintSqrt(DWORD n);

汇编源代码:

  1. .486P
  2.         .387
  3.         OPTION DOTNAME
  4. _TEXT        SEGMENT DWORD PUBLIC FLAT 'CODE'
  5.         ALIGN 004H
  6. _TEXT        ENDS

  7. _DATA        SEGMENT DWORD PUBLIC FLAT 'DATA'
  8.         ALIGN 004H
  9. _DATA        ENDS

  10. _BSS        SEGMENT DWORD PUBLIC FLAT 'BSS'
  11.         ALIGN 004H
  12. _BSS        ENDS

  13. _RDATA        SEGMENT DWORD PUBLIC FLAT 'DATA'
  14.         ALIGN 004H
  15. _RDATA        ENDS

  16. _TEXT1        SEGMENT DWORD PUBLIC FLAT 'CODE'
  17.         ALIGN 004H
  18. _TEXT1        ENDS

  19. _DATA1        SEGMENT DWORD PUBLIC FLAT 'DATA'
  20.         ALIGN 004H
  21. _DATA1        ENDS

  22.         ASSUME        CS:FLAT,DS:FLAT,SS:FLAT
  23.         
  24. _DATA        SEGMENT DWORD PUBLIC FLAT 'DATA'
  25.         ALIGN     4       
  26. _sqrtTab DB        00H
  27.         DB        01H
  28.         DB        01H
  29.         DB        01H
  30.         DB        02H
  31.         DB        02H
  32.         DB        02H
  33.         DB        02H
  34.         DB        02H
  35.         DB        03H
  36.         DB        03H
  37.         DB        03H
  38.         DB        03H
  39.         DB        03H
  40.         DB        03H
  41.         DB        03H
  42.         DB        04H
  43.         DB        04H
  44.         DB        04H
  45.         DB        04H
  46.         DB        04H
  47.         DB        04H
  48.         DB        04H
  49.         DB        04H
  50.         DB        04H
  51.         DB        05H
  52.         DB        05H
  53.         DB        05H
  54.         DB        05H
  55.         DB        05H
  56.         DB        05H
  57.         DB        05H
  58.         DB        05H
  59.         DB        05H
  60.         DB        05H
  61.         DB        05H
  62.         DB        06H
  63.         DB        06H
  64.         DB        06H
  65.         DB        06H
  66.         DB        06H
  67.         DB        06H
  68.         DB        06H
  69.         DB        06H
  70.         DB        06H
  71.         DB        06H
  72.         DB        06H
  73.         DB        06H
  74.         DB        06H
  75.         DB        07H
  76.         DB        07H
  77.         DB        07H
  78.         DB        07H
  79.         DB        07H
  80.         DB        07H
  81.         DB        07H
  82.         DB        07H
  83.         DB        07H
  84.         DB        07H
  85.         DB        07H
  86.         DB        07H
  87.         DB        07H
  88.         DB        07H
  89.         DB        07H
  90.         DB        080H
  91.         DB        080H
  92.         DB        081H
  93.         DB        082H
  94.         DB        083H
  95.         DB        084H
  96.         DB        085H
  97.         DB        086H
  98.         DB        087H
  99.         DB        088H
  100.         DB        089H
  101.         DB        08aH
  102.         DB        08bH
  103.         DB        08cH
  104.         DB        08dH
  105.         DB        08eH
  106.         DB        08fH
  107.         DB        090H
  108.         DB        090H
  109.         DB        091H
  110.         DB        092H
  111.         DB        093H
  112.         DB        094H
  113.         DB        095H
  114.         DB        096H
  115.         DB        096H
  116.         DB        097H
  117.         DB        098H
  118.         DB        099H
  119.         DB        09aH
  120.         DB        09bH
  121.         DB        09bH
  122.         DB        09cH
  123.         DB        09dH
  124.         DB        09eH
  125.         DB        09fH
  126.         DB        0a0H
  127.         DB        0a0H
  128.         DB        0a1H
  129.         DB        0a2H
  130.         DB        0a3H
  131.         DB        0a3H
  132.         DB        0a4H
  133.         DB        0a5H
  134.         DB        0a6H
  135.         DB        0a7H
  136.         DB        0a7H
  137.         DB        0a8H
  138.         DB        0a9H
  139.         DB        0aaH
  140.         DB        0aaH
  141.         DB        0abH
  142.         DB        0acH
  143.         DB        0adH
  144.         DB        0adH
  145.         DB        0aeH
  146.         DB        0afH
  147.         DB        0b0H
  148.         DB        0b0H
  149.         DB        0b1H
  150.         DB        0b2H
  151.         DB        0b2H
  152.         DB        0b3H
  153.         DB        0b4H
  154.         DB        0b5H
  155.         DB        0b5H
  156.         DB        0b6H
  157.         DB        0b7H
  158.         DB        0b7H
  159.         DB        0b8H
  160.         DB        0b9H
  161.         DB        0b9H
  162.         DB        0baH
  163.         DB        0bbH
  164.         DB        0bbH
  165.         DB        0bcH
  166.         DB        0bdH
  167.         DB        0bdH
  168.         DB        0beH
  169.         DB        0bfH
  170.         DB        0c0H
  171.         DB        0c0H
  172.         DB        0c1H
  173.         DB        0c1H
  174.         DB        0c2H
  175.         DB        0c3H
  176.         DB        0c3H
  177.         DB        0c4H
  178.         DB        0c5H
  179.         DB        0c5H
  180.         DB        0c6H
  181.         DB        0c7H
  182.         DB        0c7H
  183.         DB        0c8H
  184.         DB        0c9H
  185.         DB        0c9H
  186.         DB        0caH
  187.         DB        0cbH
  188.         DB        0cbH
  189.         DB        0ccH
  190.         DB        0ccH
  191.         DB        0cdH
  192.         DB        0ceH
  193.         DB        0ceH
  194.         DB        0cfH
  195.         DB        0d0H
  196.         DB        0d0H
  197.         DB        0d1H
  198.         DB        0d1H
  199.         DB        0d2H
  200.         DB        0d3H
  201.         DB        0d3H
  202.         DB        0d4H
  203.         DB        0d4H
  204.         DB        0d5H
  205.         DB        0d6H
  206.         DB        0d6H
  207.         DB        0d7H
  208.         DB        0d7H
  209.         DB        0d8H
  210.         DB        0d9H
  211.         DB        0d9H
  212.         DB        0daH
  213.         DB        0daH
  214.         DB        0dbH
  215.         DB        0dbH
  216.         DB        0dcH
  217.         DB        0ddH
  218.         DB        0ddH
  219.         DB        0deH
  220.         DB        0deH
  221.         DB        0dfH
  222.         DB        0e0H
  223.         DB        0e0H
  224.         DB        0e1H
  225.         DB        0e1H
  226.         DB        0e2H
  227.         DB        0e2H
  228.         DB        0e3H
  229.         DB        0e3H
  230.         DB        0e4H
  231.         DB        0e5H
  232.         DB        0e5H
  233.         DB        0e6H
  234.         DB        0e6H
  235.         DB        0e7H
  236.         DB        0e7H
  237.         DB        0e8H
  238.         DB        0e8H
  239.         DB        0e9H
  240.         DB        0eaH
  241.         DB        0eaH
  242.         DB        0ebH
  243.         DB        0ebH
  244.         DB        0ecH
  245.         DB        0ecH
  246.         DB        0edH
  247.         DB        0edH
  248.         DB        0eeH
  249.         DB        0eeH
  250.         DB        0efH
  251.         DB        0f0H
  252.         DB        0f0H
  253.         DB        0f1H
  254.         DB        0f1H
  255.         DB        0f2H
  256.         DB        0f2H
  257.         DB        0f3H
  258.         DB        0f3H
  259.         DB        0f4H
  260.         DB        0f4H
  261.         DB        0f5H
  262.         DB        0f5H
  263.         DB        0f6H
  264.         DB        0f6H
  265.         DB        0f7H
  266.         DB        0f7H
  267.         DB        0f8H
  268.         DB        0f8H
  269.         DB        0f9H
  270.         DB        0f9H
  271.         DB        0faH
  272.         DB        0faH
  273.         DB        0fbH
  274.         DB        0fbH
  275.         DB        0fcH
  276.         DB        0fcH
  277.         DB        0fdH
  278.         DB        0fdH
  279.         DB        0feH
  280.         DB        0feH
  281.         DB        0ffH
  282. _DATA        ENDS


  283. _TEXT        SEGMENT DWORD PUBLIC FLAT 'CODE'
  284.     ALIGN     4
  285.    
  286.         PUBLIC        _sqrtTab
  287.         PUBLIC        @UintSqrt@4

  288. @UintSqrt@4 PROC NEAR                                        ; COMDAT
  289. ; _n = ecx

  290. ;         if (n<64)
  291.         xor eax,eax
  292.         cmp        ecx, 64
  293.         jae        SHORT L25237
  294.         mov        al, BYTE PTR _sqrtTab[ecx]
  295.         ret        0

  296. L25237:
  297.         push        ebx

  298. ;          bc=log2(n)/2;
  299.         bsr        eax, ecx
  300.         shr        eax, 1
  301.         jmp        DWORD PTR L25370[eax*4]

  302. L25242:
  303. ;         case  3:
  304. ;         r=(sqrtTab[n]>>4);
  305.         mov        al, BYTE PTR _sqrtTab[ecx]
  306.         shr        eax, 4

  307. ; r1=r+1;
  308. ; if (r1*r1>=n) r++;
  309.         lea        ebx, DWORD PTR [eax+1]
  310.         mov        edx, ebx
  311.         imul edx, ebx
  312.         cmp        ecx, edx  
  313.         sbb eax,-1
  314.         pop ebx
  315.         ret 0

  316. L25244:       
  317. ; case  4:
  318. ; r=(sqrtTab[n>>2]>>3);
  319.         mov        ebx, ecx
  320.         shr        ebx, 2
  321.         mov        al, BYTE PTR _sqrtTab[ebx]
  322.         shr        eax, 3

  323. ;        r1=r+1;
  324. ;         if (r1*r1>=n) r++;
  325.         lea        ebx, DWORD PTR [eax+1]
  326.         mov        edx, ebx
  327.         imul        edx, ebx
  328.         cmp        ecx, edx   
  329.         sbb eax,-1
  330.         pop ebx
  331.         ret 0

  332. L25246:
  333. ;         case 5:
  334. ;        r=(sqrtTab[n>>4]>>2);
  335.         mov        ebx, ecx
  336.         shr        ebx, 4
  337.         mov        al, BYTE PTR _sqrtTab[ebx]
  338.         shr        eax, 2

  339. ;        r1=r+1;
  340. ;   if (r1*r1>=n) r++;
  341.         lea        ebx, DWORD PTR [eax+1]
  342.         mov        edx, ebx
  343.         imul        edx, ebx
  344.         cmp        ecx, edx   
  345.         sbb eax,-1
  346.         pop ebx
  347.         ret 0
  348.        
  349. L25248:
  350. ;         case 6:
  351. ;                 r=(sqrtTab[n>>6]>>1);
  352.         mov        ebx, ecx
  353.         shr        ebx, 6
  354.         mov        al, BYTE PTR _sqrtTab[ebx]
  355.         shr        eax, 1

  356. ;                 r1=r+1;
  357. ;                 if (r1*r1>=n) r++;
  358.         lea        ebx, DWORD PTR [eax+1]
  359.         mov        edx, ebx
  360.         imul edx, ebx
  361.         cmp        ecx, edx  
  362.         sbb eax,-1
  363.         pop ebx
  364.         ret 0


  365. L25250:
  366. ;         case 7:
  367. ;                 r=(sqrtTab[n>>8]);
  368.         mov        ebx, ecx
  369.         shr        ebx, 8
  370.         mov        al, BYTE PTR _sqrtTab[ebx]

  371. ;                 r1=r+1;
  372. ;                 if (r1*r1>=n)
  373.         lea        ebx, DWORD PTR [eax+1]
  374.         mov        edx, ebx
  375.         imul edx, ebx
  376.         cmp        ecx, edx
  377.         sbb eax,-1
  378.         pop ebx
  379.         ret 0

  380. L25252:
  381. ;         case 8:
  382. ;                 r=(sqrtTab[n>>10]<<1);
  383.         mov eax,ecx
  384.         xor ebx,ebx
  385.         shr        eax, 10                       
  386.         mov        bl, BYTE PTR _sqrtTab[eax]
  387.         add        ebx, ebx ;r=(sqrtTab[n>>10]<<1);
  388.        
  389.         ;r= (n/r + r)/2;
  390.         xor edx,edx
  391.         mov eax,ecx
  392.         div        ebx
  393.         add        eax, ebx
  394.         shr        eax, 1

  395. ;                 if (r*r>n) r--;
  396.         mov edx,eax
  397.         imul edx,eax
  398.         cmp ecx,edx
  399.         sbb eax,0
  400.         pop ebx
  401.         ret 0
  402.        
  403. L25254:
  404. ;         case 9:
  405. ;                 r=(sqrtTab[n>>12]<<2);

  406.         mov eax,ecx
  407.         xor ebx,ebx
  408.         shr        eax, 12       
  409.         mov        bl, BYTE PTR _sqrtTab[eax]
  410.         shl        ebx, 2

  411.         ;r= (n/r + r)/2;
  412.         xor edx,edx
  413.         mov eax,ecx
  414.         div        ebx
  415.         add        eax, ebx
  416.         shr        eax, 1

  417. ;                 if (r*r>n) r--;
  418.         mov edx,eax
  419.         imul edx,eax
  420.         cmp ecx,edx
  421.         sbb eax,0
  422.         pop ebx
  423.         ret 0

  424. L25256:
  425. ;         case 10:
  426. ;                 r=(sqrtTab[n>>14]<<3);

  427.         mov eax,ecx
  428.         xor ebx,ebx
  429.         shr        eax, 14
  430.         mov        bl, BYTE PTR _sqrtTab[eax]
  431.         shl        ebx, 3

  432.         ;r= (n/r + r)/2;
  433.         xor edx,edx
  434.         mov eax,ecx
  435.         div        ebx
  436.         add        eax, ebx
  437.         shr        eax, 1

  438.         ;        if (r*r>n) r--;
  439.         mov edx,eax
  440.         imul edx,eax
  441.         cmp ecx,edx
  442.         sbb eax,0
  443.         pop ebx
  444.         ret 0
  445. L25258:

  446. ;         case 11:
  447. ;                 r=(sqrtTab[n>>16]<<4);
  448.         mov eax,ecx
  449.         xor ebx,ebx
  450.         shr        eax, 16
  451.         mov        bl, BYTE PTR _sqrtTab[eax]
  452.         shl        ebx, 4
  453.        
  454.         ;r= (n/r + r)/2;
  455.         xor edx,edx
  456.         mov eax,ecx
  457.         div        ebx
  458.         add        eax, ebx
  459.         shr        eax, 1

  460.         ;        if (r*r>n) r--;
  461.         mov edx,eax
  462.         imul edx,eax
  463.         cmp ecx,edx
  464.         sbb eax,0
  465.         pop ebx
  466.         ret 0
  467.        
  468. L25260:
  469. ;         case 12:
  470. ;                  r=(sqrtTab[n>>18]<<5);
  471.         mov eax,ecx
  472.         xor ebx,ebx
  473.         shr        eax, 18
  474.         mov        bl, BYTE PTR _sqrtTab[eax]
  475.         shl        ebx, 5
  476.        
  477.         ;r= (n/r + r)/2;
  478.         xor edx,edx
  479.         mov eax,ecx
  480.         div        ebx
  481.         add        eax, ebx
  482.         shr        eax, 1

  483.         ;        if (r*r>n) r--;
  484.         mov edx,eax
  485.         imul edx,eax
  486.         cmp ecx,edx
  487.         sbb eax,0
  488.         pop ebx
  489.         ret 0
  490.        
  491.        
  492. L25262:
  493. ;          case 13:
  494. ;                  r=(sqrtTab[n>>20]<<6);
  495.         mov eax,ecx
  496.         xor ebx,ebx
  497.         shr        eax, 20
  498.         mov        bl, BYTE PTR _sqrtTab[eax]
  499.         shl        ebx, 6
  500.        
  501.         ;r= (n/r + r)/2;
  502.         xor edx,edx
  503.         mov eax,ecx
  504.         div        ebx
  505.         add        eax, ebx
  506.         shr        eax, 1

  507.         ;        if (r*r>n) r--;
  508.         mov edx,eax
  509.         imul edx,eax
  510.         cmp ecx,edx
  511.         sbb eax,0
  512.         pop ebx
  513.         ret 0

  514. L25264:
  515. ;          case 14:
  516. ;                  r=(sqrtTab[n>>22]<<7);
  517.         mov eax,ecx
  518.         xor ebx,ebx
  519.         shr        eax, 22
  520.         mov        bl, BYTE PTR _sqrtTab[eax]
  521.         shl        ebx, 7
  522.        
  523.         ;r= (n/r + r)/2;
  524.         xor edx,edx
  525.         mov eax,ecx
  526.         div        ebx
  527.         add        ebx, eax
  528.         shr        ebx, 1

  529.         ;r= (n/r + r)/2;
  530.         xor edx,edx
  531.         mov eax,ecx
  532.         div        ebx
  533.         add        eax, ebx
  534.         shr        eax, 1

  535.         ;        if (r*r>n) r--;
  536.         mov edx,eax
  537.         imul edx,eax
  538.         cmp ecx,edx
  539.         sbb eax,0
  540.         pop ebx
  541.         ret 0

  542. L25266:
  543. ;          case 15:
  544. ;                 r=(sqrtTab[n>>24]<<8);
  545.        
  546.         mov eax,ecx
  547.         xor ebx,ebx
  548.         shr        eax, 24
  549.         mov        bh, BYTE PTR _sqrtTab[eax]
  550.        
  551.         ;r= (n/r + r)/2;
  552.         xor edx,edx
  553.         mov eax,ecx
  554.         div        ebx
  555.         add        ebx, eax
  556.         shr        ebx, 1

  557.         ;r= (n/r + r)/2;
  558.         xor edx,edx
  559.         mov eax,ecx
  560.         div        ebx
  561.         add        eax, ebx
  562.         shr        eax, 1

  563.         ;        if (r*r>n) r--;
  564.         mov edx,eax
  565.         imul edx,eax
  566.         cmp ecx,edx
  567.         sbb eax,0
  568.         pop ebx
  569.         ret 0

  570.         align 4
  571. L25370:
  572.         DD        0
  573.         DD        0
  574.         DD        0
  575.         DD        L25242
  576.         DD        L25244
  577.         DD        L25246
  578.         DD        L25248
  579.         DD        L25250
  580.         DD        L25252
  581.         DD        L25254
  582.         DD        L25256
  583.         DD        L25258
  584.         DD        L25260
  585.         DD        L25262
  586.         DD        L25264
  587.         DD        L25266
  588. @UintSqrt@4 ENDP
  589. _TEXT        ENDS
  590. END
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-12 09:08:10 | 显示全部楼层
你只是把C改成了汇编形式

用汇编要用汇编的思维重新写算法的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-12 11:02:28 | 显示全部楼层

回复 28# 无心人 的帖子

No,No,No.
  虽然只是修改,但是修改的很多,尽量使用汇编的特性,以case 8为例,主要区别有:
  1. 寄存器的使用和编译器有很大的不同,直接编译出来的版本用到esi寄存器,需要两条保存寄存器指令,两条恢复指令,而我则用了一条寄存器保存和恢复指令,尽量合理调度指令,在同样的执行路径上,指令数也较叫编译器少。
  2. 为了速度快,宁愿写重复的代码,来减少跳转指令的使用。编译出来的版本使用了在case 8路径上需要执行3条条件转移指令,2条jmp跳转指令,而我的版本只用一条条件转移指令和一条jmp指令
  3. "if (r1*r1>=n) r++;" 这样的代码,编译器是使用jbe指令来做的,而我是采用 sbb eax,0 指令来实现的。
  4. 如果没有imul,div指令,我改编后的代码速度提高的就不是10%了。因为imul,div占主要运行时间,所以改用汇编后提速不大。

顺便说一下,我的C版在调用log2时,并没有使用call指令,log2被声明为inline函数,所以汇编提速(10%)全靠减少指令条数和减少跳转指令。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-12 11:42:49 | 显示全部楼层
呵呵

是否有整数算法不如浮点的结论了?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-4-19 19:53 , Processed in 0.043883 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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