From e4ec6e22eed1129dd96997ef9f5017a1b34357eb Mon Sep 17 00:00:00 2001 From: Calcitem Date: Sun, 19 Apr 2020 02:53:04 +0800 Subject: [PATCH] =?UTF-8?q?prefetch:=20=E5=A2=9E=E5=8A=A0=E7=BD=AE?= =?UTF-8?q?=E6=8D=A2=E8=A1=A8=E7=9A=84=E9=A2=84=E8=AF=BB=E5=8F=96=E7=89=B9?= =?UTF-8?q?=E6=80=A7=E4=BD=86=E6=9A=82=E4=B8=8D=E5=90=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对于自对弈,因为局面模拟走下一步,入栈出栈花了7s时间, 而 prefetch 预读置换表,节5s时间,总时间还是增加2s。 故暂不启用。 --- include/config.h | 2 ++ src/ai/search.cpp | 11 +++++++++++ src/ai/tt.cpp | 5 +++++ src/ai/tt.h | 3 +++ src/base/hashmap.h | 18 ++++++++++++++++++ 5 files changed, 39 insertions(+) diff --git a/include/config.h b/include/config.h index 382fd48d..c1ad8ac0 100644 --- a/include/config.h +++ b/include/config.h @@ -95,6 +95,8 @@ //#define TRANSPOSITION_TABLE_DEBUG #endif +//#define PREFETCH_SUPPORT + //#define USE_STD_STACK //#define RAPID_GAME diff --git a/src/ai/search.cpp b/src/ai/search.cpp index 862d57b0..1e359f54 100644 --- a/src/ai/search.cpp +++ b/src/ai/search.cpp @@ -863,6 +863,17 @@ value_t AIAlgorithm::search(depth_t depth, value_t alpha, value_t beta, Node *no int nchild = node->childrenSize; for (int i = 0; i < nchild; i++) { +#ifdef PREFETCH_SUPPORT + if (i + 1 < nchild) + { + stashPosition(); + doMove(node->children[i + 1]->move); + hash_t nextHash = st->getHash(); + TT::prefetchHash(nextHash); + undoMove(); + } +#endif // PREFETCH_SUPPORT + // 棋局入栈保存,以便后续撤销着法 stashPosition(); diff --git a/src/ai/tt.cpp b/src/ai/tt.cpp index e17df4ba..9e537217 100644 --- a/src/ai/tt.cpp +++ b/src/ai/tt.cpp @@ -112,6 +112,11 @@ bool TT::findHash(const hash_t &hash, TT::HashValue &hashValue) #endif } +void TT::prefetchHash(const hash_t &hash) +{ + transpositionTable.prefetch(hash); +} + int TT::recordHash(const value_t &value, const depth_t &depth, const TT::HashType &type, diff --git a/src/ai/tt.h b/src/ai/tt.h index 5356628c..6c7aee7c 100644 --- a/src/ai/tt.h +++ b/src/ai/tt.h @@ -82,6 +82,9 @@ public: // 清空置换表 static void clear(); + + // 预读取 + static void prefetchHash(const hash_t &hash); }; using TT = TranspositionTable; diff --git a/src/base/hashmap.h b/src/base/hashmap.h index 7ad59b62..e31f5b7b 100644 --- a/src/base/hashmap.h +++ b/src/base/hashmap.h @@ -76,6 +76,24 @@ namespace CTSL //Concurrent Thread Safe Library #endif } + void prefetch(const K &key) + { + K hashValue = hashFn(key) & (hashSize - 1); + const V *addr = &(hashTable[hashValue].getValue()); + +# if defined(__INTEL_COMPILER) + // This hack prevents prefetches from being optimized away by + // Intel compiler. Both MSVC and gcc seem not be affected by this. + __asm__(""); +# endif + +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) + _mm_prefetch((const char *)addr, _MM_HINT_T0); +# else + __builtin_prefetch(addr); +# endif + } + //Function to insert into the hash map. //If key already exists, update the value, else insert a new node in the bucket with the pair. K insert(const K &key, const V &value)