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

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

[复制链接]
发表于 2009-3-18 12:16:32 | 显示全部楼层
才一个主题贴,就奉上这么长的代码,着实让我吃惊。。虽然我能看得懂代码,但毕竟内功远远不够,
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-18 12:18:24 | 显示全部楼层
我开始醒悟,我既非理科,又非计算机专业的,进了这地方,是一个很大的冒失啊。

向你们致敬,想你们学习了!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-18 14:01:18 | 显示全部楼层


用我给出的表,直接查表,似乎还能加速
你的代码已经比我给出的表数据多了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-19 10:24:31 | 显示全部楼层
我从0.342优化到0.171,如果优化后速度再提高一倍,就是第一名了。按照楼主的思路,将XOR和log10这2步操作合在一起,用汇编语言写成一个函数,速度应该可以更快。等有时间我将尝试一下。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-19 11:05:21 | 显示全部楼层
呵呵

我第一次是0.468, 普通算法
不如shshsh_0510的普通算法

按照楼主的思路写的代码
现在是0.234

看来还需要优化啊
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-19 11:29:17 | 显示全部楼层
目前的笨代码
和各位无法比啊

  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. inline int _log2(unsigned int r)
  59. {
  60.         __asm
  61.         {
  62.                 bsr eax,r
  63.         }
  64. }

  65. inline int log2( UINT128 n)
  66. {
  67.     if (n.d[3] != 0) return (96 + _log2(n.d[3]));
  68.     if (n.d[2] != 0) return (64 + _log2(n.d[2]));
  69.     if (n.d[1] != 0) return (32 + _log2(n.d[1]));
  70. return (_log2(n.d[0]));
  71. }

  72. inline int compare( const void * a, const void * b )
  73. {
  74. unsigned int * l, * r;
  75. l = (unsigned int *)a; r = (unsigned int *)b;
  76. if (*(l+3) != *(r + 3)) return (*(l + 3) > *(r+3) ? 1 : -1);
  77. if (*(l+2) != *(r + 2)) return (*(l + 2) > *(r+2) ? 1 : -1);
  78. if (*(l+1) != *(r + 1)) return (*(l + 1) > *(r+1) ? 1 : -1);
  79. return (* l > * r ? 1 : (* l == * r ? 0 : -1));

  80. }

  81. inline int log_10(UINT128 n)
  82. {
  83.    int i = log2(n), j = CompTable[i][0];
  84.    if (CompTable[i][1] == 0) return (j);
  85.    if (compare(&n, &pow10[j + 1]) >= 0) return (j + 1); else return j;
  86. }

  87. int main(int argc, char* argv[])
  88. {
  89.     int count,result,i,j, k;
  90.     UINT128 data[5000];
  91. unsigned int l2[5000];
  92.     unsigned int l10[5000];
  93. UINT128 r;

  94.     scanf("%d",&count);
  95.     result=0;
  96. i = 0;
  97.     while (i < count) {
  98.         scanf("%u", &data[i].d[3]);
  99.         scanf("%u", &data[i].d[2]);
  100.         scanf("%u", &data[i].d[1]);
  101.         scanf("%u", &data[i].d[0]);
  102.         i++;
  103.     }

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

  105. for (i = 0; i < count; i ++)
  106. {
  107. l10[i] = log_10(data[i]);
  108.         l2[i] = log2(data[i]);
  109. }

  110.     for (i= count - 1; i > 0; i --)
  111. {
  112. k = l2[i];
  113. if (CompTable[k][1] == 0)
  114. {
  115.    j = i - 1;
  116.           while ((l2[j] == k) && (j >= 0))
  117.    {
  118.              r.d[3] = data[i].d[3] ^ data[j].d[3];   
  119.              r.d[2] = data[i].d[2] ^ data[j].d[2];   
  120.              r.d[1] = data[i].d[1] ^ data[j].d[1];   
  121.              r.d[0] = data[i].d[0] ^ data[j].d[0];
  122.       result += log_10(r);
  123.   j --;
  124.           }
  125.    if (j >= 0)
  126.    result += l10[i] * (j + 1);
  127. }
  128. else
  129.    for (j = i - 1; j >= 0; j --)
  130.    {
  131.    
  132.              r.d[3] = data[i].d[3] ^ data[j].d[3];   
  133.              r.d[2] = data[i].d[2] ^ data[j].d[2];   
  134.              r.d[1] = data[i].d[1] ^ data[j].d[1];   
  135.              r.d[0] = data[i].d[0] ^ data[j].d[0];
  136.       result += log_10(r);
  137.           }
  138. }
  139.     printf("%u",result*2);
  140.     return 0;
  141. }
复制代码


0.203
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-19 13:31:48 | 显示全部楼层
__declspec(naked)
int log2(UINT128 * n)
{
   __asm
   {
    mov edx, [esp + 4]
    bsr eax, [edx]
    bsr ecx, [edx + 4]
    add ecx, 32
    cmp [edx + 4], 0
    cmovne eax, ecx
    bsr ecx, [edx + 8]
    add ecx, 64
    cmp [edx + 8], 0
    cmovne eax, ecx
    bsr ecx, [edx + 12]
    add ecx, 96
    cmp [edx + 12], 0
    cmovne eax, ecx
    ret   
   }
}
128位求2的对数非跳转版本!!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-19 13:39:52 | 显示全部楼层
C中内嵌汇编,
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-19 14:09:23 | 显示全部楼层
我将我的101楼代码的阅读权限调低了。现在只有积分达到200分,就可以看我101楼的代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-3-19 16:40:54 | 显示全部楼层
147# OK了

下面汇编化 log10和log10xor

呵呵
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-5-5 11:21 , Processed in 0.043567 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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