Use hwloc for set thread affinity.

This commit is contained in:
XMRig 2019-10-06 14:40:42 +07:00
parent 9101469308
commit 72c9d94390
9 changed files with 118 additions and 38 deletions

View file

@ -98,7 +98,14 @@ elseif (APPLE)
else() else()
set(SOURCES_OS set(SOURCES_OS
src/base/io/json/Json_unix.cpp src/base/io/json/Json_unix.cpp
src/base/kernel//Platform_unix.cpp src/base/kernel/Platform_unix.cpp
)
endif()
if (WITH_HWLOC)
list(APPEND SOURCES_OS
src/base/kernel/Platform_hwloc.cpp
) )
endif() endif()

View file

@ -23,7 +23,10 @@
*/ */
#include <string.h> #include "base/kernel/Platform.h"
#include <cstring>
#include <uv.h> #include <uv.h>
@ -33,13 +36,14 @@
#endif #endif
#include "Platform.h" namespace xmrig {
String Platform::m_userAgent;
} // namespace xmrig
xmrig::String Platform::m_userAgent; void xmrig::Platform::init(const char *userAgent)
void Platform::init(const char *userAgent)
{ {
# ifdef XMRIG_FEATURE_TLS # ifdef XMRIG_FEATURE_TLS
SSL_library_init(); SSL_library_init();

View file

@ -26,12 +26,15 @@
#define XMRIG_PLATFORM_H #define XMRIG_PLATFORM_H
#include <stdint.h> #include <cstdint>
#include "base/tools/String.h" #include "base/tools/String.h"
namespace xmrig {
class Platform class Platform
{ {
public: public:
@ -56,8 +59,11 @@ public:
private: private:
static char *createUserAgent(); static char *createUserAgent();
static xmrig::String m_userAgent; static String m_userAgent;
}; };
} // namespace xmrig
#endif /* XMRIG_PLATFORM_H */ #endif /* XMRIG_PLATFORM_H */

View file

@ -0,0 +1,49 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/kernel/Platform.h"
#include "backend/cpu/platform/HwlocCpuInfo.h"
#include "backend/cpu/Cpu.h"
#include <hwloc.h>
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{
auto cpu = static_cast<HwlocCpuInfo *>(Cpu::info());
hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast<unsigned>(cpu_id));
if (pu == nullptr) {
return false;
}
if (hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD | HWLOC_CPUBIND_STRICT) >= 0) {
return true;
}
return hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD) >= 0;
}

View file

