スレッド数などの負荷調整関連を実装。
@@ -54,6 +54,16 @@ | ||
54 | 54 | return popcnt32(x) + popcnt32(x >> 32); |
55 | 55 | } |
56 | 56 | |
57 | +#ifdef DEBUG | |
58 | + #define DPRINT( ... ) \ | |
59 | + printf( "[DBG] %s:%d ", __FILE__, __LINE__ ); \ | |
60 | + printf( __VA_ARGS__ ) | |
61 | +#else | |
62 | + #define DPRINT( ... ) | |
63 | +#endif | |
64 | + | |
65 | +#define OLDPRINT( ... ) | |
66 | + | |
57 | 67 | #endif /* UTIL_H__ */ |
58 | 68 | |
59 | 69 | /* |
@@ -34,6 +34,21 @@ | ||
34 | 34 | #include "synth.h" |
35 | 35 | #include "util.h" |
36 | 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 | + | |
37 | 52 | static HANDLE mutex_key; |
38 | 53 | |
39 | 54 | /* CRYPT64 記述子 */ |
@@ -331,6 +346,7 @@ | ||
331 | 346 | (unsigned)mask, |
332 | 347 | (unsigned)mask_s); |
333 | 348 | #endif |
349 | +#if 0 | |
334 | 350 | if (popcnt64(mask_s) == 1) |
335 | 351 | /* 何も言うまい */; |
336 | 352 | else if (mask == mask_s) |
@@ -341,6 +357,7 @@ | ||
341 | 357 | fprintf(stderr, |
342 | 358 | "最高速力の%g倍の力でてきとうにがんばるよ。\n", |
343 | 359 | (double)popcnt64(mask) / popcnt64(mask_s)); |
360 | +#endif /* 0 */ | |
344 | 361 | return mask; |
345 | 362 | |
346 | 363 | #elif defined(__linux__) /* sched.h 拡張 */ |
@@ -408,6 +425,7 @@ | ||
408 | 425 | *ploop += N_ALU * ALU_BITS; |
409 | 426 | } |
410 | 427 | while (key_inc(&key, 6, 8) || key_inc(&key, KEY_SHUFFLE_POS, 8)); |
428 | + DPRINT( "saaaaalt chaaaaange\n" ); | |
411 | 429 | |
412 | 430 | WaitForSingleObject(mutex_key, INFINITE); |
413 | 431 | key_reset(&key, 0); |
@@ -417,6 +435,54 @@ | ||
417 | 435 | /* notreached */ |
418 | 436 | } |
419 | 437 | |
438 | +char | |
439 | +*bname( char *path ) | |
440 | +{ | |
441 | + char *p; | |
442 | + | |
443 | + OLDPRINT( "path <%s>\n", path ); | |
444 | + | |
445 | + for ( p = path; *p != '\0'; p++ ) | |
446 | + ; | |
447 | + while ( *p != '/' && *p != '\\' && p != path ) { | |
448 | + if ( *p == '.' ) { | |
449 | + *p = '\0'; | |
450 | + } | |
451 | + p--; | |
452 | + } | |
453 | + if ( p != path ) { | |
454 | + p++; | |
455 | + } | |
456 | + | |
457 | + OLDPRINT( "p <%s>\n", p ); | |
458 | + | |
459 | + return( p ); | |
460 | +} | |
461 | + | |
462 | +void | |
463 | +usage( path ) | |
464 | +char *path; | |
465 | +{ | |
466 | + char *myName; | |
467 | + | |
468 | + myName = bname( path ); | |
469 | + printf( "まあ、待て屋。魔改造版 (%s)\n", KIND ); | |
470 | + printf( "%s [-h] [-v] [-p num] [-t num|-m mask]\n", myName ); | |
471 | + printf( " -h : これを表示\n" ); | |
472 | + printf( " -v : 冗長メッセージ\n" ); | |
473 | + printf( " -p num : 優先度の設定 ( %d ≦ num ≦ %d, デフォルトは %d )\n", | |
474 | + PRIO_MIN, PRIO_MAX, PRIO_DEF ); | |
475 | + printf( " %d : 通常\n", PRIO_NORM ); | |
476 | + printf( " %d : 通常以下\n", PRIO_BELO ); | |
477 | + printf( " %d : 低\n", PRIO_IDLE ); | |
478 | + printf( " ※ -t と -m は排他 (あとから指定したほうが有効)\n" ); | |
479 | + printf( " ※ -m で指定できるのは有効な論理 CPU 数分まで\n" ); | |
480 | + printf( " -t num : 検索スレッド数 ( %d ≦ num ≦ %d, デフォルトは %d )\n", | |
481 | + THREAD_MIN, availCPU, availCPU ); | |
482 | + printf( " -m mask : 実行する CPU を指定するマスク ( 1 ビット ≦ mask のビット数 ≦ %d ビット )\n", | |
483 | + THREAD_MAX ); | |
484 | +} | |
485 | + | |
420 | 486 | /*************************************************************** |
421 | 487 | * |
422 | 488 | * メインループとか |
@@ -464,6 +530,135 @@ | ||
464 | 530 | exit(1); |
465 | 531 | } |
466 | 532 | |
533 | +{ | |
534 | + int optChar; | |
535 | + extern char *optarg; | |
536 | + extern int optind; | |
537 | + char *chPtr; | |
538 | + uint64_t availMask; | |
539 | + int nThread; | |
540 | + uint64_t pmask; | |
541 | + DWORD priority; | |
542 | + int verbose; | |
543 | + | |
544 | + availMask = thread_avail(); /* 有効なマスク */ | |
545 | + availCPU = popcnt64( availMask ); /* 有効な CPU 数 */ | |
546 | + | |
547 | + priority = PRIO_DEF; | |
548 | + nThread = 0; | |
549 | + pmask = 0; | |
550 | + verbose = 0; | |
551 | + | |
552 | + /* abcdefg ijkl no qrs u wxyz 未使用 */ | |
553 | + /* h m p t v 使用済み */ | |
554 | + while ( (optChar = getopt(argc, argv, "hm:p:t:v")) != EOF ) { | |
555 | + switch ( optChar ) { | |
556 | + case 'h': | |
557 | + usage( argv[0] ); | |
558 | + exit( 0 ); | |
559 | + break; | |
560 | + case 'm': | |
561 | + nThread = 0; /* スレッド数とは排他 */ | |
562 | + if ( strlen( optarg ) > THREAD_MAX ) { | |
563 | + usage( argv[0] ); | |
564 | + exit( 1 ); | |
565 | + } | |
566 | + for ( chPtr = optarg; *chPtr != '\0'; chPtr++ ) { | |
567 | + pmask <<= 1; | |
568 | + switch ( *chPtr ) { | |
569 | + case '0': /* なにもしない */ break; | |
570 | + case '1': pmask |= 1; break; | |
571 | + default: | |
572 | + usage( argv[0] ); | |
573 | + exit( 1 ); | |
574 | + break; | |
575 | + } | |
576 | + } | |
577 | + if ( pmask == 0 ) { | |
578 | + usage( argv[0] ); | |
579 | + exit( 1 ); | |
580 | + } | |
581 | + break; | |
582 | + case 'p': | |
583 | + priority = atoi( optarg ); | |
584 | + if ( priority < PRIO_MIN || priority > PRIO_MAX ) { | |
585 | + usage( argv[0] ); | |
586 | + exit( 1 ); | |
587 | + } | |
588 | + break; | |
589 | + case 't': | |
590 | + pmask = 0; /* マスクとは排他 */ | |
591 | + nThread = atoi( optarg ); | |
592 | + if ( nThread < THREAD_MIN || nThread > availCPU ) { | |
593 | + usage( argv[0] ); | |
594 | + exit( 1 ); | |
595 | + } | |
596 | + break; | |
597 | + case 'v': | |
598 | + verbose = 1; | |
599 | + break; | |
600 | + default: | |
601 | + usage( argv[0] ); | |
602 | + exit( 1 ); | |
603 | + } | |
604 | + } | |
605 | + | |
606 | + if ( pmask == 0 && nThread == 0 ) { | |
607 | + /* 指定がなければ、使える CPU 全部 */ | |
608 | + proc_mask = availMask; | |
609 | + } | |
610 | + | |
611 | + if ( pmask != 0 ) { | |
612 | + /* マスクで指定の場合、そのまんま */ | |
613 | + if ( (availMask & pmask) != pmask ) { | |
614 | + printf( "そんな CPU はねぇ!\n" ); | |
615 | + exit( 1 ); | |
616 | + } | |
617 | + proc_mask = pmask; | |
618 | + } | |
619 | + | |
620 | + if ( nThread != 0 ) { | |
621 | + /* スレッド数の場合、マスクに変換 */ | |
622 | + proc_mask = 0; /* 念のため */ | |
623 | + for ( i = 0; i < THREAD_MAX; i++ ) { | |
624 | + if ( availMask & 1ULL<<i ) { | |
625 | + if ( nThread > 0 ) { | |
626 | + proc_mask |= 1ULL<<i; | |
627 | + } | |
628 | + nThread--; | |
629 | + } | |
630 | + } | |
631 | + } | |
632 | + | |
633 | + printf( "%d 個の検索スレッドを起動\n", popcnt64( proc_mask ) ); | |
634 | + if ( verbose ) { | |
635 | + int i; | |
636 | + printf( "優先度を" ); | |
637 | + switch ( priority ) { | |
638 | + case PRIO_NORM : printf( "通常" ); break; | |
639 | + case PRIO_BELO : printf( "通常以下" ); break; | |
640 | + case PRIO_IDLE : printf( "低" ); break; | |
641 | + } | |
642 | + printf( "に設定\n" ); | |
643 | + printf( "CPU : " ); | |
644 | + for ( i = 0; i < THREAD_MAX; i++ ) { | |
645 | + if ( proc_mask & 1ULL<<i ) { | |
646 | + printf( "%d ", i ); | |
647 | + } | |
648 | + } | |
649 | + printf( "を使用\n" ); | |
650 | + } | |
651 | + | |
652 | +#ifdef WIN32 | |
653 | + switch ( priority ) { | |
654 | + case PRIO_NORM : priority = NORMAL_PRIORITY_CLASS; break; | |
655 | + case PRIO_BELO : priority = BELOW_NORMAL_PRIORITY_CLASS; break; | |
656 | + case PRIO_IDLE : priority = IDLE_PRIORITY_CLASS; break; | |
657 | + } | |
658 | + SetPriorityClass( GetCurrentProcess(), priority ); | |
659 | +#endif | |
660 | +} | |
661 | + | |
467 | 662 | assert((1 << N_STRIDE) == N_ALU * ALU_BITS); |
468 | 663 | |
469 | 664 | mutex_key = CreateMutex(NULL, FALSE, NULL); |
@@ -476,7 +671,6 @@ | ||
476 | 671 | 生成するコードを変える */ |
477 | 672 | sfp = scoreboard_open(); |
478 | 673 | fwrite(crypt64_descs[0]->pro, 1, crypt64_descs[0]->cmp_pro - crypt64_descs[0]->pro, sfp); /* prologue & コアループ */ |
479 | - proc_mask = thread_avail(); | |
480 | 674 | |
481 | 675 | #if 0 |
482 | 676 | if (0&&proc_mask == 1U) |