Browse Source

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.
pull/4/head
Wladimir J. van der Laan 9 years ago
committed by Jack Grigg
parent
commit
da1357e6cc
No known key found for this signature in database GPG Key ID: 6A6914DAFBEA00DA
  1. 4
      src/init.cpp
  2. 2
      src/miner.cpp
  3. 10
      src/util.cpp
  4. 7
      src/util.h

4
src/init.cpp

@ -333,7 +333,7 @@ std::string HelpMessage(HelpMessageMode mode)
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("-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
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "zcashd.pid"));
#endif
@ -901,7 +901,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
if (nScriptCheckThreads <= 0)
nScriptCheckThreads += boost::thread::hardware_concurrency();
nScriptCheckThreads += GetNumCores();
if (nScriptCheckThreads <= 1)
nScriptCheckThreads = 0;
else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)

2
src/miner.cpp

@ -753,7 +753,7 @@ void GenerateBitcoins(bool fGenerate, int nThreads)
if (Params().DefaultMinerThreads())
nThreads = Params().DefaultMinerThreads();
else
nThreads = boost::thread::hardware_concurrency();
nThreads = GetNumCores();
}
if (minerThreads != NULL)

10
src/util.cpp

@ -908,3 +908,13 @@ std::string LicenseInfo()
FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) +
"\n";
}
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
}

7
src/util.h

@ -219,6 +219,13 @@ std::string HelpMessageGroup(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 RenameThread(const char* name);

Loading…
Cancel
Save