1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-11 19:49:14 +00:00

Reduce lock contention in idle_loop

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>
This commit is contained in:
Marco Costalba 2012-02-03 13:18:51 +01:00
parent 57e942145c
commit c94cfebb7e
3 changed files with 12 additions and 12 deletions

View file

@ -1873,6 +1873,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
Stack ss[MAX_PLY_PLUS_2]; Stack ss[MAX_PLY_PLUS_2];
Position pos(*sp->pos, threadID); Position pos(*sp->pos, threadID);
int master = sp->master;
memcpy(ss, sp->ss - 1, 4 * sizeof(Stack)); memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
(ss+1)->sp = sp; (ss+1)->sp = sp;
@ -1894,17 +1895,17 @@ void Thread::idle_loop(SplitPoint* sp_master) {
sp->slavesMask &= ~(1ULL << threadID); sp->slavesMask &= ~(1ULL << threadID);
sp->nodes += pos.nodes_searched(); 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 // After releasing the lock we cannot access anymore any SplitPoint
// related data in a reliably way becuase it could have been released // related data in a reliably way becuase it could have been released
// under our feet by the sp master. // under our feet by the sp master.
lock_release(sp->lock); 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 // In helpful master concept a master can help only a sub-tree of its split

View 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 // 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 // is_searching flag. This must be done under lock protection to avoid concurrent
// allocation of the same slave by another master. // allocation of the same slave by another master.
lock_grab(sp->lock);
lock_grab(splitLock); lock_grab(splitLock);
lock_grab(sp->lock); // To protect sp->slaves_mask
for (int i = 0; i < activeThreads && !Fake; i++) for (int i = 0; i < activeThreads && !Fake; i++)
if (threads[i].is_available_to(master)) 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.splitPoint = sp;
masterThread.activeSplitPoints++; masterThread.activeSplitPoints++;
lock_release(sp->lock);
lock_release(splitLock); lock_release(splitLock);
lock_release(sp->lock);
// Everything is set up. The master thread enters the idle loop, from which // 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. // 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 // We have returned from the idle loop, which means that all threads are
// finished. Note that setting is_searching and decreasing activeSplitPoints is // finished. Note that setting is_searching and decreasing activeSplitPoints is
// done under lock protection to avoid a race with Thread::is_available_to(). // 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(sp->lock); // To protect sp->nodes
lock_grab(splitLock);
masterThread.is_searching = true; masterThread.is_searching = true;
masterThread.activeSplitPoints--; masterThread.activeSplitPoints--;
masterThread.splitPoint = sp->parent; masterThread.splitPoint = sp->parent;
pos.set_nodes_searched(pos.nodes_searched() + sp->nodes); pos.set_nodes_searched(pos.nodes_searched() + sp->nodes);
lock_release(sp->lock);
lock_release(splitLock); lock_release(splitLock);
lock_release(sp->lock);
return sp->bestValue; return sp->bestValue;
} }

View file

@ -40,7 +40,6 @@ struct SplitPoint {
Depth depth; Depth depth;
Value beta; Value beta;
int nodeType; int nodeType;
int ply;
int master; int master;
Move threatMove; Move threatMove;