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:
parent
57e942145c
commit
c94cfebb7e
3 changed files with 12 additions and 12 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue