hwloc NUMA memory binding

- add function `bindMemoryToNUMANode()`
- add `affinity` member to `minethd`
This commit is contained in:
psychocrypt
2017-06-05 20:18:20 +02:00
parent 63c6e98dfe
commit f50a52b4af
3 changed files with 66 additions and 3 deletions
+53
View File
@@ -0,0 +1,53 @@
#pragma once
#include "console.h"
#ifndef CONF_NO_HWLOC
#include <hwloc.h>
/** pin memory to NUMA node
*
* Set the default memory policy for the current thread to bind memory to the
* NUMA node.
*
* @param puId core id
*/
void bindMemoryToNUMANode( int puId )
{
int depth;
hwloc_topology_t topology;
hwloc_obj_t obj;
hwloc_topology_init(&topology);
hwloc_topology_load(topology);
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU);
for( int i = 0;
i < hwloc_get_nbobjs_by_depth(topology, depth);
i++ )
{
hwloc_obj_t pu = hwloc_get_obj_by_depth(topology, depth, i);
if( pu->os_index == puId )
if( 0 > hwloc_set_membind_nodeset(
topology,
pu->nodeset,
HWLOC_MEMBIND_BIND,
HWLOC_MEMBIND_THREAD)
)
printer::inst()->print_msg(L0, "hwloc: can't bind memory");
else
{
printer::inst()->print_msg(L0, "hwloc: memory pinned");
break;
}
}
}
#else
void bindMemoryToNUMANode( int )
{
}
#endif
+10 -2
View File
@@ -64,6 +64,7 @@ void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id)
#include "minethd.h"
#include "jconf.h"
#include "crypto/cryptonight_aesni.h"
#include "hwlocMemory.hpp"
telemetry::telemetry(size_t iThd)
{
@@ -140,7 +141,7 @@ void telemetry::push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTime
iBucketTop[iThd] = (iTop + 1) & iBucketMask;
}
minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch)
minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int affinity)
{
oWork = pWork;
bQuit = 0;
@@ -149,6 +150,7 @@ minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefet
iHashCount = 0;
iTimestamp = 0;
bNoPrefetch = no_prefetch;
this->affinity = affinity;
if(double_work)
oWorkThd = std::thread(&minethd::double_work_main, this);
@@ -295,7 +297,7 @@ std::vector<minethd*>* minethd::thread_starter(miner_work& pWork)
{
jconf::inst()->GetThreadConfig(i, cfg);
minethd* thd = new minethd(pWork, i, cfg.bDoubleMode, cfg.bNoPrefetch);
minethd* thd = new minethd(pWork, i, cfg.bDoubleMode, cfg.bNoPrefetch, cfg.iCpuAff);
if(cfg.iCpuAff >= 0)
{
@@ -361,6 +363,9 @@ minethd::cn_hash_fun minethd::func_selector(bool bHaveAes, bool bNoPrefetch)
void minethd::work_main()
{
// pin memory to NUMA node
bindMemoryToNUMANode(this->affinity);
cn_hash_fun hash_fun;
cryptonight_ctx* ctx;
uint64_t iCount = 0;
@@ -448,6 +453,9 @@ minethd::cn_hash_fun_dbl minethd::func_dbl_selector(bool bHaveAes, bool bNoPrefe
void minethd::double_work_main()
{
// pin memory to NUMA node
bindMemoryToNUMANode(this->affinity);
cn_hash_fun_dbl hash_fun;
cryptonight_ctx* ctx0;
cryptonight_ctx* ctx1;
+3 -1
View File
@@ -97,11 +97,13 @@ public:
std::atomic<uint64_t> iHashCount;
std::atomic<uint64_t> iTimestamp;
int affinity;
private:
typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*);
typedef void (*cn_hash_fun_dbl)(const void*, size_t, void*, cryptonight_ctx* __restrict, cryptonight_ctx* __restrict);
minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch);
minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int affinity);
// We use the top 10 bits of the nonce for thread and resume
// This allows us to resume up to 128 threads 4 times before