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

[求助] 关于一个运算优化的问题

[复制链接]
发表于 2009-3-23 09:52:26 | 显示全部楼层
使用了更多的汇编。函数logSum几乎 完全汇编(没有使用386以上的指令)化了,这样终于达到了传说中的0.062. 以下代码为主函数。
  1. int main(int argc, char* argv[])
  2. {
  3. int i,count;
  4. DWORD d0,d1,d2,d3, nlogSum;
  5. UINT128 *pData=NULL;

  6. scanf("%d",&count);
  7. pData=new UINT128[count];

  8. for (i=0;i<count;i++)
  9. {
  10. scanf("%u %u %u %u",&d0,&d1,&d2,&d3);
  11. pData[i].U[0]=d0;
  12. pData[i].U[1]=d1;
  13. pData[i].U[2]=d2;
  14. pData[i].U[3]=d3;
  15. }

  16. qsort( (void *)pData, (size_t)count, sizeof(UINT128), Uint128Compare );
  17. nlogSum= logSum(pData,count);
  18. delete[] pData; pData=NULL;

  19. printf("%lu\n",nlogSum);
  20. return 0;
  21. }
复制代码

评分

参与人数 1威望 +1 鲜花 +1 收起 理由
litaoye + 1 + 1

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 09:58:44 | 显示全部楼层


这么多汇编,可就有点麻烦了
呵呵
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 10:00:55 | 显示全部楼层

回复 161# liangbch 的帖子

  1. for (i=0;i<count;i++)
  2. {
  3.     scanf("%u %u %u %u",&d0,&d1,&d2,&d3);
  4.     pData[i].U[0]=d0;
  5.     pData[i].U[1]=d1;
  6.     pData[i].U[2]=d2;
  7.     pData[i].U[3]=d3;
  8. }
