http://ll.jus.or.jp/2006/blog/doukaku2
ããããå»å¹´æ大å¦ã®ä¸¦åè¨ç®ã®è¬ç¾©ã§ãã¿ã«ãã¾ãããç°¡åãªæ´æ°æ¼ç®ã大éã«ãã£ã¦ä½ãé¢ç½ããã¨ãåºæ¥ã話ã®ä¸ã¤ã¨ãã¦ã2CH ã®ããªããã/etc/passwd ã®ã¯ã©ãã¯ãªã©ã¨å
±ã«ç´¹ä»ãã¾ããã
åèãªã³ã¯ï¼http://www.math.grinnell.edu/~chamberl/conference/proceedings.html
é«éåã®æ¹æ³ã¨ãã¦èããããã®ã¯ãè¨ç®æ¸ã¿ã® g(n) ãä¿åãã¦ãå¾ã®è¨ç®ã§ããã«ããããããè¨ç®ãçç¥ãããã¦ã®ã ãã©ãå¿
è¦ãªã¡ã¢ãªãäºæ¸¬ã§ããªãã®ã§ããªããã¼ããªã
ã¨ããããæ¸ãã¦ã¿ã
å®è¡çµæãAMD Sempron ã®LINUX + GCCã10000 ã¾ã§ã¯ééãã¦æ¸¬å®ä¸è½ã100000ã§0.01secã1000000 ã§int ã®ãªã¼ãã¼ããã¼ã§è½ã¡ãã使ç¨ã¡ã¢ãªã¯æ°ã¡ã¬ã
追è¨
ä¸å®ã®å¤ãè¶ãã㨠64 bit æ¼ç®ã«ã¹ã¤ããããããæ¹é ãã¦ã¿ããgprof ã§èª¿ã¹ã㨠64 bit æ¼ç®ã«è²»ãã¦ããæé㯠n=10^8 ã®å ´åã§ãå
¨ä½ã®3% ç¨åº¦ãªãã§ãå
¨é¨64bit ã§ãããããéããªã£ã¦ããã¨æãããã 追è¨ï¼å
¨é¨64bitã§ãã£ãã»ããéãã£ãã
n=10^8 ãããããã¡ã¢ãªä¸è¶³ã§ãã¼ãã«å¼ããã§ããªããªã£ã¦é
ããªãã
time a.out 100 g(97) = 119 0.000u 0.000s 0:00.00 0.0% 0+0k 0+0io 84pf+0w time a.out 1000 g(871) = 179 0.000u 0.000s 0:00.00 0.0% 0+0k 0+0io 84pf+0w time a.out 10000 g(6171) = 262 0.000u 0.000s 0:00.00 0.0% 0+0k 0+0io 84pf+0w time a.out 100000 g(77031) = 351 0.010u 0.010s 0:00.02 100.0% 0+0k 0+0io 84pf+0w time a.out 1000000 ã»ã°ã¡ã³ãã¨ã©ã¼
64 bit ç (ãã°ããã£ãã以ä¸ä¿®æ£æ¸ã¿)
time a.out 1000000 g(837799) = 525 0.110u 0.150s 0:00.27 96.2% 0+0k 0+0io 90pf+0w time a.out 10000000 g(8400511) = 686 1.000u 1.080s 0:02.08 100.0% 0+0k 0+0io 97pf+0w time a.out 100000000 (ãã¼ãã«ãµã¤ãº = n * 0.1) g(63728127) = 950 26.410u 26.470s 0:52.98 99.8% 0+0k 0+0io 101pf+0w time a.out 1000000000 (ãã¼ãã«ãµã¤ãº = n * 0.03) g(670617279) = 987 434.710u 435.190s 14:31.53 99.8% 0+0k 0+0io 97pf+0w ããã¯èªèº«ãªã n=10000000000 g(9780657630) = 1133 4222.760u 4223.620s 2:23:12.06 98.3% 0+0k 0+0io 95pf+0w
10^10 以é㯠n ã int ä¸éãè¶ããã®ã§å
¨é¨ 64 bit ã§ãã£ãã»ããããããããã¨ãã¼ãã«ã¯å½¹ã«ç«ããªããªããã§ç´ ç´ã«å
¨é¨è¨ç®ããã»ããä¸çªéãããããã¶ã n log(n) ã®è¨ç®æéã«ãªãã
n=4000000 ã®æããã¼ãã«ã®ãµã¤ãºãããããå¤ãã¦æ¸¬ãã¨ä»¥ä¸ã®ããã«ãªã£ãããã¼ãã«ãµã¤ãºãnã¨åãæãæé©ã£ã½ãã
ãµã¤ãº CPUæé 0.1 n 0.960 0.2 n 0.690 0.4 n 0.480 0.6 n 0.390 0.8 n 0.350 1.0 n 0.340 1.2 n 0.380 1.4 n 0.390 1.6 n 0.440
ã½ã¼ã¹ã¯ãã¡ãã64 bit ã§è¡ãé¨å㯠#ifdef GO_64 ã§å²ã£ã¦ããã
#include <stdio.h> #include <stdlib.h> #define GO_64 0x40000000 #ifdef GO_64 void handle_64(unsigned int *x, int *g) { int g0 = 0; unsigned long long x64 = *x; while (x64 >= GO_64) { unsigned long long m = x64>>1; if (x64 & 1) { x64 = 3*m+2; g0 += 2; } else { x64 = m; g0++; } if (x64 > 0x4000000000000000LL) { printf("Error 64 bit is not enough!\n"); exit(1); } } *x = (unsigned int) x64; (*g) += g0; } #endif int main(int argc, char **argv) { int i,j,k; #define H_BUFSIZE (1<<16) int x_log[H_BUFSIZE]; int g_log[H_BUFSIZE]; int gmax = 1; int kmax = 1; int n = atoi(argv[1]); int *gtable; int gtable_size = n; if (argc==3) { double r = (double)atof(argv[2]); gtable_size = (int)(n * r + 1); } #define GTABLE_MAX 30000000 if (gtable_size > GTABLE_MAX) gtable_size = GTABLE_MAX; gtable = (int *)malloc(gtable_size * sizeof(int)); if (gtable == NULL) { printf("Not enough memory\n"); exit(1); } printf("Buffer size ratio %f\n",1.0*gtable_size/n); for(i=0;i<gtable_size;i++) gtable[i] = 0; gtable[0] = 1; for(i=0;i<n;i++) { int g=0; int n_log = 0; unsigned int x = i+1; while( (x > gtable_size) || (gtable[x-1] == 0)) { if (x <= gtable_size) { x_log[n_log] = x; g_log[n_log] = g; n_log++; } if (x & 1) x = x*3+1; else x >>=1; g++; #ifdef GO_64 if (x > GO_64) handle_64(&x, &g); #endif } g += gtable[x-1]; for(j=0;j<n_log;j++) { int g0 = g_log[j]; x = x_log[j]; gtable[x-1] = g-g0; } if (g>gmax) { gmax = g; kmax = i+1; } }//i printf("g(%d) = %d\n",kmax, gmax); }