Use real number of cores for default -par, ignore virtual cores
To determine the default for `-par`, the number of script verification threads, use [boost:🧵:physical_concurrency()](http://www.boost.org/doc/libs/1_58_0/doc/html/thread/thread_management.html#thread.thread_management.thread.physical_concurrency) which counts only physical cores, not virtual cores. Virtual cores are roughly a set of cached registers to avoid context switches while threading, they cannot actually perform work, so spawning a verification thread for them could even reduce efficiency and will put undue load on the system. Should fix issue #6358, as well as some other reported system overload issues, especially on Intel processors. The function was only introduced in boost 1.56, so provide a utility function `GetNumCores` to fall back for older Boost versions.
This commit is contained in:
parent
da77a6f761
commit
47162673c7
5 changed files with 21 additions and 4 deletions
|
@ -283,7 +283,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||||
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
|
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
|
||||||
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
|
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
|
||||||
strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
|
strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
|
||||||
-(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
|
-GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
|
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
|
||||||
#endif
|
#endif
|
||||||
|
@ -774,7 +774,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
|
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
|
||||||
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
|
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
|
||||||
if (nScriptCheckThreads <= 0)
|
if (nScriptCheckThreads <= 0)
|
||||||
nScriptCheckThreads += boost::thread::hardware_concurrency();
|
nScriptCheckThreads += GetNumCores();
|
||||||
if (nScriptCheckThreads <= 1)
|
if (nScriptCheckThreads <= 1)
|
||||||
nScriptCheckThreads = 0;
|
nScriptCheckThreads = 0;
|
||||||
else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
|
else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
|
||||||
|
|
|
@ -560,7 +560,7 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
||||||
if (Params().DefaultMinerThreads())
|
if (Params().DefaultMinerThreads())
|
||||||
nThreads = Params().DefaultMinerThreads();
|
nThreads = Params().DefaultMinerThreads();
|
||||||
else
|
else
|
||||||
nThreads = boost::thread::hardware_concurrency();
|
nThreads = GetNumCores();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minerThreads != NULL)
|
if (minerThreads != NULL)
|
||||||
|
|
|
@ -42,7 +42,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
|
||||||
/* Main elements init */
|
/* Main elements init */
|
||||||
ui->databaseCache->setMinimum(nMinDbCache);
|
ui->databaseCache->setMinimum(nMinDbCache);
|
||||||
ui->databaseCache->setMaximum(nMaxDbCache);
|
ui->databaseCache->setMaximum(nMaxDbCache);
|
||||||
ui->threadsScriptVerif->setMinimum(-(int)boost::thread::hardware_concurrency());
|
ui->threadsScriptVerif->setMinimum(-GetNumCores());
|
||||||
ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
|
ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
|
||||||
|
|
||||||
/* Network elements init */
|
/* Network elements init */
|
||||||
|
|
10
src/util.cpp
10
src/util.cpp
|
@ -756,3 +756,13 @@ void SetThreadPriority(int nPriority)
|
||||||
#endif // PRIO_THREAD
|
#endif // PRIO_THREAD
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetNumCores()
|
||||||
|
{
|
||||||
|
#if BOOST_VERSION >= 105600
|
||||||
|
return boost::thread::physical_concurrency();
|
||||||
|
#else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores
|
||||||
|
return boost::thread::hardware_concurrency();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,13 @@ std::string HelpMessageGroup(const std::string& message);
|
||||||
*/
|
*/
|
||||||
std::string HelpMessageOpt(const std::string& option, const std::string& message);
|
std::string HelpMessageOpt(const std::string& option, const std::string& message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of physical cores available on the current system.
|
||||||
|
* @note This does not count virtual cores, such as those provided by HyperThreading
|
||||||
|
* when boost is newer than 1.56.
|
||||||
|
*/
|
||||||
|
int GetNumCores();
|
||||||
|
|
||||||
void SetThreadPriority(int nPriority);
|
void SetThreadPriority(int nPriority);
|
||||||
void RenameThread(const char* name);
|
void RenameThread(const char* name);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue