找回密码
 欢迎注册
楼主: gxqcn

[擂台] 求bit位为1数目不超出2的正整数

[复制链接]
发表于 2009-2-3 22:21:48 | 显示全部楼层
如果怕兼容性问题,用mm0也可以的
不会有不支持mmx的U了吧
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-3 23:12:27 | 显示全部楼层
刚去查MMX的书(中文实体书)
movd是有的
也可以考虑下MMX的部分指令
所以59#应该还能优化
不知道GxQ能否给出代码的完整程序

另外,如果程序不用浮点,用不到emms
甚至,只要在浮点前用可以了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-4 09:54:10 | 显示全部楼层

测试模版

  1. #include < stdio.h >
  2. #include < time.h >

  3. typedef unsigned int UINT32;

  4. typedef UINT32 func_t( UINT32 );

  5. #define FN(ID)      GreaterEqualBit2_##ID##F /* ex.: GreaterEqualBit2_24F */
  6. #define TEST_VAL    314159265UL

  7. /*

  8. UINT32 GreaterEqualBit2_24F( UINT32 n /* 1 <= n <= 2^31+2^30 */ )
  9. {
  10.     ...
  11. }

  12. ...
  13. */

  14. void testFun( void )
  15. {
  16.     time_t t;
  17.     UINT32 i, j;
  18.     UINT32 fID[] = { 24, 36, 57, 58, 59 };
  19.     func_t * funcTable[] = { FN(24), FN(36), FN(57), FN(58), FN(59) };
  20.     func_t * pfn;

  21.     // check result
  22.     for ( i=0; i<sizeof(fID)/sizeof(fID[0]); ++i )
  23.     {
  24.         printf( "GreaterEqualBit2_%uF(%u)=0x%X\n",
  25.             fID[i], TEST_VAL, (funcTable[i])(TEST_VAL) );
  26.     }

  27.     // test speed
  28.     printf( "\n\nn: 1-2^31\n\n" );
  29.     for ( i=0; i<sizeof(fID)/sizeof(fID[0]); ++i )
  30.     {
  31.         pfn = funcTable[i];

  32.         t = time(NULL);
  33.         for ( j=0x80000000UL; 0!=j; --j )
  34.         {
  35.             pfn( j );
  36.         }
  37.         t = time(NULL)-t;

  38.         printf( "%u#: %u s\n", fID[i], t );
  39.     }

  40. }

  41. int main(int argc, char* argv[])
  42. {
  43.     testFun();

  44.     return 0;
  45. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-4 12:50:40 | 显示全部楼层
我也曾想到查表法,这样,就可以省掉移位指令。这样指令是少了,但增加了访问L1/L2 cache的开销。
我曾试图在不使用查表法的基础上,精简指令条数,但没有取得突破。
在 Intel 和 AMD cpu上的测试结果表明,AMD 对cache 读写不敏感, 而Intel的cpu则对读写cache比较敏感。
在PIV cpu 运行gxq的那个版本,减少的指令条数的正效应 和 cache读写的负效 正好抵消,故和我的版本速度相当。而在AMD cpu运行 这几个版本,gxq  和 无心人的版本因指令较少而胜出。
  
  另外,我认为,测试代码和真实环境应该很难做到一致。测试代码多次读写同一处地址空间。故对RAM的存取实际上是对L1 cache的存取。而在真实环境则存在cache命中失败的情况。故在真实环境下,使用查表法的的实际运行速度应该慢于测试代码。

评分

参与人数 1威望 +2 收起 理由
gxqcn + 2 观点精辟

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-4 14:05:52 | 显示全部楼层
__declspec(naked)
UINT32 GreaterEqualBit2_75F( UINT32 n /* 1 <= n <= 2^31+2^30 */ )
{
    __asm
    {
        movd mm0, ebx
        mov     ebx, [esp+4]
        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
        cmovne  ecx, edx

        add     eax, ecx

        movd    ebx, mm0

        ret;
    }
}
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-4 14:06:50 | 显示全部楼层
增加一个测试例子
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-4 14:44:09 | 显示全部楼层
Core 2 XEON 1.6G

...\GreaterEqualBit2\Debug>GreaterEqualBit2.exe
GreaterEqualBit2_24F(314159265)=0x14000000
GreaterEqualBit2_25F(314159265)=0x14000000
GreaterEqualBit2_36F(314159265)=0x14000000
GreaterEqualBit2_57F(314159265)=0x14000000
GreaterEqualBit2_58F(314159265)=0x14000000
GreaterEqualBit2_59F(314159265)=0x14000000
GreaterEqualBit2_75F(314159265)=0x14000000
24# 24321.769 ms
25# 23220.229 ms
36# 26370.029 ms
57# 22912.707 ms
58# 25381.062 ms
59# 24208.571 ms
75# 23457.994 ms

...\GreaterEqualBit2\Debug>GreaterEqualBit2.exe
GreaterEqualBit2_24F(314159265)=0x14000000
GreaterEqualBit2_25F(314159265)=0x14000000
GreaterEqualBit2_36F(314159265)=0x14000000
GreaterEqualBit2_57F(314159265)=0x14000000
GreaterEqualBit2_58F(314159265)=0x14000000
GreaterEqualBit2_59F(314159265)=0x14000000
GreaterEqualBit2_75F(314159265)=0x14000000
24# 24329.577 ms
25# 23221.619 ms
36# 26376.303 ms
57# 22911.231 ms
58# 25355.553 ms
59# 24209.400 ms
75# 23447.267 ms
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-4 15:04:06 | 显示全部楼层
可以认为, 查表法没有多少优势
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-4 16:35:56 | 显示全部楼层
程序代码和编译后程序
仅要求支持MMX即可

代码
GreaterEqualBit2.cpp (5.48 KB, 下载次数: 0)

程序
GreaterEqualBit2.zip (9.26 KB, 下载次数: 1)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-4 16:36:12 | 显示全部楼层
P4 Xeon 2.0G结果

GreaterEqualBit2_24F(314159265)=0x14000000
GreaterEqualBit2_25F(314159265)=0x14000000
GreaterEqualBit2_36F(314159265)=0x14000000
GreaterEqualBit2_57F(314159265)=0x14000000
GreaterEqualBit2_58F(314159265)=0x14000000
GreaterEqualBit2_59F(314159265)=0x14000000
GreaterEqualBit2_75F(314159265)=0x14000000
24# 43275.580 ms
25# 38754.110 ms
36# 68405.044 ms
57# 41526.848 ms
58# 44159.591 ms
59# 43885.799 ms
75# 43158.709 ms

GreaterEqualBit2_24F(314159265)=0x14000000
GreaterEqualBit2_25F(314159265)=0x14000000
GreaterEqualBit2_36F(314159265)=0x14000000
GreaterEqualBit2_57F(314159265)=0x14000000
GreaterEqualBit2_58F(314159265)=0x14000000
GreaterEqualBit2_59F(314159265)=0x14000000
GreaterEqualBit2_75F(314159265)=0x14000000
24# 43023.756 ms
25# 38908.013 ms
36# 68550.773 ms
57# 41309.780 ms
58# 43682.767 ms
59# 43913.680 ms
75# 43546.108 ms
=======================================
25#优势明显
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-4-27 03:36 , Processed in 0.047961 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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