Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/mty-makai/mty.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 257 - (show annotations) (download) (as text)
Sun Jan 2 06:13:37 2011 UTC (13 years, 3 months ago) by notanpe
File MIME type: text/x-csrc
File size: 19791 byte(s)
ギア指定時に最小タイマ分解能を変更。 (副作用はあるのか?)
1 /***********************************************************************
2 *
3 * file: mty.c
4 *
5 * まあ、待て屋。
6 *
7 * $Id$
8 *
9 */
10
11 #include <assert.h>
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <time.h>
15 #include <sys/timeb.h>
16
17 #if defined(WIN32)
18
19 #include <windows.h>
20 #include <process.h>
21
22 #elif defined(__GNUC__)
23
24 #include <sys/time.h>
25
26 #endif
27
28 #include "desconst.h"
29 #include "expr_parse.h"
30 #include "hit.h"
31 #include "key.h"
32 #include "log.h"
33 #include "scoreboard.h"
34 #include "synth.h"
35 #include "util.h"
36
37 #ifdef WIN32
38 /* 優先度 */
39 #define PRIO_MIN 0
40 #define PRIO_NORM 0
41 #define PRIO_BELO 1
42 #define PRIO_IDLE 2
43 #define PRIO_MAX 2
44 #define PRIO_DEF 2
45 #endif /* WIN32 */
46
47 /* スレッド数と CPU 数 */
48 #define THREAD_MIN 1
49 #define THREAD_MAX 32
50 int availCPU; /* usage() で使うので大域変数 */
51
52 #define STS_SPAN 5000 /* 速度表示の間隔 (ミリ秒) */
53
54 /* がんばりぐあい */
55 #define GEAR_MAX 10
56 #define GEAR_MIN 1
57 #define GEAR_DEF 10
58 #define GEAR_SLEEP 10
59 #define YOUSUMI 6 /* STS_PAN * YOUSUMI 秒様子見 */
60 int lCntMax;
61
62 static HANDLE mutex_key;
63
64 /* CRYPT64 記述子 */
65 static
66 struct CRYPT64_DESC const *const crypt64_descs[] =
67 {
68 &crypt64_desc,
69 };
70
71 /* 速度評価用 */
72 static int n_cpus;
73 static uint64_t loop_cpu[1024];
74
75 #define USEC_SEC 1000 /* 1秒 */
76
77 static
78 uint64_t
79 usec(void)
80 {
81 uint32_t sec, msec;
82
83 #if !defined(WIN32)
84 struct timeval tv;
85 gettimeofday(&tv, NULL);
86 sec = tv.tv_sec;
87 msec = tv.tv_usec / (1000000 / USEC_SEC);
88 #else
89 struct timeb tm;
90 ftime(&tm);
91 sec = tm.time;
92 msec = tm.millitm / (1000 / USEC_SEC);
93 #endif
94
95 return (uint64_t)USEC_SEC * sec + msec;
96 }
97
98 /***************************************************************
99 *
100 * CPU capabilities を取得
101 * [XXX] あまりにも古いプロセッサのことは考えない。
102 *
103 * a[4] = {EAX,EBX,ECX,EDX}
104 *
105 */
106
107 #if defined(__GNUC__)
108
109 #define cpuid(n,a,b,c,d) \
110 asm("cpuid" \
111 : "=a"(a), "=b"(b), "=c"(c), "=d"(d) \
112 : "a"(n))
113
114 #elif defined(WIN32)
115
116 #define cpuid(n,a,b,c,d) \
117 do {int r[4]; __cpuid(r,n); \
118 (a) = r[0]; (b) = r[1]; (c) = r[2]; (d) = r[3];} while (0)
119
120 #endif
121
122 static
123 unsigned
124 cpuid_getfflags(void)
125 {
126 unsigned a, b, c, d;
127 cpuid(1, a, b, c, d);
128 return d;
129 }
130
131 static
132 int
133 cpuid_issupported(void)
134 {
135 unsigned m = REQUIRED_CAPS;
136 return !((cpuid_getfflags() ^ m) & m);
137 }
138
139 /***************************************************************
140 *
141 * バッチ処理用パケット
142 *
143 */
144
145 static
146 struct PACKET_CRYPT64 *
147 packet_create(int n, /* パケット数 */
148 int tn, /* 末尾要素にて必要なワーク数 */
149 uint8_t const *ini_key)
150 {
151 int i;
152 int siz;
153 void *p;
154 intptr_t a = 128;
155 struct PACKET_CRYPT64 *pkts;
156 assert(IS_POWER2(sizeof(struct PACKET_CRYPT64)));
157 assert(n >= 1);
158
159 siz = (a - 1
160 + (n - 1) * sizeof(struct PACKET_CRYPT64)
161 + offsetof(struct PACKET_CRYPT64, param64.hit[tn]));
162 p = calloc(siz, 1);
163 /* バンダリあわせ */
164 pkts = (struct PACKET_CRYPT64 *)(((intptr_t)p
165 + a - 1)
166 & -a);
167 #if DEBUG>=1
168 fprintf(stderr,
169 "packet(n=%d,tn=%d) %d allocated; %p aligned to %p\n",
170 n, tn,
171 siz, p, pkts);
172 #endif
173
174 /* 内部の初期化
175 コピーして回るのは、厳密には
176 最終要素のケツを破ってしまうことになるので
177 どうせ速度も要求されないしベタコード */
178 for (i = 0; i < n; i++)
179 {
180 int j, k;
181
182 /* t[16] は、内部演算で使用する、all 1 が入っている */
183 memset(&pkts[i].param64.t[T_INV], -1, sizeof(SLICE));
184
185 /* 固定キーの生成 */
186 key_init_sk(&pkts[i].key64);
187
188 /* キースケジュールをここに押し込めておく
189 従来は crypt64.S 内で完結するように引いていた */
190 for (j = 0; j < 28; j++)
191 for (k = 0; k < N_ALU; k++)
192 pkts[i].key64.ks[j].a[k] = sizeof(WS_T) * ks_ls[j];
193
194 /* 念のため、鍵をここで落ち着けておく(不要?) */
195 for (j = 0; j < 8; j++)
196 key_set64(&pkts[i].key64, j, pkts[i].uk.key[j] = ini_key[j], 0, 0x7F);
197 }
198
199 return pkts;
200 }
201
202 /***************************************************************
203 *
204 * thread
205 *
206 */
207
208 #if defined(__GNUC__)
209
210 typedef int32_t ATOMWORD_T;
211
212 #define LOCK_INC(p) \
213 asm volatile ("lock incl %0" \
214 : "=m"(*(p)) \
215 : /*nil*/ \
216 : "memory")
217
218 #define LOCK_DEC(p) \
219 asm volatile ("lock decl %0" \
220 : "=m"(*(p)) \
221 : /*nil*/ \
222 : "memory")
223
224 #define LOCK_CAS(pd,s,r) \
225 ({ ATOMWORD_T a; \
226 asm volatile ("lock cmpxchg %2,%1" \
227 : "=a"(a) \
228 : "m"(*(pd)), "r"(s), "0"(r) \
229 : "memory");a;})
230
231 #define LOCK_CASP(pd,s,r) \
232 ({ void *a; \
233 asm volatile ("lock cmpxchg %2,%1" \
234 : "=a"(a) \
235 : "m"(*(pd)), "r"(s), "0"(r) \
236 : "memory");a;})
237
238 #elif defined(WIN32)
239
240 typedef LONG ATOMWORD_T;
241
242 #define LOCK_INC(p) InterlockedIncrement((LONG *)(p))
243 #define LOCK_DEC(p) InterlockedDecrement((LONG *)(p))
244 #define LOCK_CAS(pd,s,r) InterlockedCompareExchange((LONG *)(pd), s, r)
245 #define LOCK_CASP(pd,s,r) InterlockedCompareExchangePointer((PVOID *)(pd), (PVOID)(s), (PVOID)r)
246
247 #else
248 #error "configuration not implemented"
249 #endif
250
251 #if defined(WIN32)
252
253 typedef DWORD THREAD_TIMEOUT_T;
254
255 #define THREAD_INFINITE INFINITE
256
257 typedef HANDLE THREAD_TH_T;
258
259 #define thread_sleep(n) Sleep(n)
260 #define thread_create(th, proc, arg) {(th) = (HANDLE)_beginthread(proc, 8192, arg);}
261 #define thread_get_tid() GetCurrentThread()
262 #define thread_set_priority(tid,n) SetThreadPriority(tid, n)
263 #define thread_set_affinity(tid,m) SetThreadAffinityMask(tid, (DWORD_PTR)1 << (m))
264
265 #elif defined(_POSIX_SOURCE)
266
267 #include <pthread.h>
268 #include <unistd.h>
269
270 typedef int THREAD_TIMEOUT_T;
271
272 #define THREAD_INFINITE INT_MAX
273
274 #if defined(THREAD_PRIORITY_BELOW_NOROMAL) || defined(THREAD_PRIORITY_IDLE)
275 #error "unsupported implementation"
276 #endif
277
278 #define THREAD_PRIORITY_NORMAL 14
279 #define THREAD_PRIORITY_BELOW_NORMAL 15
280 #define THREAD_PRIORITY_IDLE 16
281
282 typedef pthread_t THREAD_TH_T;
283
284 #define thread_sleep(n) (usleep(1000 * (n)) != EINVAL || sleep((n) / 1000))
285 #define thread_create(th, proc, arg) thread_create_p(&(th), proc, arg)
286
287 static
288 void
289 thread_create_p(pthread_t *th, NORETURN (*proc)(void *), void *param)
290 {
291 pthread_create(th, NULL, (void *(*)(void *))proc, param);
292 }
293
294 #if defined(__linux__)
295
296 /* デフォルトスケジューリングポリシーでは
297 優先度設定したりアイドルスレッド起こしても
298 おもしろくないので、そのへんは今後の研究課題。 */
299
300 #include <linux/unistd.h>
301 _syscall0(pid_t,gettid)
302
303 #define thread_get_tid() gettid()
304
305 static
306 int thread_set_affinity(pid_t tid, int i)
307 {
308 cpu_set_t m;
309 CPU_ZERO(&m);
310 CPU_SET(i, &m);
311 return sched_setaffinity(tid, sizeof(m), &m);
312 }
313
314 #else
315
316 /* POSIX では、スレッド単位のスケジューリングに介入できない。 */
317
318 #endif
319
320 #else
321 #error "configuration not supported"
322 #endif
323
324 struct THREAD_PARAM
325 {
326 /* 以下は共通情報のコピー */
327 CODE_T *code;
328 long code_cmp;
329 unsigned seed;
330
331 /* 以下はスレッド固有 */
332 #ifdef thread_set_priority
333 int pri;
334 #endif
335 };
336
337 static
338 uint64_t
339 thread_avail(void)
340 {
341 #if !USE_MT
342
343 return 0x1U;
344
345 #elif defined(WIN32) /* Win32 API */
346 DWORD_PTR mask, mask_s;
347 if (!GetProcessAffinityMask(GetCurrentProcess(),
348 &mask,
349 &mask_s)
350 || !mask
351 || !mask_s)
352 return 0x1U;
353 #if DEBUG>=1
354 fprintf(stderr,
355 "m=%08X s=%08X\n",
356 (unsigned)mask,
357 (unsigned)mask_s);
358 #endif
359 #if 0
360 if (popcnt64(mask_s) == 1)
361 /* 何も言うまい */;
362 else if (mask == mask_s)
363 fprintf(stderr,
364 "通常の%d倍とはよく言ったものです。\n",
365 popcnt64(mask));
366 else
367 fprintf(stderr,
368 "最高速力の%g倍の力でてきとうにがんばるよ。\n",
369 (double)popcnt64(mask) / popcnt64(mask_s));
370 #endif /* 0 */
371 return mask;
372
373 #elif defined(__linux__) /* sched.h 拡張 */
374
375 int i;
376 uint64_t m = 0;
377 cpu_set_t am;
378 if (sched_getaffinity(getpid(), sizeof(am), &am) < 0)
379 return 0x1U;
380
381 for (i = 0; i < 64 && i < CPU_SETSIZE; i++)
382 if (CPU_ISSET(i, &am))
383 m |= 1ULL << i;
384
385 return m;
386 #else
387
388 /* XXX プロセッサ数を調べ上げてください */
389 return 0x01U;
390
391 #endif
392 }
393
394 static
395 NORETURN
396 thread_crypt64_new(void *a_param)
397 {
398 struct THREAD_PARAM *param = a_param;
399 CODE_T *code = param->code;
400 CODE_T *cmp = code + param->code_cmp;
401 struct KS_KEY key;
402 struct PACKET_CRYPT64 *pkt = packet_create(16, 1024, key.key);
403 uint64_t *ploop;
404 THREAD_TH_T th = thread_get_tid();
405 int lc;
406
407 WaitForSingleObject(mutex_key, INFINITE);
408
409 OLDPRINT( "n_cpus %d\n", n_cpus );
410 ploop = &loop_cpu[n_cpus++];
411
412 srand(usec() ^ param->seed ^ (unsigned)th);
413 key_init(&key);
414 ReleaseMutex(mutex_key);
415
416 #ifdef thread_set_priority
417 thread_set_priority(th, param->pri);
418 #endif
419
420 lc = 0;
421 for (;;)
422 {
423 do
424 {
425 int j;
426 for (j = 0; j < 8; j++)
427 {
428 key_set64(&pkt->key64, j, key.key[j], key.key[j] ^ pkt->uk.key[j], 0);
429 pkt->uk.key[j] = key.key[j];
430 }
431 CALL_CRYPT64(code,
432 &pkt->key64,
433 &pkt->param64);
434 CALL_CMP64(cmp,
435 pkt->param64.hit,
436 pkt->param64.lr);
437 check_hit(pkt, pkt->param64.hit);
438 (*ploop)++;
439 #ifdef ENABLE_GEAR
440 lc++;
441 if ( lCntMax != 0 ) {
442 if ( lc > lCntMax ) {
443 OLDPRINT( "before %I64u\n", usec() );
444 Sleep( (DWORD)GEAR_SLEEP );
445 OLDPRINT( "after %I64u\n", usec() );
446 lc = 0;
447 }
448 }
449 #endif /* ENABLE_GEAR */
450 }
451 while (key_inc(&key, 6, 8) || key_inc(&key, KEY_SHUFFLE_POS, 8));
452 OLDPRINT( "saaaaalt chaaaaange\n" );
453
454 WaitForSingleObject(mutex_key, INFINITE);
455 key_reset(&key, 0);
456 ReleaseMutex(mutex_key);
457 }
458
459 /* notreached */
460 }
461
462 char
463 *bname( char *path )
464 {
465 char *p;
466
467 OLDPRINT( "path <%s>\n", path );
468
469 for ( p = path; *p != '\0'; p++ )
470 ;
471 while ( *p != '/' && *p != '\\' && p != path ) {
472 if ( *p == '.' ) {
473 *p = '\0';
474 }
475 p--;
476 }
477 if ( p != path ) {
478 p++;
479 }
480
481 OLDPRINT( "p <%s>\n", p );
482
483 return( p );
484 }
485
486 void
487 usage( path )
488 char *path;
489 {
490 char *myName;
491
492 myName = bname( path );
493 printf( "まあ、待て屋。魔改造版 (%s)\n", KIND );
494 printf( "%s [-h] [-v] [-p num] [-t num|-m mask] [-g num]\n", myName );
495 printf( " -h : これを表示\n" );
496 printf( " -v : 冗長メッセージ\n" );
497 printf( " -p num : 優先度の設定 ( %d ≦ num ≦ %d, デフォルトは %d )\n",
498 PRIO_MIN, PRIO_MAX, PRIO_DEF );
499 printf( " %d : 通常\n", PRIO_NORM );
500 printf( " %d : 通常以下\n", PRIO_BELO );
501 printf( " %d : 低\n", PRIO_IDLE );
502 printf( " ※ -t と -m は排他 (あとから指定したほうが有効)\n" );
503 printf( " ※ -m で指定できるのは有効な論理 CPU 数分まで\n" );
504 printf( " -t num : 検索スレッド数 ( %d ≦ num ≦ %d, デフォルトは %d )\n",
505 THREAD_MIN, availCPU, availCPU );
506 printf( " -m mask : 実行する CPU を指定するマスク ( 1 ビット ≦ mask のビット数 ≦ %d ビット )\n",
507 THREAD_MAX );
508 printf( " -g num : がんばりぐあい ( %d (やる気なし) ≦ num ≦ %d (フルパワー), デフォルトは、%d )\n", GEAR_MIN, GEAR_MAX, GEAR_DEF );
509 }
510
511 /***************************************************************
512 *
513 * メインループとか
514 *
515 */
516
517 int
518 main(int argc, char *argv[])
519 {
520 int i;
521 CODE_T *code = NULL;
522 long code_cmp;
523 FILE *sfp; /* scoreboard */
524 struct ITREE *root_expr;
525 uint64_t proc_mask;
526 int nThread;
527 struct THREAD_PARAM *threads = NULL;
528 int nthreads;
529 int tn;
530 int aveSpeed, spanSpeed, bestSpeed;
531 int gear;
532 int sCnt;
533 int tmplCntMax;
534 int maxSrchCnt;
535
536 /* 鍵文字列 */
537 struct KS_KEY key;
538
539 #define UPDATE_INTERVAL 8 /* 速度表示の間隔 秒 */
540 struct status {
541 uint64_t startTime; /* 開始時刻 ミリ秒 */
542 uint64_t lastTime; /* 最後に表示した時刻 ミリ秒 */
543 uint64_t loop; /* 総検索個数 */
544 uint64_t lastloop; /* 最後に表示した時の loop */
545 } status;
546 uint64_t curTime;
547
548 if (!cpuid_issupported())
549 {
550 fprintf(stderr, "この環境で走らせることが想定されていません。\n");
551 exit(1);
552 }
553
554 {
555 int optChar;
556 extern char *optarg;
557 extern int optind;
558 char *chPtr;
559 uint64_t availMask;
560 uint64_t pmask;
561 DWORD priority;
562 int verbose;
563
564 availMask = thread_avail(); /* 有効なマスク */
565 availCPU = popcnt64( availMask ); /* 有効な CPU 数 */
566
567 priority = PRIO_DEF;
568 nThread = 0;
569 pmask = 0;
570 verbose = 0;
571 gear = GEAR_DEF;
572
573 /* abcdef ijkl no qrs u wxyz 未使用 */
574 /* gh m p t v 使用済み */
575 while ( (optChar = getopt(argc, argv, "g:hm:p:t:v")) != EOF ) {
576 switch ( optChar ) {
577 case 'g':
578 #ifdef ENABLE_GEAR
579 gear = atoi( optarg );
580 if ( gear < GEAR_MIN || gear > GEAR_MAX ) {
581 usage( argv[0] );
582 exit( 1 );
583 }
584 #else /* ENABLE_GEAR */
585 printf( "-g オプションは無効化されています\n" );
586 #endif /* ENABLE_GEAR */
587 break;
588 case 'h':
589 usage( argv[0] );
590 exit( 0 );
591 break;
592 case 'm':
593 nThread = 0; /* スレッド数とは排他 */
594 if ( strlen( optarg ) > THREAD_MAX ) {
595 usage( argv[0] );
596 exit( 1 );
597 }
598 for ( chPtr = optarg; *chPtr != '\0'; chPtr++ ) {
599 pmask <<= 1;
600 switch ( *chPtr ) {
601 case '0': /* なにもしない */ break;
602 case '1': pmask |= 1; break;
603 default:
604 usage( argv[0] );
605 exit( 1 );
606 break;
607 }
608 }
609 if ( pmask == 0 ) {
610 usage( argv[0] );
611 exit( 1 );
612 }
613 break;
614 case 'p':
615 priority = atoi( optarg );
616 if ( priority < PRIO_MIN || priority > PRIO_MAX ) {
617 usage( argv[0] );
618 exit( 1 );
619 }
620 break;
621 case 't':
622 pmask = 0; /* マスクとは排他 */
623 nThread = atoi( optarg );
624 if ( nThread < THREAD_MIN || nThread > availCPU ) {
625 usage( argv[0] );
626 exit( 1 );
627 }
628 break;
629 case 'v':
630 verbose = 1;
631 break;
632 default:
633 usage( argv[0] );
634 exit( 1 );
635 }
636 }
637
638 if ( pmask == 0 && nThread == 0 ) {
639 /* 指定がなければ、使える CPU 全部 */
640 proc_mask = availMask;
641 }
642
643 if ( pmask != 0 ) {
644 /* マスクで指定の場合、そのまんま */
645 if ( (availMask & pmask) != pmask ) {
646 printf( "そんな CPU はねぇ!\n" );
647 exit( 1 );
648 }
649 proc_mask = pmask;
650 }
651
652 if ( nThread != 0 ) {
653 /* スレッド数の場合、マスクに変換 */
654 proc_mask = 0; /* 念のため */
655 for ( i = 0; i < THREAD_MAX; i++ ) {
656 if ( availMask & 1ULL<<i ) {
657 if ( nThread > 0 ) {
658 proc_mask |= 1ULL<<i;
659 }
660 nThread--;
661 }
662 }
663 }
664
665 if ( gear != GEAR_MAX ) {
666 TIMECAPS tc;
667 if ( timeGetDevCaps( &tc, sizeof( TIMECAPS ) ) == MMSYSERR_NOERROR ) {
668 timeBeginPeriod( tc.wPeriodMin );
669 }
670 }
671
672 nThread = popcnt64( proc_mask );
673 printf( "%d 個の検索スレッドを起動\n", nThread );
674
675 if ( verbose ) {
676 int i;
677 printf( "優先度を" );
678 switch ( priority ) {
679 case PRIO_NORM : printf( "通常" ); break;
680 case PRIO_BELO : printf( "通常以下" ); break;
681 case PRIO_IDLE : printf( "低" ); break;
682 }
683 printf( "に設定\n" );
684 printf( "CPU : " );
685 for ( i = 0; i < THREAD_MAX; i++ ) {
686 if ( proc_mask & 1ULL<<i ) {
687 printf( "%d ", i );
688 }
689 }
690 printf( "を使用\n" );
691 if ( gear == GEAR_MAX ) {
692 printf( "CPU を 100%% 使用\n" );
693 } else {
694 printf( "CPU を %d 割ぐらい使用\n", gear );
695 }
696 }
697
698 #ifdef WIN32
699 switch ( priority ) {
700 case PRIO_NORM : priority = NORMAL_PRIORITY_CLASS; break;
701 case PRIO_BELO : priority = BELOW_NORMAL_PRIORITY_CLASS; break;
702 case PRIO_IDLE : priority = IDLE_PRIORITY_CLASS; break;
703 }
704 SetPriorityClass( GetCurrentProcess(), priority );
705 #endif
706 }
707
708 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
709
710 mutex_key = CreateMutex(NULL, FALSE, NULL);
711
712 /* タゲ読み込み */
713 root_expr = expr_parse("target.txt");
714
715 /* コードを生成・展開
716 起動予定スレッド数に応じて
717 生成するコードを変える */
718 sfp = scoreboard_open();
719 fwrite(crypt64_descs[0]->pro, 1, crypt64_descs[0]->cmp_pro - crypt64_descs[0]->pro, sfp); /* prologue & コアループ */
720
721 #if 0
722 if (0&&proc_mask == 1U)
723 {
724 /* single */
725 code_cmp = 0;
726 }
727 else
728 #endif
729 {
730 /* multi */
731 fwrite(crypt64_descs[0]->ep, 1, crypt64_descs[0]->ep_end - crypt64_descs[0]->ep, sfp); /* epilogue */
732
733 /* 比較器のみを生成(前半) */
734 code_cmp = ftell(sfp);
735 fseek(sfp, (-code_cmp) & 63, SEEK_CUR);
736 code_cmp = ftell(sfp);
737 fwrite(crypt64_descs[0]->pro, 1, crypt64_descs[0]->crypt - crypt64_descs[0]->pro, sfp); /* prologue */
738 }
739
740 /* 比較部を生成 */
741 fwrite(crypt64_descs[0]->cmp_pro, 1, crypt64_descs[0]->cmp_ep - crypt64_descs[0]->cmp_pro, sfp); /* 比較器準備 */
742 tn = synth_synthesize(sfp, root_expr);
743 fwrite(crypt64_descs[0]->cmp_ep, 1, crypt64_descs[0]->ep_end - crypt64_descs[0]->cmp_ep, sfp); /* epilogue */
744
745 /* コードをメモリに貼り付ける */
746 code = scoreboard_map(sfp);
747
748 /* キーの初期化 */
749 WaitForSingleObject(mutex_key, INFINITE);
750 srand(usec());
751 key_init(&key);
752 ReleaseMutex(mutex_key);
753 set_salt(code, crypt64_descs[0], key.key);
754
755 if (log_open("log.txt") != 0) return 1;
756
757 WaitForSingleObject(mutex_key, INFINITE);
758
759 /* 働くおじさんを量産 */
760 nthreads = 0;
761 if (code_cmp)
762 {
763 THREAD_TH_T h;
764 int ots = -1;
765 threads = calloc(2 * popcnt64(proc_mask), sizeof(*threads));
766 for (i = 0; i < 64; i++)
767 if (proc_mask & (1ULL << i))
768 {
769 if (0&&ots < 0)
770 {
771 /* 自分自身のスケジューリング
772 こーゆー系のアプリは低めに設定するのが吉(かも) */
773 #ifdef WIN32
774 h = GetCurrentProcess();
775 SetPriorityClass(h, BELOW_NORMAL_PRIORITY_CLASS);
776 #endif
777 #if defined(thread_set_priority)
778 /* 心の隙間お埋めします */
779 threads[nthreads].code = code;
780 threads[nthreads].code_cmp = code_cmp;
781 threads[nthreads].seed = rand();
782 threads[nthreads].pri = THREAD_PRIORITY_IDLE;
783 thread_create(h, thread_crypt64_new, &threads[nthreads]);
784 nthreads++;
785 #endif
786 if (!code_cmp)
787 break;
788
789 /* 自分自身の残りの設定を、あとでやる */
790 ots = i;
791 }
792 else
793 {
794 /* 他スレッドは、やや低めの優先度で。 */
795 threads[nthreads].code = code;
796 threads[nthreads].code_cmp = code_cmp;
797 threads[nthreads].seed = rand();
798 #ifdef thread_set_priority
799 //threads[nthreads].pri = THREAD_PRIORITY_BELOW_NORMAL;
800 threads[nthreads].pri = THREAD_PRIORITY_LOWEST;
801 #endif
802 thread_create(h, thread_crypt64_new, &threads[nthreads]);
803 #ifdef thread_get_tid
804 thread_set_affinity(h, i);
805 #endif
806 nthreads++;
807 #if 0
808 /* IDLE */
809 threads[nthreads].code = code;
810 threads[nthreads].code_cmp = code_cmp;
811 threads[nthreads].seed = rand();
812 #ifdef thread_set_priority
813 threads[nthreads].pri = THREAD_PRIORITY_IDLE;
814 #endif
815 thread_create(h, thread_crypt64_new, &threads[nthreads]);
816 #ifdef thread_get_tid
817 SetThreadAffinityMask(h, proc_mask);
818 #endif
819 nthreads++;
820 #endif
821 }
822 }
823 #ifdef thread_get_tid
824 if (ots)
825 thread_set_affinity(thread_get_tid(), ots);
826 #endif
827 }
828
829 fprintf(stderr, "検索開始!\n");
830 ReleaseMutex(mutex_key);
831
832 memset( &status, 0, sizeof( struct status ) );
833 status.startTime = status.lastTime = usec();
834
835 bestSpeed = 0;
836 sCnt = 0;
837 lCntMax = 0;
838 maxSrchCnt = 0;
839 for ( ;; ) {
840 uint64_t diffTime;
841 uint64_t spanLoop;
842
843 Sleep(STS_SPAN);
844
845 #ifdef OLDEBUG
846 putchar( '\n' );
847 #endif /* DEBUG */
848 status.loop = 0;
849 for (i = 0; i < n_cpus; i++) {
850 OLDPRINT( "loop_cpu[%d] %d\n", i, loop_cpu[i] );
851 status.loop += loop_cpu[i];
852 }
853 status.loop *= N_ALU * ALU_BITS;
854
855 spanLoop = status.loop - status.lastloop;
856 if ( spanLoop > maxSrchCnt ) {
857 maxSrchCnt = spanLoop;
858 }
859
860 curTime = usec();
861
862 /* 通算 (単位 trips/usec = ktrips/sec) */
863 diffTime = curTime - status.startTime;
864 aveSpeed = status.loop / diffTime;
865
866 /* 区間 (単位 trips/usec = ktrips/sec) */
867 diffTime = curTime - status.lastTime;
868 spanSpeed = spanLoop / diffTime;
869
870 /* 最速 */
871 if ( spanSpeed > bestSpeed ) {
872 bestSpeed = spanSpeed;
873 if ( gear != GEAR_MAX ) {
874 tmplCntMax = ((maxSrchCnt / (N_ALU * ALU_BITS)) * gear / 10) / ((STS_SPAN - (STS_SPAN * gear / 10)) / GEAR_SLEEP) / nThread;
875 }
876 }
877
878 if ( gear != GEAR_MAX ) {
879 if ( sCnt == YOUSUMI && lCntMax == 0 ) {
880 if ( tmplCntMax < 1 ) {
881 lCntMax = 1;
882 } else {
883 lCntMax = tmplCntMax;
884 }
885 OLDPRINT( "lCntMax = %d\n", lCntMax );
886 printf( "\nCPU 使用率制限モード開始\n" );
887 }
888 }
889 sCnt++;
890
891 status.lastTime = curTime;
892 status.lastloop = status.loop;
893
894 fprintf(stderr,
895 "通算 %dktrips/s [区間 %dktrips/s] {最速 %dktrips/s}\r",
896 aveSpeed, spanSpeed, bestSpeed );
897 }
898
899 return 0;
900 }
901
902 /*
903 * Local Variables:
904 * tab-width: 4
905 * End:
906 *
907 * EOF */

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Rev URL

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26