复制代码
也可简化成以下形式吧?
  1. for (i=0;i<count;i++)
  2. {
  3.     scanf("%u %u %u %u",&(pData[i].U[0]),&(pData[i].U[1]),&(pData[i].U[2]),&(pData[i].U[3]));
  4. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 10:01:33 | 显示全部楼层
祝贺各位!

正如 litaoye 在 151# 所言:
原帖由 litaoye 于 2009-3-20 04:05 发表
。。。这道题的平均水平都被大家带高了!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 10:08:49 | 显示全部楼层
这其中似乎有别的因素在影响时间
比如L2 Cache等
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 10:29:47 | 显示全部楼层

回复 163# gxqcn 的帖子

完全可以呀,不过对性能几乎没有影响。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 14:36:20 | 显示全部楼层

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. typedef struct
  5. {
  6.     unsigned int d[4];
  7. } UINT128;

  8. unsigned int CompTable[128][2] =  {0,0, 0,0, 0,0, 0,1, 1,0, 1,0, 1,1, 2,0, 2,0, 2,1, 3,0, 3,0, 3,0, 3,1,
  9.     4,0,4,0,4,1,5,0,5,0,5,1,6,0,6,0,6,0,6,1,7,0,7,0,7,1,8,0,8,0,
  10.     8,1,9,0,9,0,9,0,9,1,10,0,10,0,10,1,11,0,11,0,11,1,12,0,12,
  11.     0,12,0,12,1,13,0,13,0,13,1,14,0,14,0,14,1,15,0,15,0,15,0,15,
  12.     1,16,0,16,0,16,1,17,0,17,0,17,1,18,0,18,0,18,0,18,1,19,0,19,
  13.     0,19,1,20,0,20,0,20,1,21,0,21,0,21,0,21,1,22,0,22,0,22,1,23,
  14.     0,23,0,23,1,24,0,24,0,24,0,24,1,25,0,25,0,25,1,26,0,26,0,26,
  15.     1,27,0,27,0,27,0,27,1,28,0,28,0,28,1,29,0,29,0,29,1,30,0,30,
  16.     0,30,1,31,0,31,0,31,0,31,1,32,0,32,0,32,1,33,0,33,0,33,1,34,
  17.     0,34,0,34,0,34,1,35,0,35,0,35,1,36,0,36,0,36,1,37,0,37,0,37,0,37,1,38,0};

  18. UINT128 pow10[40] = {1,0,0,0,
  19.     10,0,0,0,
  20.     100,0,0,0,
  21.     1000,0,0,0,
  22.     10000,0,0,0,
  23.     100000,0,0,0,
  24.     1000000,0,0,0,
  25.     10000000,0,0,0,
  26.     100000000,0,0,0,
  27.     1000000000,0,0,0,
  28.     1410065408,2,0,0,
  29.     1215752192,23,0,0,
  30.     3567587328,232,0,0,
  31.     1316134912,2328,0,0,
  32.     276447232,23283,0,0,
  33.     2764472320,232830,0,0,
  34.     1874919424,2328306,0,0,
  35.     1569325056,23283064,0,0,
  36.     2808348672,232830643,0,0,
  37.     2313682944,2328306436,0,0,
  38.     1661992960,1808227885,5,0,
  39.     3735027712,902409669,54,0,
  40.     2990538752,434162106,542,0,
  41.     4135583744,46653770,5421,0,
  42.     2701131776,466537709,54210,0,
  43.     1241513984,370409800,542101,0,
  44.     3825205248,3704098002,5421010,0,
  45.     3892314112,2681241660,54210108,0,
  46.     268435456,1042612833,542101086,0,
  47.     2684354560,1836193738,1126043566,1,
  48.     1073741824,1182068202,2670501072,12,
  49.     2147483648,3230747430,935206946,126,
  50.     0,2242703233,762134875,1262,
  51.     0,952195850,3326381459,12621,
  52.     0,932023908,3199043520,126217,
  53.     0,730304488,1925664130,1262177,
  54.     0,3008077584,2076772117,12621774,
  55.     0,16004768,3587851993,126217744,
  56.     0,160047680,1518781562,1262177448,
  57.     0, 0, 0, 0};

  58. /*
  59. __declspec(naked)
  60. int __fastcall log2(UINT128 * n)
  61. {
  62.     __asm
  63.     {
  64.         bsr eax, [ecx]
  65.         bsr edx, [ecx + 4]
  66.         add edx, 32
  67.         cmp [ecx + 4], 0
  68.         cmovne eax, edx
  69.         bsr edx, [ecx + 8]
  70.         add edx, 64
  71.         cmp [ecx + 8], 0
  72.         cmovne eax, edx
  73.         bsr edx, [ecx + 12]
  74.         add edx, 96
  75.         cmp [ecx + 12], 0
  76.         cmovne eax, edx
  77.         ret   
  78.     }
  79. }

  80. */
  81. int compare( const void * a, const void * b )
  82. {
  83.     unsigned int * l, * r;
  84.     l = (unsigned int *)a; r = (unsigned int *)b;
  85.     if (*(l+3) != *(r + 3)) return (*(l + 3) > *(r+3) ? 1 : -1);
  86.     if (*(l+2) != *(r + 2)) return (*(l + 2) > *(r+2) ? 1 : -1);
  87.     if (*(l+1) != *(r + 1)) return (*(l + 1) > *(r+1) ? 1 : -1);
  88.     return (* l > * r ? 1 : (* l == * r ? 0 : -1));
  89. }

  90. __declspec(naked)
  91. int __fastcall log_10(UINT128 * n)
  92. {
  93.     __asm
  94.     {
  95.     bsr edx, [ecx]
  96.     bsr eax, [ecx + 4]
  97.     add eax, 32
  98.     cmp dword ptr [ecx + 4], 0
  99.     cmovne edx, eax
  100.     bsr eax, [ecx + 8]
  101.     add eax, 64
  102.     cmp dword ptr [ecx + 8], 0
  103.     cmovne edx, eax
  104.     bsr eax, [ecx + 12]
  105.     add eax, 96
  106.     cmp dword ptr [ecx + 12], 0
  107.     cmovne edx, eax
  108.     mov eax, dword ptr CompTable[8 * edx]
  109.     cmp dword ptr CompTable[8 * edx + 4], 0
  110.     je ex
  111.     add eax, 1
  112.     mov edx, eax
  113.     shl edx, 4
  114.     push ebx
  115.     mov ebx, [ecx]
  116.     sub ebx, pow10[edx]
  117.     mov ebx, [ecx + 4]
  118.     sbb ebx, pow10[edx + 4]
  119.     mov ebx, [ecx + 8]
  120.     sbb ebx, pow10[edx + 8]
  121.     mov ebx, [ecx + 12]
  122.     sbb ebx, pow10[edx + 12]
  123.     sbb ebx, ebx
  124.     add eax, ebx
  125.     pop ebx
  126.   ex:   
  127.     ret
  128.     }   
  129. }

  130. __declspec(naked)
  131. int __fastcall logxor(UINT128 * a, UINT128 * b)
  132. {
  133.   __asm
  134.   {
  135.     mov eax, 0
  136.     ret
  137.   }
  138. }

  139. int main(int argc, char* argv[])
  140. {
  141.     int count,result,i,j, k;
  142.     UINT128 data[5000], r;
  143.    
  144.     scanf("%d",&count);
  145.     result=0;
  146.     i = 0;
  147.     while (i < count) {
  148.         scanf("%u", &data[i].d[3]);
  149.         scanf("%u", &data[i].d[2]);
  150.         scanf("%u", &data[i].d[1]);
  151.         scanf("%u", &data[i].d[0]);
  152.         i++;
  153.     }

  154.     qsort( (void *)data, (size_t)count, 16, compare );

  155.     for (i= 0; i < count - 1; i ++)
  156.     {
  157.         for (j = i + 1; j < count; j ++)
  158.         {

  159.             r.d[3] = data[i].d[3] ^ data[j].d[3];   
  160.             r.d[2] = data[i].d[2] ^ data[j].d[2];   
  161.             r.d[1] = data[i].d[1] ^ data[j].d[1];   
  162.             r.d[0] = data[i].d[0] ^ data[j].d[0];
  163. //            printf("%u, %u, %u, %u", r.d[3], r.d[2], r.d[1], r.d[0]);
  164. //            printf(":%u\n", log_10(&r));
  165.             result += log_10(&r);
  166.         }
  167.     }

  168.     printf("%u",result*2);
  169.     return 0;
  170. }
复制代码
0.156
和各位还存在一点点差距

评分

参与人数 1威望 +1 鲜花 +1 收起 理由
litaoye + 1 + 1

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 16:09:29 | 显示全部楼层
有点昏昏的

好像,大概,似乎,寄存器不够用了啊

不知道 宝宝怎么设定的寄存器
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 16:27:21 | 显示全部楼层

回复 168# 无心人 的帖子

我的建议,如果先求128bit的xor运算再求 log10 就比较慢。我是将2者结合在一起的。在我的程序中,先对两个128bit数的最高32bit的边求xor,如果值为0,继续求下32bit。 直到结果非0。 如果前64bit是0,那么在和10^n比较的时候就只需比较后64bit 就可以了。
  我的xorLog10函数没有内存写指令,也不用SSE,SSE2,MMX 和 REP cmpd 等指令,寄存器完全够用了。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-23 16:40:23 | 显示全部楼层


俺用了xmm寄存器了
所以也够用了

就是汇编语句有点长
快100行了

所以毛病太多了
使劲调试中
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-5-5 06:29 , Processed in 0.064465 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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