@ -30,7 +30,7 @@
#include <uv.h> #include <uv.h>
#include "Platform.h" #include "base/kernel/Platform.h"
#include "version.h" #include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT #ifdef XMRIG_NVIDIA_PROJECT
@ -38,7 +38,7 @@
#endif #endif
char *Platform::createUserAgent() char *xmrig::Platform::createUserAgent()
{ {
constexpr const size_t max = 256; constexpr const size_t max = 256;
@ -60,7 +60,8 @@ char *Platform::createUserAgent()
} }
bool Platform::setThreadAffinity(uint64_t cpu_id) #ifndef XMRIG_FEATURE_HWLOC
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{ {
thread_port_t mach_thread; thread_port_t mach_thread;
thread_affinity_policy_data_t policy = { static_cast<integer_t>(cpu_id) }; thread_affinity_policy_data_t policy = { static_cast<integer_t>(cpu_id) };
@ -68,25 +69,26 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS; return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS;
} }
#endif
uint32_t Platform::setTimerResolution(uint32_t resolution) uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
{ {
return resolution; return resolution;
} }
void Platform::restoreTimerResolution() void xmrig::Platform::restoreTimerResolution()
{ {
} }
void Platform::setProcessPriority(int priority) void xmrig::Platform::setProcessPriority(int priority)
{ {
} }
void Platform::setThreadPriority(int priority) void xmrig::Platform::setThreadPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {
return; return;

View file

@ -39,7 +39,7 @@
#include <uv.h> #include <uv.h>
#include "Platform.h" #include "base/kernel/Platform.h"
#include "version.h" #include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT #ifdef XMRIG_NVIDIA_PROJECT
@ -52,7 +52,7 @@ typedef cpuset_t cpu_set_t;
#endif #endif
char *Platform::createUserAgent() char *xmrig::Platform::createUserAgent()
{ {
constexpr const size_t max = 256; constexpr const size_t max = 256;
@ -84,7 +84,8 @@ char *Platform::createUserAgent()
} }
bool Platform::setThreadAffinity(uint64_t cpu_id) #ifndef XMRIG_FEATURE_HWLOC
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{ {
cpu_set_t mn; cpu_set_t mn;
CPU_ZERO(&mn); CPU_ZERO(&mn);
@ -96,25 +97,26 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0; return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0;
# endif # endif
} }
#endif
uint32_t Platform::setTimerResolution(uint32_t resolution) uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
{ {
return resolution; return resolution;
} }
void Platform::restoreTimerResolution() void xmrig::Platform::restoreTimerResolution()
{ {
} }
void Platform::setProcessPriority(int priority) void xmrig::Platform::setProcessPriority(int priority)
{ {
} }
void Platform::setThreadPriority(int priority) void xmrig::Platform::setThreadPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {
return; return;

View file

@ -29,8 +29,8 @@
#include <uv.h> #include <uv.h>
#include "base/kernel/Platform.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "Platform.h"
#include "version.h" #include "version.h"
@ -51,10 +51,10 @@ static inline OSVERSIONINFOEX winOsVersion()
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll"); HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
if (ntdll ) { if (ntdll ) {
RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(GetProcAddress(ntdll, "RtlGetVersion")); auto pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(GetProcAddress(ntdll, "RtlGetVersion"));
if (pRtlGetVersion) { if (pRtlGetVersion) {
pRtlGetVersion((LPOSVERSIONINFO) &result); pRtlGetVersion(reinterpret_cast<LPOSVERSIONINFO>(&result));
} }
} }
@ -62,7 +62,7 @@ static inline OSVERSIONINFOEX winOsVersion()
} }
char *Platform::createUserAgent() char *xmrig::Platform::createUserAgent()
{ {
const auto osver = winOsVersion(); const auto osver = winOsVersion();
constexpr const size_t max = 256; constexpr const size_t max = 256;
@ -91,7 +91,8 @@ char *Platform::createUserAgent()
} }
bool Platform::setThreadAffinity(uint64_t cpu_id) #ifndef XMRIG_FEATURE_HWLOC
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
{ {
if (cpu_id >= 64) { if (cpu_id >= 64) {
LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63."); LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63.");
@ -99,9 +100,10 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0; return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0;
} }
#endif
uint32_t Platform::setTimerResolution(uint32_t resolution) uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
{ {
# ifdef XMRIG_AMD_PROJECT # ifdef XMRIG_AMD_PROJECT
TIMECAPS tc; TIMECAPS tc;
@ -119,7 +121,7 @@ uint32_t Platform::setTimerResolution(uint32_t resolution)
} }
void Platform::restoreTimerResolution() void xmrig::Platform::restoreTimerResolution()
{ {
# ifdef XMRIG_AMD_PROJECT # ifdef XMRIG_AMD_PROJECT
if (timerResolution) { if (timerResolution) {
@ -129,7 +131,7 @@ void Platform::restoreTimerResolution()
} }
void Platform::setProcessPriority(int priority) void xmrig::Platform::setProcessPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {
return; return;
@ -166,7 +168,7 @@ void Platform::setProcessPriority(int priority)
} }
void Platform::setThreadPriority(int priority) void xmrig::Platform::setThreadPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {
return; return;

View file

@ -49,6 +49,9 @@ uint32_t xmrig::VirtualMemory::bindToNUMANode(int64_t affinity)
auto cpu = static_cast<HwlocCpuInfo *>(Cpu::info()); auto cpu = static_cast<HwlocCpuInfo *>(Cpu::info());
hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast<unsigned>(affinity)); hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast<unsigned>(affinity));
char *buffer;
hwloc_bitmap_asprintf(&buffer, pu->cpuset);
if (pu == nullptr || !cpu->membind(pu->nodeset)) { if (pu == nullptr || !cpu->membind(pu->nodeset)) {
LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory\"", affinity); LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory\"", affinity);

View file

@ -28,8 +28,11 @@
#define XMRIG_VIRTUALMEMORY_H #define XMRIG_VIRTUALMEMORY_H
#include <stddef.h> #include "base/tools/Object.h"
#include <stdint.h>
#include <cstddef>
#include <cstdint>
#include <utility> #include <utility>
@ -39,7 +42,9 @@ namespace xmrig {
class VirtualMemory class VirtualMemory
{ {
public: public:
inline VirtualMemory() {} XMRIG_DISABLE_COPY_MOVE(VirtualMemory)
VirtualMemory() = default;
VirtualMemory(size_t size, bool hugePages = true, size_t align = 64); VirtualMemory(size_t size, bool hugePages = true, size_t align = 64);
~VirtualMemory(); ~VirtualMemory();
@ -49,7 +54,7 @@ public:
inline std::pair<size_t, size_t> hugePages() const inline std::pair<size_t, size_t> hugePages() const
{ {
return std::pair<size_t, size_t>(isHugePages() ? (align(size()) / 2097152) : 0, align(size()) / 2097152); return { isHugePages() ? (align(size()) / 2097152) : 0, align(size()) / 2097152 };
} }
static uint32_t bindToNUMANode(int64_t affinity); static uint32_t bindToNUMANode(int64_t affinity);