shshsh_0510 发表于 2009-2-3 17:11:50

说明一下,表中对8个位中有两个1的数据,预先存好返回值,这样先检测前8位,只有9/256的数据需要继续检测后面
如果有一个1,也存好相应值
由于预先算好,于是程序执行主要是寻址

shshsh_0510 发表于 2009-2-3 17:13:31

原帖由 无心人 于 2009-2-3 17:08 发表 http://bbs.emath.ac.cn/images/common/back.gif
:lol

   你认为这么复杂的代码比我的汇编要高效么?
   况且,最终的代码的适用范围要比GxQ题目要求的大
   只要是1-2^32-2就可以
效率和代码复杂性的关系是这样的么?:)

shshsh_0510 发表于 2009-2-3 17:18:21

可能是比不过你们的,毕竟用内存和寄存器是有较大差别的,不好说,我觉得这个得试试

无心人 发表于 2009-2-3 19:27:20

从翻译后的汇编语句的行数就肯定要比我的多很多了啊
而且这么多比较和分支

shshsh_0510 发表于 2009-2-3 20:44:18

试了一下,比你们的慢10倍:P

无心人 发表于 2009-2-3 20:53:17

:lol

   那个,你比较了时间, 哪组汇编快???

gxqcn 发表于 2009-2-3 21:11:19

GxQ 的版本

typedef unsigned int UINT32;

const UINT32 POW2[] = { 0, 1UL, 1UL<<1, 1UL<<2, 1UL<<3,
                        1UL<<4,1UL<<5,1UL<<6,1UL<<7,
                        1UL<<8,1UL<<9,1UL<<10, 1UL<<11,
                        1UL<<12, 1UL<<13, 1UL<<14, 1UL<<15,
                        1UL<<16, 1UL<<17, 1UL<<18, 1UL<<19,
                        1UL<<20, 1UL<<21, 1UL<<22, 1UL<<23,
                        1UL<<24, 1UL<<25, 1UL<<26, 1UL<<27,
                        1UL<<28, 1UL<<29, 1UL<<30, 1UL<<31 };

__declspec(naked)
UINT32 GreaterEqualBit2_57F( UINT32 n /* 1 <= n <= 2^31+2^30 */ )
{
    __asm
    {
      lea   edx, dword ptr;
      mov   eax, dword ptr;

      bsr   ecx, eax;
      mov   ecx, dword ptr;
      push    ecx;

      xor   eax, ecx;
      mov   ecx, -1;
      bsr   ecx, eax;
      mov   ecx, dword ptr;

      lea   edx, ;
      xor   eax, ecx;
      cmovneecx, edx;

      pop   eax;
      add   eax, ecx;

      ret;
    }
}15条指令,无移位运算(用查表法)

gxqcn 发表于 2009-2-3 21:11:25

__declspec(naked)
UINT32 GreaterEqualBit2_58F( UINT32 n /* 1 <= n <= 2^31+2^30 */ )
{
    __asm
    {
      mov   edx, dword ptr;
      mov   eax, 1;

      bsr   ecx, edx;
      shl   eax, cl;
      push    eax;

      xor   edx, eax;
      bsr   ecx, edx;
      mov   eax, 0;
      setne   al;
      shl   eax, cl;

      lea   ecx, ;
      xor   edx, eax;
      cmovneeax, ecx;

      pop   edx;
      add   eax, edx;

      ret;
    }
}移位(不查表)

gxqcn 发表于 2009-2-3 21:11:30

__declspec(naked)
UINT32 GreaterEqualBit2_59F( UINT32 n /* 1 <= n <= 2^31+2^30 */ )
{
    __asm
    {
      push    ebx;
      mov   ebx, dword ptr;

      bsr   ecx, ebx
      mov   eax, 1
      shl   eax, cl

      xor   ebx, eax
      xor   edx, edx
      bsr   ecx, ebx
      setne   dl
      shl   edx, cl
      add   eax, edx

      xor   ecx, ecx
      sub   ebx, edx
      cmovneecx, edx

      add   eax, ecx

      pop   ebx;

      ret;
    }
}(改编自无心人的 36#)

gxqcn 发表于 2009-2-3 21:17:55

测试结果

在 Intel P4 2.93GHz CPU 上,对 n 从 1 到 2147483648 进行测试,运行时间如下:
24#: 25 s
36#: 35 s
57#: 25 s
58#: 32 s
59#: 27 s

在 AMD Athlon 64 3200+ 上测试则为:
24#: 40 s
36#: 37 s
57#: 37 s
58#: 36 s
59#: 38 s

注:24# 为 liangbch 所写;36# 为 无心人 所写;后3个则为 GxQ 所写。
页: 1 2 3 4 5 [6] 7 8 9 10 11
查看完整版本: 求bit位为1数目不超出2的正整数