Use threads to clear the TT faster.
authorRodrigo Exterckötter Tjäder <rodrigo@tjader.xyz>
Mon, 14 May 2018 17:52:21 +0000 (14:52 -0300)
committerStéphane Nicolet <cassio@free.fr>
Wed, 30 May 2018 11:07:18 +0000 (13:07 +0200)
Stockfish currently takes a while to clear the TT when using larger hash sizes.

On one machine with 128 GB hash it takes about 50 seconds with a single thread,
allowing it to use all allocated cores brought that time down to 4 seconds on
some Linux systems. The patch was further tested on Windows and refined with
NUMA binding of the hash initializing threads (we refer to pull request #1601
for the complete discussion and the speed measurements).

Closes https://github.com/official-stockfish/Stockfish/pull/1601

No functional change

src/tt.cpp

index 25f1cd0..5fa1290 100644 (file)
 
 #include <cstring>   // For std::memset
 #include <iostream>
+#include <thread>
 
 #include "bitboard.h"
+#include "misc.h"
 #include "tt.h"
+#include "uci.h"
 
 TranspositionTable TT; // Our global transposition table
 
@@ -58,12 +61,28 @@ void TranspositionTable::resize(size_t mbSize) {
 /// TranspositionTable::clear() overwrites the entire transposition table
 /// with zeros. It is called whenever the table is resized, or when the
 /// user asks the program to clear the table (from the UCI interface).
+/// It starts as many threads as allowed by the Threads option.
 
 void TranspositionTable::clear() {
 
-  std::memset(table, 0, clusterCount * sizeof(Cluster));
-}
+  const size_t stride = clusterCount / Options["Threads"];
+  std::vector<std::thread> threads;
+  for (size_t idx = 0; idx < Options["Threads"]; idx++)
+  {
+      const size_t start =  stride * idx,
+                   len =    idx != Options["Threads"] - 1 ?
+                            stride :
+                            clusterCount - start;
+      threads.push_back(std::thread([this, idx, start, len]() {
+          if (Options["Threads"] >= 8)
+              WinProcGroup::bindThisThread(idx);
+          std::memset(&table[start], 0, len * sizeof(Cluster));
+      }));
+  }
 
+  for (std::thread& th: threads)
+      th.join();
+}
 
 /// TranspositionTable::probe() looks up the current position in the transposition
 /// table. It returns true and a pointer to the TTEntry if the position is found.