From a091ae4cc8ec12fc43a5e6b26d7e82125f7eff3e Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sat, 15 Mar 2014 23:43:35 +0100 Subject: [PATCH] Split also if no slaves are found Because we test for available slaves before entering split(), we almost always allocate a slave, only in the rare case of a race (less then 2% of cases) this is not true, but to special case this occurrence is not worth the added complexity. bench: 7451319 --- src/thread.cpp | 54 ++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/src/thread.cpp b/src/thread.cpp index 60c0ce71..cdc94ee0 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -296,41 +296,35 @@ void Thread::split(Position& pos, const Stack* ss, Value alpha, Value beta, Valu activeSplitPoint = &sp; activePosition = NULL; - int slavesCnt = 1; // This thread is always included - Thread* slave; - - while (!Fake && (slave = Threads.available_slave(this)) != NULL) - { - ++slavesCnt; - sp.slavesMask |= 1ULL << slave->idx; - slave->activeSplitPoint = &sp; - slave->searching = true; // Slave leaves idle_loop() - slave->notify_one(); // Could be sleeping - } + if (!Fake) + for (Thread* slave; (slave = Threads.available_slave(this)) != NULL; ) + { + sp.slavesMask |= 1ULL << slave->idx; + slave->activeSplitPoint = &sp; + slave->searching = true; // Slave leaves idle_loop() + slave->notify_one(); // Could be sleeping + } // Everything is set up. The master thread enters the idle loop, from which // it will instantly launch a search, because its 'searching' flag is set. // The thread will return from the idle loop when all slaves have finished // their work at this split point. - if (slavesCnt > 1 || Fake) - { - sp.mutex.unlock(); - Threads.mutex.unlock(); - - Thread::idle_loop(); // Force a call to base class idle_loop() - - // In the helpful master concept, a master can help only a sub-tree of its - // split point and because everything is finished here, it's not possible - // for the master to be booked. - assert(!searching); - assert(!activePosition); - - // We have returned from the idle loop, which means that all threads are - // finished. Note that setting 'searching' and decreasing splitPointsSize is - // done under lock protection to avoid a race with Thread::available_to(). - Threads.mutex.lock(); - sp.mutex.lock(); - } + sp.mutex.unlock(); + Threads.mutex.unlock(); + + Thread::idle_loop(); // Force a call to base class idle_loop() + + // In the helpful master concept, a master can help only a sub-tree of its + // split point and because everything is finished here, it's not possible + // for the master to be booked. + assert(!searching); + assert(!activePosition); + + // We have returned from the idle loop, which means that all threads are + // finished. Note that setting 'searching' and decreasing splitPointsSize is + // done under lock protection to avoid a race with Thread::available_to(). + Threads.mutex.lock(); + sp.mutex.lock(); searching = true; --splitPointsSize; -- 2.39.2