Implement hash table
authorH.G. Muller <h.g.muller@hccnet.nl>
Mon, 27 May 2013 20:24:29 +0000 (22:24 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Mon, 21 Oct 2013 08:40:24 +0000 (10:40 +0200)
hachu.c

diff --git a/hachu.c b/hachu.c
index 04b95f3..97cab1b 100644 (file)
--- a/hachu.c
+++ b/hachu.c
 #define PATH level==0 || path[0] == 0xc4028 &&  (level==1 /*|| path[1] == 0x75967 && (level == 2 || path[2] == 0x3400b && (level == 3))*/)\r
 //define PATH 0\r
 \r
+#define HASH\r
+\r
 #include <stdio.h>\r
 #include <stdlib.h>\r
 #include <string.h>\r
 #include <signal.h>\r
 #include <time.h>\r
+#include <stdint.h>\r
 \r
 #ifdef WIN32 \r
 #    include <windows.h>\r
@@ -79,6 +82,21 @@ void pboard(int *b);
 void pbytes(unsigned char *b);\r
 \r
 typedef struct {\r
+  int lock[5];\r
+  int move[5];\r
+  short int score[5];\r
+  char depth[5];\r
+  char flag[5];\r
+  char age[4];\r
+} HashBucket;\r
+\r
+HashBucket *hashTable;\r
+int hashMask;\r
+\r
+#define H_UPPER 2\r
+#define H_LOWER 1\r
+\r
+typedef struct {\r
   char *name, *promoted;\r
   int value;\r
   signed char range[8];\r
@@ -1556,6 +1574,9 @@ Search (int alpha, int beta, int difEval, int depth, int oldPromo, int promoSupp
   int score, bestScore, curEval, iterAlpha;\r
   Move move, nullMove;\r
   UndoInfo tb;\r
+#ifdef HASH\r
+  Move hashMove; int index, nr, hit;\r
+#endif\r
 if(PATH) /*pboard(board),pmap(attacks, BLACK),*/printf("search(%d) {%d,%d} eval=%d, stm=%d\n",depth,alpha,beta,difEval,stm),fflush(stdout);\r
   xstm = stm ^ WHITE;\r
 //printf("map made\n");fflush(stdout);\r
@@ -1578,9 +1599,27 @@ if(PATH) /*pboard(board),pmap(attacks, BLACK),*/printf("search(%d) {%d,%d} eval=
   nodes++;\r
   pv[pvPtr++] = 0; // start empty PV, directly behind PV of parent\r
 \r
+\r
   firstMove = curMove = sorted = msp += 50; // leave 50 empty slots in front of move list\r
-  tb.fireMask = phase = 0; iterDep=1; replyDep = (depth < 1 ? depth : 1) - 1;\r
-  do {\r
+  iterDep = 0; tb.fireMask = phase = 0;\r
+\r
+#ifdef HASH\r
+  index = hashKeyL & hashMask; nr = hashKeyL >> 30; hit = -1;\r
+  if(hashTable[index].lock[nr] == hashKeyH) hit = nr; else\r
+  if(hashTable[index].lock[4]  == hashKeyH) hit = 4;\r
+  if(hit >= 0) {\r
+    bestScore = hashTable[index].score[hit];\r
+    if((bestScore <= alpha || hashTable[index].flag[hit] & H_LOWER) &&\r
+       (bestScore >= beta  || hashTable[index].flag[hit] & H_UPPER)   ) {\r
+      iterDep = hashTable[index].depth[hit];\r
+    }\r
+  } else { // decide on replacement\r
+    if(depth >= hashTable[index].depth[nr]) hit = nr; else hit = 4;\r
+  }\r
+#endif\r
+\r
+  replyDep = (depth < 1 ? depth : iterDep < 1 ? 1 : iterDep);\r
+  while(++iterDep <= depth) {\r
 if(flag && depth>= 0) printf("iter %d:%d\n", depth,iterDep),fflush(stdout);\r
     iterAlpha = alpha; bestScore = -INF; bestMoveNr = 0; resDep = 60;\r
     for(curMove = firstMove; ; curMove++) { // loop over moves\r
@@ -1605,6 +1644,12 @@ if(flag && depth>= 0) printf("phase=%d: first/curr/last = %d / %d / %d\n", phase
 //if(PATH) printf("mask=%x\n",tb.fireMask),pbytes(fireBoard);\r
            phase = 1;\r
          case 1: // hash move\r
+#ifdef HASH\r
+           if(hashMove) {\r
+             moveStack[sorted = msp++] = hashMove;\r
+             goto extractMove;\r
+           }\r
+#endif\r
            phase = 2;\r
          case 2: // capture-gen init\r
            nextVictim = xstm;\r
@@ -1771,7 +1816,17 @@ if(PATH) printf("%d:%2d:%d %3d %6x %-10s %6d %6d\n", level, depth, iterDep, curM
       if(GetTickCount() - startTime > tlim1) break; // do not start iteration we can (most likely) not finish\r
     }\r
     replyDep = iterDep;\r
-  } while(++iterDep <= depth); // next depth\r
+#ifdef HASH\r
+    // hash store\r
+    hashTable[index].lock[hit]  = hashKeyH;\r
+    hashTable[index].depth[hit] = iterDep;\r
+    hashTable[index].flag[hit]  = (bestScore < beta) * H_UPPER;\r
+    if(bestScore > alpha) {\r
+      hashTable[index].flag[hit] |= H_LOWER;\r
+      hashTable[index].move[hit]  = bestMoveNr ? moveStack[bestMoveNr] : 0;\r
+    } else hashTable[index].move[hit] = 0;\r
+#endif\r
+  } // next depth\r
   retMSP = msp;\r
   retFirst = firstMove;\r
   msp = oldMSP; // pop move list\r
@@ -1958,6 +2013,19 @@ Setup2 (char *fen)
 void\r
 SetMemorySize (int n)\r
 {\r
+#ifdef HASH\r
+  static HashBucket *realHash;\r
+  static int oldSize;\r
+  int m = 1;\r
+  intptr_t l;\r
+  if(n != oldSize) {\r
+    if(oldSize) free(realHash);\r
+    while(m*sizeof(HashBucket) <= n*512) m <<= 1;\r
+    m *= 1024; hashMask = m - 1;\r
+    realHash = calloc(m + 1, sizeof(HashBucket));\r
+    l = (intptr_t) realHash; hashTable = (HashBucket*) (l & ~63); // align with cache line\r
+  }\r
+#endif\r
 }\r
 \r
 char *\r