diff options
author | fireice-uk <fireice-uk@users.noreply.github.com> | 2017-05-24 14:43:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-24 14:43:39 +0100 |
commit | ee2a2d77ecf5e20cd323443497de38d45ebb580c (patch) | |
tree | 6e48f3fe18fe53780c8a3537b7dff86f64013489 | |
parent | 8f51236e6743849bd3737d633f9716607b7427d1 (diff) | |
parent | e8a8cca0fb9663761d67ae3f2ed159f3701b4f50 (diff) | |
download | xmr-stak-ee2a2d77ecf5e20cd323443497de38d45ebb580c.zip xmr-stak-ee2a2d77ecf5e20cd323443497de38d45ebb580c.tar.gz |
Merge pull request #108 from psychocrypt/topic-hwloc
hwloc autoadjust
-rw-r--r-- | CMakeLists.txt | 23 | ||||
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | autoAdjustHwloc.hpp | 209 | ||||
-rw-r--r-- | cli-miner.cpp | 6 |
4 files changed, 243 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2373d85..876d68d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,29 @@ else() endif() ################################################################################ +# Find hwloc +################################################################################ + +option(HWLOC_ENABLE "Enable or disable the requirement of hwloc" ON) +if(HWLOC_ENABLE) + find_path(HWLOC_INCLUDE_DIR hwloc.h + $ENV{HWLOC_ROOT}/inlcude + /opt/local/include + /usr/local/include + /usr/include + ) + find_library(HWLOC NAMES hwloc) + if("${HWLOC}" STREQUAL "MHTD-NOTFOUND" OR ${HWLOC_INCLUDE_DIR} STREQUAL "HWLOC_INCLUDE_DIR-NOTFOUND") + message(FATAL_ERROR "hwloc NOT found: use `-DHWLOC_ENABLE=OFF` to build without hwloc support") + else() + set(LIBS ${LIBS} ${HWLOC}) + include_directories(AFTER ${HWLOC_INCLUDE_DIR}) + endif() +else() + add_definitions("-DCONF_NO_HWLOC") +endif() + +################################################################################ # Compile & Link ################################################################################ @@ -46,7 +46,7 @@ xXl2Nm/u3cPP/eQVrZz5H8eACwIv+LL1EV+9uLanWUa+IO5hHr3KElvKNKD6vN0= ### GNU Compiler ``` - sudo apt-get install libmicrohttpd-dev libssl-dev cmake build-essential + sudo apt-get install libmicrohttpd-dev libssl-dev cmake build-essential libhwloc-dev cmake . make install ``` @@ -171,9 +171,12 @@ and install. - `MICROHTTPD_ENABLE` allow to disable/enable the dependency *microhttpd* - by default enabled - there is no *http* interface available if option is disabled: `cmake . -DMICROHTTPD_ENABLE=OFF` -- `OpenSSL_ENABLE`allow to disable/enable the dependency *OpenSSL* +- `OpenSSL_ENABLE` allow to disable/enable the dependency *OpenSSL* - by default enabled - - it is not possible to connect to a *https* secured pool if optin is disabled: `cmake . -DOpenSSL_ENABLE=OFF` + - it is not possible to connect to a *https* secured pool if option is disabled: `cmake . -DOpenSSL_ENABLE=OFF` +- `HWLOC_ENABLE` allow to disable/enable the dependency *hwloc* + - by default enabled + - the config suggestion is not optimal if option is disabled: `cmake . -DHWLOC_ENABLE=OFF` ## PGP Key ``` diff --git a/autoAdjustHwloc.hpp b/autoAdjustHwloc.hpp new file mode 100644 index 0000000..07c3b4a --- /dev/null +++ b/autoAdjustHwloc.hpp @@ -0,0 +1,209 @@ +#pragma once + +#include "console.h" +#include <hwloc.h> + +#ifdef _WIN32 +#include <windows.h> +#else +#include <unistd.h> +#endif // _WIN32 + +class autoAdjust +{ +public: + + autoAdjust() + { + } + + void printConfig() + { + printer::inst()->print_str("The configuration for 'cpu_threads_conf' in your config file is 'null'.\n"); + printer::inst()->print_str("The miner evaluates your system and prints a suggestion for the section `cpu_threads_conf` to the terminal.\n"); + printer::inst()->print_str("The values are not optimal, please try to tweak the values based on notes in config.txt.\n"); + printer::inst()->print_str("Please copy & paste the block within the asterisks to your config.\n\n"); + printer::inst()->print_str("\n**************** Copy&Paste ****************\n\n"); + printer::inst()->print_str("\"cpu_threads_conf\" :\n[\n"); + + int depth; + hwloc_topology_t topology; + hwloc_obj_t socket; + + + hwloc_topology_init(&topology); + hwloc_topology_load(topology); + + depth = hwloc_get_type_depth(topology, HWLOC_OBJ_SOCKET); + if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) + { + printf("*** The number of sockets is unknown\n"); + } + + for (int i = 0; i < hwloc_get_nbobjs_by_depth(topology, depth); i++) + { + socket = hwloc_get_obj_by_depth(topology, depth, i); + + // search cacheprinter::inst()->print_str("\n**************** Copy&Paste ****************\n\n"); + for (int j = 0; j < socket->arity; j++) + { + hwloc_obj_t nextLvl = socket->children[j]; + findCache(topology, nextLvl); + } + } + + /* Destroy topology object. */ + hwloc_topology_destroy(topology); + + printer::inst()->print_str("],\n\n**************** Copy&Paste ****************\n"); + } + +private: + + /** count bits with ones */ + template<typename T> + int compat_popcnt(T x) + { + int count = 0; + for( int i = 0; i < sizeof(T) - 1; ++i ) + if( ( ( x >> i ) & 1 ) == 1 ) + ++count; + return count; + } + + int rightZeros(size_t v) + { + int c; + if (v) + { + v = (v ^ (v - 1)) >> 1; + for (c = 0; v; c++) + { + v >>= 1; + } + } + else + { + c = CHAR_BIT * sizeof (v); + } + return c; + } + + inline void getConfig(hwloc_topology_t topology, hwloc_obj_t obj, size_t& numHashes, int& numCachesLeft) + { + if (obj->type == HWLOC_OBJ_CORE) + { + if (obj) + { + hwloc_cpuset_t cpuset; + /* Get a copy of its cpuset that we may modify. */ + cpuset = hwloc_bitmap_dup(obj->cpuset); + size_t allcpu = hwloc_bitmap_to_ulong(cpuset); + /* Get only one logical processor (in case the core is + SMT/hyperthreaded). */ + hwloc_bitmap_singlify(cpuset); + + + size_t cpu = hwloc_bitmap_to_ulong(cpuset); + // move bit mask to right to allow to compare always the first bit + cpu >>= rightZeros(allcpu); + + + int nativeCores = compat_popcnt(cpu); + int numPus = obj->arity; + for (int i = 0; i < numPus && numHashes != 0; i++) + { + hwloc_obj_t pu = obj->children[i]; + // only use native pu's + if (pu->type == HWLOC_OBJ_PU && cpu & 1) + { + // if no cache is available we give each native core a hash + int numUnit = numCachesLeft != 0 ? numCachesLeft : nativeCores; + + // two hashes per native pu if number of hashes if larger than compute units + int power = numHashes > numUnit ? 2 : 1; + char strbuf[256]; + //printf("------------------------------core %i -> %i mpu=%i %lu\n", pu->os_index, power, nativeCores, numHashes); + snprintf(strbuf, sizeof(strbuf), " { \"low_power_mode\" : %s, \"no_prefetch\" : true, \"affine_to_cpu\" : %u },\n", + power == 2 ? "true" : "false", pu->os_index); + printer::inst()->print_str(strbuf); + + // update number of free hashes + numHashes -= power; + cpu >>= 1; + + // one cache is filled with hashes + if (numCachesLeft != 0) numCachesLeft--; + } + } + } + } + else + { + for (int i = 0; i < obj->arity; i++) + getConfig(topology, obj->children[i], numHashes, numCachesLeft); + } + } + + inline void findCache(hwloc_topology_t topology, hwloc_obj_t obj) + { + if (obj->type == HWLOC_OBJ_CACHE) + { + size_t cacheSize = obj->attr->cache.size; + size_t numHashL3 = ( cacheSize + m_scratchPadMemSize/ 2llu ) / m_scratchPadMemSize; + + /* check cache is exclusive or inclusive */ + const char* value = hwloc_obj_get_info_by_name(obj, "Inclusive"); + + + bool doL3 = true; + if (value == NULL || value[0] != 49 || cacheSize == 0) + { + size_t numHashes = 0; + int numL2 = obj->arity; + for (int k = 0; k < numL2; k++) + { + hwloc_obj_t l3Cache = obj->children[k]; + size_t l2Cache = 0; + + if (obj->type == HWLOC_OBJ_CACHE) + l2Cache = l3Cache->attr->cache.size; + else + break; + + if (l2Cache < m_scratchPadMemSize) + { + // we need to start from L3 + break; + } + + // start from L2 + + /* if more hashes available than objects in the current depth of the topology + * than divide with round down else round up + */ + int extraHash = numHashL3 > numL2 ? numHashL3 / numL2 : (numHashL3 + numL2 - 1) / numL2; + numHashL3 -= extraHash; + if (numHashL3 < 0) + numHashL3 = 0; + numHashes += extraHash; + //add L2 hashes + numHashes += ( l2Cache + m_scratchPadMemSize / 2llu ) / m_scratchPadMemSize; + int numCachesLeft = numL2; + getConfig(topology, l3Cache, numHashes, numCachesLeft); + doL3 = false; + } + } + if (doL3) + { + int numCachesLeft = obj->arity; + getConfig(topology, obj, numHashL3, numCachesLeft); + } + } + else + for (int j = 0; j < obj->arity; j++) + findCache(topology, obj->children[j]); + } + + static constexpr size_t m_scratchPadMemSize = ( 2llu * 1024llu * 1024llu ); +}; diff --git a/cli-miner.cpp b/cli-miner.cpp index 70a5228..2cbe6d9 100644 --- a/cli-miner.cpp +++ b/cli-miner.cpp @@ -26,7 +26,11 @@ #include "jconf.h" #include "console.h" #include "donate-level.h" -#include "autoAdjust.hpp" +#ifndef CONF_NO_HWLOC +# include "autoAdjustHwloc.hpp" +#else +# include "autoAdjust.hpp" +#endif #include "version.h" #ifndef CONF_NO_HTTPD |