Reduce lock contention in idle_loop
authorMarco Costalba <mcostalba@gmail.com>
Fri, 3 Feb 2012 12:18:51 +0000 (13:18 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 3 Feb 2012 12:43:58 +0000 (13:43 +0100)
Release split point lock before to wake up
master thread. This seems to increase speed
in case "sleeping threads" are used:

After 7792 games with 4 threads at very fast TC (2"+0.05)
Mod vs Orig 1722 - 1627 - 4443 ELO +4 (+- 5.1)

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/search.cpp
src/thread.cpp
src/thread.h

index 49a7b4da8883ddcd76cebcde2e15bab6a15b32ae..8823e98f45ec8a581b6c45529848afd3a1755c91 100644 (file)
@@ -1873,6 +1873,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
 
           Stack ss[MAX_PLY_PLUS_2];
           Position pos(*sp->pos, threadID);
+          int master = sp->master;
 
           memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
           (ss+1)->sp = sp;
@@ -1894,17 +1895,17 @@ void Thread::idle_loop(SplitPoint* sp_master) {
           sp->slavesMask &= ~(1ULL << threadID);
           sp->nodes += pos.nodes_searched();
 
-          // Wake up master thread so to allow it to return from the idle loop in
-          // case we are the last slave of the split point.
-          if (   Threads.use_sleeping_threads()
-              && threadID != sp->master
-              && !Threads[sp->master].is_searching)
-              Threads[sp->master].wake_up();
-
           // After releasing the lock we cannot access anymore any SplitPoint
           // related data in a reliably way becuase it could have been released
           // under our feet by the sp master.
           lock_release(sp->lock);
+
+          // Wake up master thread so to allow it to return from the idle loop in
+          // case we are the last slave of the split point.
+          if (   Threads.use_sleeping_threads()
+              && threadID != master
+              && !Threads[master].is_searching)
+              Threads[master].wake_up();
       }
   }
   // In helpful master concept a master can help only a sub-tree of its split
index 8a8e7199d43e00c42b3c5405ea95ace53af93d40..3eb393bc4ec7226ee131dd48d1773763fe591cde 100644 (file)
@@ -274,8 +274,8 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
   // Try to allocate available threads and ask them to start searching setting
   // is_searching flag. This must be done under lock protection to avoid concurrent
   // allocation of the same slave by another master.
+  lock_grab(sp->lock);
   lock_grab(splitLock);
-  lock_grab(sp->lock); // To protect sp->slaves_mask
 
   for (int i = 0; i < activeThreads && !Fake; i++)
       if (threads[i].is_available_to(master))
@@ -294,8 +294,8 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
   masterThread.splitPoint = sp;
   masterThread.activeSplitPoints++;
 
-  lock_release(sp->lock);
   lock_release(splitLock);
+  lock_release(sp->lock);
 
   // Everything is set up. The master thread enters the idle loop, from which
   // it will instantly launch a search, because its is_searching flag is set.
@@ -308,16 +308,16 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
   // We have returned from the idle loop, which means that all threads are
   // finished. Note that setting is_searching and decreasing activeSplitPoints is
   // done under lock protection to avoid a race with Thread::is_available_to().
-  lock_grab(splitLock);
   lock_grab(sp->lock); // To protect sp->nodes
+  lock_grab(splitLock);
 
   masterThread.is_searching = true;
   masterThread.activeSplitPoints--;
   masterThread.splitPoint = sp->parent;
   pos.set_nodes_searched(pos.nodes_searched() + sp->nodes);
 
-  lock_release(sp->lock);
   lock_release(splitLock);
+  lock_release(sp->lock);
 
   return sp->bestValue;
 }
index 10d120140843dcd17b1c6977729526a8ae7f4e7d..c93bcb4d9f8074d0c0c76b5d8afc4d6ef1c00704 100644 (file)
@@ -40,7 +40,6 @@ struct SplitPoint {
   Depth depth;
   Value beta;
   int nodeType;
-  int ply;
   int master;
   Move threatMove;