summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
da6e2b5)
Let to sleep even split point master, it will be waken
up by its slaves when they return from the search.
This time let it be enabled by an UCI option, so
people is free to test it on their Hyper Thread box.
Option is disabled by default.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
// Multi-threads related variables
Depth MinimumSplitDepth;
int MaxThreadsPerSplitPoint;
// Multi-threads related variables
Depth MinimumSplitDepth;
int MaxThreadsPerSplitPoint;
+ bool UseSleepingMaster;
ThreadsManager ThreadsMgr;
// Node counters, used only by thread[0] but try to keep in different cache
ThreadsManager ThreadsMgr;
// Node counters, used only by thread[0] but try to keep in different cache
MaxThreadsPerSplitPoint = Options["Maximum Number of Threads per Split Point"].value<int>();
MultiPV = Options["MultiPV"].value<int>();
UseLogFile = Options["Use Search Log"].value<bool>();
MaxThreadsPerSplitPoint = Options["Maximum Number of Threads per Split Point"].value<int>();
MultiPV = Options["MultiPV"].value<int>();
UseLogFile = Options["Use Search Log"].value<bool>();
+ UseSleepingMaster = Options["Use Sleeping Master"].value<bool>();
if (UseLogFile)
LogFile.open(Options["Search Log Filename"].value<std::string>().c_str(), std::ios::out | std::ios::app);
if (UseLogFile)
LogFile.open(Options["Search Log Filename"].value<std::string>().c_str(), std::ios::out | std::ios::app);
assert(threadID >= 0 && threadID < MAX_THREADS);
assert(threadID >= 0 && threadID < MAX_THREADS);
+ int i;
+ bool allFinished = false;
+
while (true)
{
// Slave threads can exit as soon as AllThreadsShouldExit raises,
while (true)
{
// Slave threads can exit as soon as AllThreadsShouldExit raises,
// instead of wasting CPU time polling for work.
while ( threadID >= ActiveThreads
|| threads[threadID].state == THREAD_INITIALIZING
// instead of wasting CPU time polling for work.
while ( threadID >= ActiveThreads
|| threads[threadID].state == THREAD_INITIALIZING
- || (!sp && threads[threadID].state == THREAD_AVAILABLE))
+ || (threads[threadID].state == THREAD_AVAILABLE && (!sp || UseSleepingMaster)))
- assert(!sp);
- assert(threadID != 0);
-
- if (AllThreadsShouldExit)
- break;
-
- // Retest condition under lock protection
- if (!( threadID >= ActiveThreads
- || threads[threadID].state == THREAD_INITIALIZING
- || (!sp && threads[threadID].state == THREAD_AVAILABLE)))
+ // Test with lock held to avoid races with wake_sleeping_thread()
+ for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
+ allFinished = (i == ActiveThreads);
+
+ // Retest sleep conditions under lock protection
+ if ( AllThreadsShouldExit
+ || allFinished
+ || !( threadID >= ActiveThreads
+ || threads[threadID].state == THREAD_INITIALIZING
+ || (threads[threadID].state == THREAD_AVAILABLE && (!sp || UseSleepingMaster))))
assert(threads[threadID].state == THREAD_SEARCHING);
threads[threadID].state = THREAD_AVAILABLE;
assert(threads[threadID].state == THREAD_SEARCHING);
threads[threadID].state = THREAD_AVAILABLE;
+
+ // 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 (UseSleepingMaster && threadID != tsp->master && threads[tsp->master].state == THREAD_AVAILABLE)
+ wake_sleeping_thread(tsp->master);
}
// If this thread is the master of a split point and all slaves have
// finished their work at this split point, return from the idle loop.
}
// If this thread is the master of a split point and all slaves have
// finished their work at this split point, return from the idle loop.
- int i = 0;
- for ( ; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
+ for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
+ allFinished = (i == ActiveThreads);
- if (i == ActiveThreads)
{
// Because sp->slaves[] is reset under lock protection,
// be sure sp->lock has been released before to return.
{
// Because sp->slaves[] is reset under lock protection,
// be sure sp->lock has been released before to return.
// Initialize the split point object
splitPoint.parent = masterThread.splitPoint;
// Initialize the split point object
splitPoint.parent = masterThread.splitPoint;
+ splitPoint.master = master;
splitPoint.stopRequest = false;
splitPoint.ply = ply;
splitPoint.depth = depth;
splitPoint.stopRequest = false;
splitPoint.ply = ply;
splitPoint.depth = depth;
bool pvNode, mateThreat;
Value beta;
int ply;
bool pvNode, mateThreat;
Value beta;
int ply;
Move threatMove;
SearchStack sstack[MAX_THREADS][PLY_MAX_PLUS_2];
Move threatMove;
SearchStack sstack[MAX_THREADS][PLY_MAX_PLUS_2];
Options["Minimum Split Depth"] = Option(4, 4, 7);
Options["Maximum Number of Threads per Split Point"] = Option(5, 4, 8);
Options["Threads"] = Option(1, 1, MAX_THREADS);
Options["Minimum Split Depth"] = Option(4, 4, 7);
Options["Maximum Number of Threads per Split Point"] = Option(5, 4, 8);
Options["Threads"] = Option(1, 1, MAX_THREADS);
+ Options["Use Sleeping Master"] = Option(false);
Options["Hash"] = Option(32, 4, 8192);
Options["Clear Hash"] = Option(false, "button");
Options["New Game"] = Option(false, "button");
Options["Hash"] = Option(32, 4, 8192);
Options["Clear Hash"] = Option(false, "button");
Options["New Game"] = Option(false, "button");