From f197f6b1ebb13f6c46ec1e79fe3547961a7902f8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 06:38:18 +0700 Subject: [PATCH 01/25] Changed directory structure. --- CMakeLists.txt | 15 +++++++-------- src/{core => common/config}/CommonConfig.cpp | 2 +- src/{core => common/config}/CommonConfig.h | 2 +- src/{core => common/config}/ConfigLoader.cpp | 4 ++-- src/{core => common/config}/ConfigLoader.h | 0 src/{core => common/config}/ConfigWatcher.cpp | 4 ++-- src/{core => common/config}/ConfigWatcher.h | 2 +- src/{core => common}/utils/c_str.h | 0 src/core/Config.cpp | 2 +- src/core/Config.h | 2 +- src/core/Controller.cpp | 2 +- src/net/Pool.h | 2 +- src/workers/CpuThread.cpp | 2 +- 13 files changed, 19 insertions(+), 20 deletions(-) rename src/{core => common/config}/CommonConfig.cpp (99%) rename src/{core => common/config}/CommonConfig.h (99%) rename src/{core => common/config}/ConfigLoader.cpp (98%) rename src/{core => common/config}/ConfigLoader.h (100%) rename src/{core => common/config}/ConfigWatcher.cpp (97%) rename src/{core => common/config}/ConfigWatcher.h (98%) rename src/{core => common}/utils/c_str.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5502405ca..096fa97f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,15 +14,14 @@ include (cmake/cpu.cmake) set(HEADERS src/api/NetworkState.h src/App.h + src/common/config/CommonConfig.h + src/common/config/ConfigLoader.h + src/common/config/ConfigWatcher.h + src/common/utils/c_str.h src/Console.h - src/core/CommonConfig.h src/core/Config.cpp - src/core/ConfigLoader.cpp - src/core/ConfigLoader.h src/core/ConfigLoader_platform.h - src/core/ConfigWatcher.cpp src/core/Controller.h - src/core/utils/c_str.h src/Cpu.h src/interfaces/IClientListener.h src/interfaces/IConfig.h @@ -89,11 +88,11 @@ endif() set(SOURCES src/api/NetworkState.cpp src/App.cpp + src/common/config/CommonConfig.cpp + src/common/config/ConfigLoader.cpp + src/common/config/ConfigWatcher.cpp src/Console.cpp - src/core/CommonConfig.cpp src/core/Config.cpp - src/core/ConfigLoader.cpp - src/core/ConfigWatcher.cpp src/core/Controller.cpp src/log/ConsoleLog.cpp src/log/FileLog.cpp diff --git a/src/core/CommonConfig.cpp b/src/common/config/CommonConfig.cpp similarity index 99% rename from src/core/CommonConfig.cpp rename to src/common/config/CommonConfig.cpp index 726b0e37b..6902b7a24 100644 --- a/src/core/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -29,7 +29,7 @@ #include -#include "core/CommonConfig.h" +#include "common/config/CommonConfig.h" #include "donate.h" #include "log/Log.h" #include "net/Pool.h" diff --git a/src/core/CommonConfig.h b/src/common/config/CommonConfig.h similarity index 99% rename from src/core/CommonConfig.h rename to src/common/config/CommonConfig.h index 0b72b7e1b..f4cf4b437 100644 --- a/src/core/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -28,7 +28,7 @@ #include -#include "core/utils/c_str.h" +#include "common/utils/c_str.h" #include "interfaces/IConfig.h" #include "net/Pool.h" #include "xmrig.h" diff --git a/src/core/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp similarity index 98% rename from src/core/ConfigLoader.cpp rename to src/common/config/ConfigLoader.cpp index c84ba962d..a9c802f6a 100644 --- a/src/core/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -32,10 +32,10 @@ #endif +#include "common/config/ConfigLoader.h" +#include "common/config/ConfigWatcher.h" #include "core/ConfigCreator.h" -#include "core/ConfigLoader.h" #include "core/ConfigLoader_platform.h" -#include "core/ConfigWatcher.h" #include "interfaces/IConfig.h" #include "interfaces/IWatcherListener.h" #include "net/Pool.h" diff --git a/src/core/ConfigLoader.h b/src/common/config/ConfigLoader.h similarity index 100% rename from src/core/ConfigLoader.h rename to src/common/config/ConfigLoader.h diff --git a/src/core/ConfigWatcher.cpp b/src/common/config/ConfigWatcher.cpp similarity index 97% rename from src/core/ConfigWatcher.cpp rename to src/common/config/ConfigWatcher.cpp index 092a0f3aa..21d73188f 100644 --- a/src/core/ConfigWatcher.cpp +++ b/src/common/config/ConfigWatcher.cpp @@ -25,9 +25,9 @@ #include +#include "common/config/ConfigLoader.h" +#include "common/config/ConfigWatcher.h" #include "core/ConfigCreator.h" -#include "core/ConfigLoader.h" -#include "core/ConfigWatcher.h" #include "interfaces/IWatcherListener.h" #include "log/Log.h" diff --git a/src/core/ConfigWatcher.h b/src/common/config/ConfigWatcher.h similarity index 98% rename from src/core/ConfigWatcher.h rename to src/common/config/ConfigWatcher.h index a5d258640..7f38b45a8 100644 --- a/src/core/ConfigWatcher.h +++ b/src/common/config/ConfigWatcher.h @@ -29,7 +29,7 @@ #include -#include "core/utils/c_str.h" +#include "common/utils/c_str.h" #include "rapidjson/fwd.h" diff --git a/src/core/utils/c_str.h b/src/common/utils/c_str.h similarity index 100% rename from src/core/utils/c_str.h rename to src/common/utils/c_str.h diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f72112509..ee305091a 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -26,9 +26,9 @@ #include +#include "common/config/ConfigLoader.h" #include "core/Config.h" #include "core/ConfigCreator.h" -#include "core/ConfigLoader.h" #include "Cpu.h" #include "net/Pool.h" #include "rapidjson/document.h" diff --git a/src/core/Config.h b/src/core/Config.h index 536e1c012..999f30599 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -29,7 +29,7 @@ #include -#include "core/CommonConfig.h" +#include "common/config/CommonConfig.h" #include "rapidjson/fwd.h" #include "xmrig.h" diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 805861efb..954e5b10e 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -25,8 +25,8 @@ #include +#include "common/config/ConfigLoader.h" #include "core/Config.h" -#include "core/ConfigLoader.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IControllerListener.h" diff --git a/src/net/Pool.h b/src/net/Pool.h index efa3e3a7a..aff1ea318 100644 --- a/src/net/Pool.h +++ b/src/net/Pool.h @@ -28,7 +28,7 @@ #include -#include "core/utils/c_str.h" +#include "common/utils/c_str.h" #include "xmrig.h" diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 482b4305d..20a8006fb 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -24,7 +24,7 @@ #include -#include "core/CommonConfig.h" +#include "net/Pool.h" #include "rapidjson/document.h" #include "workers/CpuThread.h" From 51422f4b1e3e7fe0df5506c12b01c547d18c55df Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 07:00:51 +0700 Subject: [PATCH 02/25] Move xmrig.h to common/xmrig.h. --- CMakeLists.txt | 2 +- src/Cpu.h | 2 +- src/Mem.h | 2 +- src/Mem_win.cpp | 4 ++-- src/common/config/CommonConfig.cpp | 1 - src/common/config/CommonConfig.h | 2 +- src/{ => common}/xmrig.h | 0 src/core/Config.cpp | 1 - src/core/Config.h | 2 +- src/crypto/CryptoNight_constants.h | 2 +- src/interfaces/IThread.h | 2 +- src/net/Job.h | 2 +- src/net/Pool.h | 2 +- src/net/strategies/DonateStrategy.cpp | 2 +- src/workers/CpuThread.h | 2 +- 15 files changed, 13 insertions(+), 15 deletions(-) rename src/{ => common}/xmrig.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 096fa97f2..97d3e51b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(HEADERS src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h src/common/utils/c_str.h + src/common/xmrig.h src/Console.h src/core/Config.cpp src/core/ConfigLoader_platform.h @@ -60,7 +61,6 @@ set(HEADERS src/workers/SingleWorker.h src/workers/Worker.h src/workers/Workers.h - src/xmrig.h ) set(HEADERS_CRYPTO diff --git a/src/Cpu.h b/src/Cpu.h index 118c7b7d3..e739ccce4 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -28,7 +28,7 @@ #include -#include "xmrig.h" +#include "common/xmrig.h" class Cpu diff --git a/src/Mem.h b/src/Mem.h index 73947b42d..06b470c8f 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -30,7 +30,7 @@ #include -#include "xmrig.h" +#include "common/xmrig.h" struct cryptonight_ctx; diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index ec30e3e82..1f3066ea3 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -34,10 +34,10 @@ # include #endif -#include "log/Log.h" +#include "common/xmrig.h" #include "crypto/CryptoNight.h" +#include "log/Log.h" #include "Mem.h" -#include "xmrig.h" /***************************************************************** diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 6902b7a24..2cce845cc 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -36,7 +36,6 @@ #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" -#include "xmrig.h" xmrig::CommonConfig::CommonConfig() : diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index f4cf4b437..5a229269e 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -29,9 +29,9 @@ #include "common/utils/c_str.h" +#include "common/xmrig.h" #include "interfaces/IConfig.h" #include "net/Pool.h" -#include "xmrig.h" namespace xmrig { diff --git a/src/xmrig.h b/src/common/xmrig.h similarity index 100% rename from src/xmrig.h rename to src/common/xmrig.h diff --git a/src/core/Config.cpp b/src/core/Config.cpp index ee305091a..07f111925 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -35,7 +35,6 @@ #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" #include "workers/CpuThread.h" -#include "xmrig.h" static char affinity_tmp[20] = { 0 }; diff --git a/src/core/Config.h b/src/core/Config.h index 999f30599..fd33b614f 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -30,8 +30,8 @@ #include "common/config/CommonConfig.h" +#include "common/xmrig.h" #include "rapidjson/fwd.h" -#include "xmrig.h" class Addr; diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index 60f0df087..3c746d47a 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -29,7 +29,7 @@ #include -#include "xmrig.h" +#include "common/xmrig.h" namespace xmrig diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index e2325c729..5b3efa0de 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -27,8 +27,8 @@ #include +#include "common/xmrig.h" #include "rapidjson/fwd.h" -#include "xmrig.h" namespace xmrig { diff --git a/src/net/Job.h b/src/net/Job.h index e89643140..a60f061ce 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -30,8 +30,8 @@ #include +#include "common/xmrig.h" #include "net/Id.h" -#include "xmrig.h" class Job diff --git a/src/net/Pool.h b/src/net/Pool.h index aff1ea318..ecce865a7 100644 --- a/src/net/Pool.h +++ b/src/net/Pool.h @@ -29,7 +29,7 @@ #include "common/utils/c_str.h" -#include "xmrig.h" +#include "common/xmrig.h" class Pool diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 311ca4241..da25e23f1 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,13 +22,13 @@ */ +#include "common/xmrig.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/Job.h" #include "net/strategies/DonateStrategy.h" #include "net/strategies/FailoverStrategy.h" #include "Platform.h" -#include "xmrig.h" extern "C" diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index aef73719c..dadd0424b 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -25,8 +25,8 @@ #define __CPUTHREAD_H__ +#include "common/xmrig.h" #include "interfaces/IThread.h" -#include "xmrig.h" struct cryptonight_ctx; From a6b698d4ebc93525adc592f85e82fd41d7a2d2d2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 07:12:53 +0700 Subject: [PATCH 03/25] Move common parts of API. --- CMakeLists.txt | 12 ++++++------ src/App.cpp | 2 +- src/api/Api.cpp | 4 ++-- src/api/ApiRouter.cpp | 4 ++-- src/{ => common}/api/HttpBody.h | 0 src/{ => common}/api/HttpReply.h | 0 src/{ => common}/api/HttpRequest.cpp | 6 +++--- src/{ => common}/api/HttpRequest.h | 0 src/{ => common}/api/Httpd.cpp | 6 +++--- src/{ => common}/api/Httpd.h | 0 10 files changed, 17 insertions(+), 17 deletions(-) rename src/{ => common}/api/HttpBody.h (100%) rename src/{ => common}/api/HttpReply.h (100%) rename src/{ => common}/api/HttpRequest.cpp (97%) rename src/{ => common}/api/HttpRequest.h (100%) rename src/{ => common}/api/Httpd.cpp (97%) rename src/{ => common}/api/Httpd.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97d3e51b9..0da768b2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,14 +214,14 @@ if (WITH_HTTPD) set(HTTPD_SOURCES src/api/Api.h src/api/ApiRouter.h - src/api/HttpBody.h - src/api/Httpd.h - src/api/HttpReply.h - src/api/HttpRequest.h + src/common/api/HttpBody.h + src/common/api/Httpd.h + src/common/api/HttpReply.h + src/common/api/HttpRequest.h src/api/Api.cpp src/api/ApiRouter.cpp - src/api/Httpd.cpp - src/api/HttpRequest.cpp + src/common/api/Httpd.cpp + src/common/api/HttpRequest.cpp ) else() message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support") diff --git a/src/App.cpp b/src/App.cpp index dc22836df..9ac785006 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -45,7 +45,7 @@ #ifndef XMRIG_NO_HTTPD -# include "api/Httpd.h" +# include "common/api/Httpd.h" #endif diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 368591363..6f9991ee1 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -26,8 +26,8 @@ #include "api/Api.h" #include "api/ApiRouter.h" -#include "api/HttpReply.h" -#include "api/HttpRequest.h" +#include "common/api/HttpReply.h" +#include "common/api/HttpRequest.h" ApiRouter *Api::m_router = nullptr; diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 6c4f1f271..81f765c5a 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -33,8 +33,8 @@ #include "api/ApiRouter.h" -#include "api/HttpReply.h" -#include "api/HttpRequest.h" +#include "common/api/HttpReply.h" +#include "common/api/HttpRequest.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" diff --git a/src/api/HttpBody.h b/src/common/api/HttpBody.h similarity index 100% rename from src/api/HttpBody.h rename to src/common/api/HttpBody.h diff --git a/src/api/HttpReply.h b/src/common/api/HttpReply.h similarity index 100% rename from src/api/HttpReply.h rename to src/common/api/HttpReply.h diff --git a/src/api/HttpRequest.cpp b/src/common/api/HttpRequest.cpp similarity index 97% rename from src/api/HttpRequest.cpp rename to src/common/api/HttpRequest.cpp index ac7210bd4..01245dfc0 100644 --- a/src/api/HttpRequest.cpp +++ b/src/common/api/HttpRequest.cpp @@ -25,9 +25,9 @@ #include #include -#include "api/HttpBody.h" -#include "api/HttpRequest.h" -#include "api/HttpReply.h" +#include "common/api/HttpBody.h" +#include "common/api/HttpRequest.h" +#include "common/api/HttpReply.h" #ifndef MHD_HTTP_PAYLOAD_TOO_LARGE diff --git a/src/api/HttpRequest.h b/src/common/api/HttpRequest.h similarity index 100% rename from src/api/HttpRequest.h rename to src/common/api/HttpRequest.h diff --git a/src/api/Httpd.cpp b/src/common/api/Httpd.cpp similarity index 97% rename from src/api/Httpd.cpp rename to src/common/api/Httpd.cpp index e0901b771..135ac7c9a 100644 --- a/src/api/Httpd.cpp +++ b/src/common/api/Httpd.cpp @@ -27,9 +27,9 @@ #include "api/Api.h" -#include "api/Httpd.h" -#include "api/HttpReply.h" -#include "api/HttpRequest.h" +#include "common/api/Httpd.h" +#include "common/api/HttpReply.h" +#include "common/api/HttpRequest.h" #include "log/Log.h" diff --git a/src/api/Httpd.h b/src/common/api/Httpd.h similarity index 100% rename from src/api/Httpd.h rename to src/common/api/Httpd.h From c1800094d0a5b91755ea66498ebd0c50261a4a1b Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 07:23:01 +0700 Subject: [PATCH 04/25] Move Platform. --- CMakeLists.txt | 10 +++++----- src/App.cpp | 2 +- src/api/ApiRouter.cpp | 2 +- src/{ => common}/Platform.cpp | 0 src/{ => common}/Platform.h | 0 src/{ => common}/Platform_mac.cpp | 0 src/{ => common}/Platform_unix.cpp | 0 src/{ => common}/Platform_win.cpp | 0 src/common/config/ConfigLoader.cpp | 2 +- src/core/Controller.cpp | 2 +- src/net/strategies/DonateStrategy.cpp | 2 +- src/net/strategies/FailoverStrategy.cpp | 2 +- src/net/strategies/SinglePoolStrategy.cpp | 2 +- src/workers/Worker.cpp | 2 +- 14 files changed, 13 insertions(+), 13 deletions(-) rename src/{ => common}/Platform.cpp (100%) rename src/{ => common}/Platform.h (100%) rename src/{ => common}/Platform_mac.cpp (100%) rename src/{ => common}/Platform_unix.cpp (100%) rename src/{ => common}/Platform_win.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0da768b2f..c8d381d44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ set(HEADERS src/common/config/CommonConfig.h src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h + src/common/Platform.h src/common/utils/c_str.h src/common/xmrig.h src/Console.h @@ -51,7 +52,6 @@ set(HEADERS src/net/strategies/FailoverStrategy.h src/net/strategies/SinglePoolStrategy.h src/net/SubmitResult.h - src/Platform.h src/Summary.h src/version.h src/workers/CpuThread.h @@ -91,6 +91,7 @@ set(SOURCES src/common/config/CommonConfig.cpp src/common/config/ConfigLoader.cpp src/common/config/ConfigWatcher.cpp + src/common/Platform.cpp src/Console.cpp src/core/Config.cpp src/core/Controller.cpp @@ -106,7 +107,6 @@ set(SOURCES src/net/strategies/FailoverStrategy.cpp src/net/strategies/SinglePoolStrategy.cpp src/net/SubmitResult.cpp - src/Platform.cpp src/Summary.cpp src/workers/CpuThread.cpp src/workers/DoubleWorker.cpp @@ -130,9 +130,9 @@ if (WIN32) set(SOURCES_OS res/app.rc src/App_win.cpp + src/common/Platform_win.cpp src/Cpu_win.cpp src/Mem_win.cpp - src/Platform_win.cpp ) add_definitions(/DWIN32) @@ -140,16 +140,16 @@ if (WIN32) elseif (APPLE) set(SOURCES_OS src/App_unix.cpp + src/common/Platform_mac.cpp src/Cpu_mac.cpp src/Mem_unix.cpp - src/Platform_mac.cpp ) else() set(SOURCES_OS src/App_unix.cpp + src/common/Platform_unix.cpp src/Cpu_unix.cpp src/Mem_unix.cpp - src/Platform_unix.cpp ) set(EXTRA_LIBS pthread rt) diff --git a/src/App.cpp b/src/App.cpp index 9ac785006..3d0cb3df4 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -28,6 +28,7 @@ #include "api/Api.h" #include "App.h" +#include "common/Platform.h" #include "Console.h" #include "core/Config.h" #include "core/Controller.h" @@ -38,7 +39,6 @@ #include "log/Log.h" #include "Mem.h" #include "net/Network.h" -#include "Platform.h" #include "Summary.h" #include "version.h" #include "workers/Workers.h" diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 81f765c5a..cb7a80051 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -35,13 +35,13 @@ #include "api/ApiRouter.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" +#include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IThread.h" #include "Mem.h" #include "net/Job.h" -#include "Platform.h" #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" #include "rapidjson/stringbuffer.h" diff --git a/src/Platform.cpp b/src/common/Platform.cpp similarity index 100% rename from src/Platform.cpp rename to src/common/Platform.cpp diff --git a/src/Platform.h b/src/common/Platform.h similarity index 100% rename from src/Platform.h rename to src/common/Platform.h diff --git a/src/Platform_mac.cpp b/src/common/Platform_mac.cpp similarity index 100% rename from src/Platform_mac.cpp rename to src/common/Platform_mac.cpp diff --git a/src/Platform_unix.cpp b/src/common/Platform_unix.cpp similarity index 100% rename from src/Platform_unix.cpp rename to src/common/Platform_unix.cpp diff --git a/src/Platform_win.cpp b/src/common/Platform_win.cpp similarity index 100% rename from src/Platform_win.cpp rename to src/common/Platform_win.cpp diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp index a9c802f6a..47c6cdf90 100644 --- a/src/common/config/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -34,12 +34,12 @@ #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/Platform.h" #include "core/ConfigCreator.h" #include "core/ConfigLoader_platform.h" #include "interfaces/IConfig.h" #include "interfaces/IWatcherListener.h" #include "net/Pool.h" -#include "Platform.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/filereadstream.h" diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 954e5b10e..f120c0c12 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,6 +26,7 @@ #include "common/config/ConfigLoader.h" +#include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" @@ -34,7 +35,6 @@ #include "log/FileLog.h" #include "log/Log.h" #include "net/Network.h" -#include "Platform.h" #ifdef HAVE_SYSLOG_H diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index da25e23f1..27beae33d 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,13 +22,13 @@ */ +#include "common/Platform.h" #include "common/xmrig.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/Job.h" #include "net/strategies/DonateStrategy.h" #include "net/strategies/FailoverStrategy.h" -#include "Platform.h" extern "C" diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp index a4e252775..cef9da0c3 100644 --- a/src/net/strategies/FailoverStrategy.cpp +++ b/src/net/strategies/FailoverStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/Platform.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/FailoverStrategy.h" -#include "Platform.h" FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index 8c113d933..c74a794b1 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/Platform.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/SinglePoolStrategy.h" -#include "Platform.h" SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) : diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index f9162e3f6..30305ac6e 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -24,9 +24,9 @@ #include +#include "common/Platform.h" #include "Cpu.h" #include "Mem.h" -#include "Platform.h" #include "workers/CpuThread.h" #include "workers/Handle.h" #include "workers/Worker.h" From 9ce9147dad8924e9c14537ab76639076b7eb6dbf Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 09:27:37 +0700 Subject: [PATCH 05/25] Use new method to set affinity. --- src/App_unix.cpp | 6 ------ src/App_win.cpp | 6 ------ src/Cpu.h | 1 - src/Cpu_unix.cpp | 25 ------------------------- src/Cpu_win.cpp | 11 ----------- src/Mem_unix.cpp | 2 +- src/common/Platform.cpp | 9 +++++---- src/common/Platform.h | 14 ++++++++++---- src/common/Platform_mac.cpp | 19 +++++++++++++++---- src/common/Platform_unix.cpp | 34 ++++++++++++++++++++++++++++++---- src/common/Platform_win.cpp | 21 +++++++++++++++------ src/core/Controller.cpp | 1 - src/workers/Handle.cpp | 3 +-- src/workers/Handle.h | 4 +--- src/workers/Worker.cpp | 6 +++--- src/workers/Workers.cpp | 2 +- 16 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/App_unix.cpp b/src/App_unix.cpp index fdb2b124a..f739e42e7 100644 --- a/src/App_unix.cpp +++ b/src/App_unix.cpp @@ -31,7 +31,6 @@ #include "App.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "log/Log.h" @@ -39,11 +38,6 @@ void App::background() { signal(SIGPIPE, SIG_IGN); - const int64_t affinity = m_controller->config()->affinity(); - if (affinity != -1L) { - Cpu::setAffinity(-1, affinity); - } - if (!m_controller->config()->isBackground()) { return; } diff --git a/src/App_win.cpp b/src/App_win.cpp index b3a2c4cf3..9b923870e 100644 --- a/src/App_win.cpp +++ b/src/App_win.cpp @@ -27,18 +27,12 @@ #include "App.h" -#include "Cpu.h" #include "core/Controller.h" #include "core/Config.h" void App::background() { - const int64_t affinity = m_controller->config()->affinity(); - if (affinity != -1L) { - Cpu::setAffinity(-1, affinity); - } - if (!m_controller->config()->isBackground()) { return; } diff --git a/src/Cpu.h b/src/Cpu.h index e739ccce4..97e593ed8 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -42,7 +42,6 @@ public: static int optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage); static void init(); - static void setAffinity(int id, uint64_t mask); static inline bool hasAES() { return (m_flags & AES) != 0; } static inline bool isX64() { return (m_flags & X86_64) != 0; } diff --git a/src/Cpu_unix.cpp b/src/Cpu_unix.cpp index 9a13e7a52..b895c8979 100644 --- a/src/Cpu_unix.cpp +++ b/src/Cpu_unix.cpp @@ -52,28 +52,3 @@ void Cpu::init() initCommon(); } - - -void Cpu::setAffinity(int id, uint64_t mask) -{ - cpu_set_t set; - CPU_ZERO(&set); - - for (int i = 0; i < m_totalThreads; i++) { - if (mask & (1UL << i)) { - CPU_SET(i, &set); - } - } - - if (id == -1) { -# ifndef __FreeBSD__ - sched_setaffinity(0, sizeof(&set), &set); -# endif - } else { -# ifndef __ANDROID__ - pthread_setaffinity_np(pthread_self(), sizeof(&set), &set); -# else - sched_setaffinity(gettid(), sizeof(&set), &set); -# endif - } -} diff --git a/src/Cpu_win.cpp b/src/Cpu_win.cpp index 13113a178..7258f7266 100644 --- a/src/Cpu_win.cpp +++ b/src/Cpu_win.cpp @@ -39,14 +39,3 @@ void Cpu::init() initCommon(); } - - -void Cpu::setAffinity(int id, uint64_t mask) -{ - if (id == -1) { - SetProcessAffinityMask(GetCurrentProcess(), mask); - } - else { - SetThreadAffinityMask(GetCurrentThread(), mask); - } -} diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 0dd833d7f..df7aaad2e 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -34,10 +34,10 @@ #endif +#include "common/xmrig.h" #include "crypto/CryptoNight.h" #include "log/Log.h" #include "Mem.h" -#include "xmrig.h" bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) diff --git a/src/common/Platform.cpp b/src/common/Platform.cpp index 4ddb14296..52b55987f 100644 --- a/src/common/Platform.cpp +++ b/src/common/Platform.cpp @@ -29,16 +29,16 @@ #include "Platform.h" -char *Platform::m_defaultConfigName = nullptr; -char *Platform::m_userAgent = nullptr; +char Platform::m_defaultConfigName[520] = { 0 }; +xmrig::c_str Platform::m_userAgent; const char *Platform::defaultConfigName() { size_t size = 520; - if (m_defaultConfigName == nullptr) { - m_defaultConfigName = new char[size]; + if (*m_defaultConfigName) { + return m_defaultConfigName; } if (uv_exepath(m_defaultConfigName, &size) < 0) { @@ -58,5 +58,6 @@ const char *Platform::defaultConfigName() } } + *m_defaultConfigName = '\0'; return nullptr; } diff --git a/src/common/Platform.h b/src/common/Platform.h index 87c8cc4db..8704604a8 100644 --- a/src/common/Platform.h +++ b/src/common/Platform.h @@ -25,20 +25,26 @@ #define __PLATFORM_H__ +#include + + +#include "common/utils/c_str.h" + + class Platform { public: + static bool setThreadAffinity(uint64_t cpu_id); static const char *defaultConfigName(); static void init(const char *userAgent); - static void release(); static void setProcessPriority(int priority); static void setThreadPriority(int priority); - static inline const char *userAgent() { return m_userAgent; } + static inline const char *userAgent() { return m_userAgent.data(); } private: - static char *m_defaultConfigName; - static char *m_userAgent; + static char m_defaultConfigName[520]; + static xmrig::c_str m_userAgent; }; diff --git a/src/common/Platform_mac.cpp b/src/common/Platform_mac.cpp index ba541f1d0..b8181cc49 100644 --- a/src/common/Platform_mac.cpp +++ b/src/common/Platform_mac.cpp @@ -22,6 +22,8 @@ */ +#include +#include #include #include #include @@ -53,15 +55,24 @@ static inline char *createUserAgent() } -void Platform::init(const char *userAgent) +bool Platform::setThreadAffinity(uint64_t cpu_id) { - m_userAgent = userAgent ? strdup(userAgent) : createUserAgent(); + thread_port_t mach_thread; + thread_affinity_policy_data_t policy = { static_cast(cpu_id) }; + mach_thread = pthread_mach_thread_np(pthread_self()); + + return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS; } -void Platform::release() +void Platform::init(const char *userAgent) { - delete [] m_userAgent; + if (userAgent) { + m_userAgent = userAgent; + } + else { + m_userAgent = createUserAgent(); + } } diff --git a/src/common/Platform_unix.cpp b/src/common/Platform_unix.cpp index c05893072..624594e9b 100644 --- a/src/common/Platform_unix.cpp +++ b/src/common/Platform_unix.cpp @@ -21,6 +21,14 @@ * along with this program. If not, see . */ +#ifdef __FreeBSD__ +# include +# include +# include +# include +#endif + + #include #include #include @@ -37,6 +45,11 @@ #endif +#ifdef __FreeBSD__ +typedef cpuset_t cpu_set_t; +#endif + + static inline char *createUserAgent() { const size_t max = 160; @@ -63,15 +76,28 @@ static inline char *createUserAgent() } -void Platform::init(const char *userAgent) +bool Platform::setThreadAffinity(uint64_t cpu_id) { - m_userAgent = userAgent ? strdup(userAgent) : createUserAgent(); + cpu_set_t mn; + CPU_ZERO(&mn); + CPU_SET(cpu_id, &mn); + +# ifndef __ANDROID__ + return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mn) == 0; +# else + return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0; +# endif } -void Platform::release() +void Platform::init(const char *userAgent) { - delete [] m_userAgent; + if (userAgent) { + m_userAgent = userAgent; + } + else { + m_userAgent = createUserAgent(); + } } diff --git a/src/common/Platform_win.cpp b/src/common/Platform_win.cpp index 880bdd982..47f418671 100644 --- a/src/common/Platform_win.cpp +++ b/src/common/Platform_win.cpp @@ -27,9 +27,11 @@ #include +#include "log/Log.h" #include "Platform.h" #include "version.h" + #ifdef XMRIG_NVIDIA_PROJECT # include "nvidia/cryptonight.h" #endif @@ -82,16 +84,24 @@ static inline char *createUserAgent() } -void Platform::init(const char *userAgent) +bool Platform::setThreadAffinity(uint64_t cpu_id) { - m_userAgent = userAgent ? strdup(userAgent) : createUserAgent(); + if (cpu_id >= 64) { + LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63."); + } + + return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0; } -void Platform::release() +void Platform::init(const char *userAgent) { - delete [] m_defaultConfigName; - delete [] m_userAgent; + if (userAgent) { + m_userAgent = userAgent; + } + else { + m_userAgent = createUserAgent(); + } } @@ -131,7 +141,6 @@ void Platform::setProcessPriority(int priority) } - void Platform::setThreadPriority(int priority) { if (priority == -1) { diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index f120c0c12..5f0a9bb3d 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -73,7 +73,6 @@ xmrig::Controller::Controller() xmrig::Controller::~Controller() { ConfigLoader::release(); - Platform::release(); delete d_ptr; } diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 01d032e9b..29f57fb25 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,8 +25,7 @@ #include "workers/Handle.h" -Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity) : - m_affinity(affinity), +Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays) : m_worker(nullptr), m_totalThreads(totalThreads), m_totalWays(totalWays), diff --git a/src/workers/Handle.h b/src/workers/Handle.h index 8a64922a5..b3a7c76f7 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -38,11 +38,10 @@ class IWorker; class Handle { public: - Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity); + Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays); void join(); void start(void (*callback) (void *)); - inline int64_t affinity() const { return m_affinity; } inline IWorker *worker() const { return m_worker; } inline size_t threadId() const { return m_config->index(); } inline size_t totalThreads() const { return m_totalThreads; } @@ -51,7 +50,6 @@ public: inline xmrig::IThread *config() const { return m_config; } private: - int64_t m_affinity; IWorker *m_worker; size_t m_totalThreads; size_t m_totalWays; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 30305ac6e..594343904 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -42,11 +42,11 @@ Worker::Worker(Handle *handle) : m_sequence(0), m_thread(static_cast(handle->config())) { - if (Cpu::threads() > 1 && handle->affinity() != -1L) { - Cpu::setAffinity(m_id, handle->affinity()); + if (Cpu::threads() > 1 && m_thread->affinity() != -1L) { + Platform::setThreadAffinity(m_thread->affinity()); } - Platform::setThreadPriority(handle->config()->priority()); + Platform::setThreadPriority(m_thread->priority()); m_ctx = Mem::create(m_id); } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 38965d8ad..00941c7be 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -130,7 +130,7 @@ void Workers::start(xmrig::Controller *controller) uv_timer_start(&m_timer, Workers::onTick, 500, 500); for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, threads.size(), totalWays, controller->config()->affinity()); + Handle *handle = new Handle(thread, threads.size(), totalWays); m_workers.push_back(handle); handle->start(Workers::onReady); } From c44b2997504b93e0e47cce634cc494daf3ead088 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 17:59:27 +0700 Subject: [PATCH 06/25] Added reader for advanced threads. --- src/common/xmrig.h | 7 +++++++ src/core/Config.cpp | 40 +++++++++++++++++++++++++++------------ src/core/Config.h | 25 ++++++++++++++++++------ src/workers/CpuThread.cpp | 27 ++++++++++++++++++++++++++ src/workers/CpuThread.h | 20 ++++++++++++++++++++ 5 files changed, 101 insertions(+), 18 deletions(-) diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 7196aee3f..0aa6b8425 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -64,6 +64,13 @@ enum Variant { }; +enum AesMode { + AES_AUTO, + AES_HW, + AES_SOFT +}; + + } /* namespace xmrig */ diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 07f111925..2b8809ff7 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -41,6 +41,7 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : xmrig::CommonConfig(), + m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), m_doubleHash(false), m_dryRun(false), @@ -48,9 +49,7 @@ xmrig::Config::Config() : xmrig::CommonConfig(), m_safe(false), m_maxCpuUsage(75), m_printTime(60), - m_priority(-1), - m_affinity(-1L), - m_threadsCount(0) + m_priority(-1) { } @@ -162,18 +161,18 @@ bool xmrig::Config::adjust() m_doubleHash = true; } - if (!m_threadsCount) { - m_threadsCount = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + if (!m_threads.count) { + m_threads.count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); } else if (m_safe) { const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); - if (m_threadsCount > count) { - m_threadsCount = count; + if (m_threads.count > count) { + m_threads.count = count; } } - for (size_t i = 0; i < m_threadsCount; ++i) { - m_threads.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_affinity, m_priority)); + for (size_t i = 0; i < m_threads.count; ++i) { + m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_threads.mask, m_priority)); } return true; @@ -228,7 +227,7 @@ bool xmrig::Config::parseString(int key, const char *arg) case xmrig::IConfig::ThreadsKey: /* --threads */ if (strncmp(arg, "all", 3) == 0) { - m_threadsCount = Cpu::threads(); + m_threads.count = Cpu::threads(); return true; } @@ -257,7 +256,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg) switch (key) { case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ if (arg) { - m_affinity = arg; + m_threads.mask = arg; } break; @@ -271,6 +270,23 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg) void xmrig::Config::parseJSON(const rapidjson::Document &doc) { + const rapidjson::Value &threads = doc["threads"]; + + if (threads.IsArray()) { + for (const rapidjson::Value &value : threads.GetArray()) { + if (!value.IsObject()) { + continue; + } + + if (value.HasMember("low_power_mode")) { + auto data = CpuThread::parse(value); + + if (data.valid) { + m_threads.cpu.push_back(std::move(data)); + } + } + } + } } @@ -279,7 +295,7 @@ bool xmrig::Config::parseInt(int key, int arg) switch (key) { case xmrig::IConfig::ThreadsKey: /* --threads */ if (arg >= 0 && arg < 1024) { - m_threadsCount = arg; + m_threads.count = arg; } break; diff --git a/src/core/Config.h b/src/core/Config.h index fd33b614f..657679ec3 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -32,6 +32,7 @@ #include "common/config/CommonConfig.h" #include "common/xmrig.h" #include "rapidjson/fwd.h" +#include "workers/CpuThread.h" class Addr; @@ -67,15 +68,16 @@ public: void getJSON(rapidjson::Document &doc) const override; + inline AesMode aesMode() const { return m_aesMode; } inline AlgoVariant algoVariant() const { return m_algoVariant; } inline bool isDoubleHash() const { return m_doubleHash; } inline bool isDryRun() const { return m_dryRun; } inline bool isHugePages() const { return m_hugePages; } - inline const std::vector &threads() const { return m_threads; } + inline const std::vector &threads() const { return m_threads.list; } inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } - inline int threadsCount() const { return m_threadsCount; } - inline int64_t affinity() const { return m_affinity; } + inline int threadsCount() const { return m_threads.count; } + inline int64_t affinity() const { return m_threads.mask; } static Config *load(int argc, char **argv, IWatcherListener *listener); @@ -94,6 +96,19 @@ private: AlgoVariant getAlgoVariantLite() const; # endif + + struct Threads + { + inline Threads() : mask(-1L), count(0) {} + + int64_t mask; + size_t count; + std::vector cpu; + std::vector list; + }; + + + AesMode m_aesMode; AlgoVariant m_algoVariant; bool m_doubleHash; bool m_dryRun; @@ -102,9 +117,7 @@ private: int m_maxCpuUsage; int m_printTime; int m_priority; - int64_t m_affinity; - size_t m_threadsCount; - std::vector m_threads; + Threads m_threads; }; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 20a8006fb..5a707a585 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -197,6 +197,33 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } +xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) +{ + Data data; + + const auto &multiway = object["low_power_mode"]; + if (multiway.IsBool()) { + data.multiway = multiway.IsTrue() ? DoubleWay : SingleWay; + data.valid = true; + } + else if (multiway.IsUint()) { + data.setMultiway(multiway.GetInt()); + } + + if (!data.valid) { + return data; + } + + const auto &affinity = object["affine_to_cpu"]; + + if (affinity.IsUint64()) { + data.affinity = affinity.GetInt64(); + } + + return data; +} + + #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index dadd0424b..f9640a6c3 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -46,6 +46,25 @@ public: PentaWay }; + + struct Data + { + inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} + + inline void setMultiway(int value) + { + if (value >= SingleWay && value <= PentaWay) { + multiway = static_cast(value); + valid = true; + } + } + + bool valid; + int64_t affinity; + Multiway multiway; + }; + + CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); ~CpuThread(); @@ -53,6 +72,7 @@ public: static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); + static Data parse(const rapidjson::Value &object); inline bool isPrefetch() const { return m_prefetch; } inline bool isSoftAES() const { return m_softAES; } From c81401ab2d2aabfc8219cdeee11f8fc5c7b79321 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 14 Apr 2018 07:01:12 +0700 Subject: [PATCH 07/25] Basic advanced config reader, only single hash supported. --- src/core/Config.cpp | 12 ++++++++++++ src/core/Config.h | 2 +- src/log/Log.cpp | 12 ++++++++++-- src/log/Log.h | 21 +++++++++++++++------ src/workers/CpuThread.cpp | 18 ++++++++++++++++++ src/workers/CpuThread.h | 1 + src/workers/Workers.cpp | 7 +++++-- 7 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 2b8809ff7..ddce69806 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -156,6 +156,18 @@ bool xmrig::Config::adjust() return false; } + if (m_aesMode == AES_AUTO) { + m_aesMode = Cpu::hasAES() ? AES_SOFT : AES_SOFT; + } + + if (!m_threads.cpu.empty()) { + for (size_t i = 0; i < m_threads.cpu.size(); ++i) { + m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, m_aesMode == AES_SOFT)); + } + + return true; + } + m_algoVariant = getAlgoVariant(); if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) { m_doubleHash = true; diff --git a/src/core/Config.h b/src/core/Config.h index 657679ec3..720557a7d 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -76,7 +76,7 @@ public: inline const std::vector &threads() const { return m_threads.list; } inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } - inline int threadsCount() const { return m_threads.count; } + inline int threadsCount() const { return m_threads.list.size(); } inline int64_t affinity() const { return m_threads.mask; } static Config *load(int argc, char **argv, IWatcherListener *listener); diff --git a/src/log/Log.cpp b/src/log/Log.cpp index 3e5d5671a..131faa54b 100644 --- a/src/log/Log.cpp +++ b/src/log/Log.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * 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 @@ -38,6 +38,8 @@ Log *Log::m_self = nullptr; void Log::message(Log::Level level, const char* fmt, ...) { + uv_mutex_lock(&m_mutex); + va_list args; va_list copy; va_start(args, fmt); @@ -47,11 +49,15 @@ void Log::message(Log::Level level, const char* fmt, ...) backend->message(level, fmt, copy); va_end(copy); } + + uv_mutex_unlock(&m_mutex); } void Log::text(const char* fmt, ...) { + uv_mutex_lock(&m_mutex); + va_list args; va_list copy; va_start(args, fmt); @@ -63,6 +69,8 @@ void Log::text(const char* fmt, ...) } va_end(args); + + uv_mutex_unlock(&m_mutex); } diff --git a/src/log/Log.h b/src/log/Log.h index fd944d800..f8c6a4016 100644 --- a/src/log/Log.h +++ b/src/log/Log.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * 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 @@ -25,6 +25,7 @@ #define __LOG_H__ +#include #include #include @@ -54,20 +55,28 @@ public: constexpr static const char* kCL_GRAY = "\x1B[90m"; # endif - static inline Log* i() { return m_self; } + static inline Log* i() { assert(m_self != nullptr); return m_self; } static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); } - static inline void init() { if (!m_self) { m_self = new Log();} } - static inline void release() { delete m_self; } + static inline void init() { if (!m_self) { new Log(); } } + static inline void release() { assert(m_self != nullptr); delete m_self; } void message(Level level, const char* fmt, ...); void text(const char* fmt, ...); private: - inline Log() {} + inline Log() { + assert(m_self == nullptr); + + uv_mutex_init(&m_mutex); + + m_self = this; + } + ~Log(); static Log *m_self; std::vector m_backends; + uv_mutex_t m_mutex; }; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 5a707a585..07fbbb64e 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -197,6 +197,24 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } +xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES) +{ + int av = AV_AUTO; + const Multiway multiway = data.multiway; + + if (multiway <= DoubleWay) { + av = softAES ? (multiway + 2) : multiway; + } + else { + av = softAES ? (multiway + 5) : (multiway + 2); + } + + assert(av > AV_AUTO && av < AV_MAX); + + return new CpuThread(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false); +} + + xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) { Data data; diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index f9640a6c3..9d1bc4e73 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -72,6 +72,7 @@ public: static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); + static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); inline bool isPrefetch() const { return m_prefetch; } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 00941c7be..44ac399f3 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -112,6 +112,8 @@ void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); + LOG_NOTICE("- %d", std::this_thread::get_id()); + size_t totalWays = 0; for (const xmrig::IThread *thread : threads) { totalWays += thread->multiway(); @@ -165,6 +167,9 @@ void Workers::submit(const JobResult &result) void Workers::onReady(void *arg) { auto handle = static_cast(arg); + + LOG_NOTICE("%zu %d", handle->threadId(), std::this_thread::get_id()); + if (Mem::isDoubleHash()) { handle->setWorker(new DoubleWorker(handle)); } @@ -175,9 +180,7 @@ void Workers::onReady(void *arg) const bool rc = handle->worker()->start(); if (!rc) { - uv_mutex_lock(&m_mutex); LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); - uv_mutex_unlock(&m_mutex); } } From 4b71b7aa29e6ff89e20e8679625f4599edf75b40 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 14 Apr 2018 22:14:57 +0700 Subject: [PATCH 08/25] Added class MultiWorker and remove classes SingleWorker and DoubleWorker. --- CMakeLists.txt | 6 +- src/interfaces/IWorker.h | 3 +- src/net/Job.cpp | 11 + src/net/Job.h | 4 + src/workers/DoubleWorker.cpp | 189 ------------------ src/workers/DoubleWorker.h | 59 ------ src/workers/Handle.cpp | 4 +- src/workers/Handle.h | 9 +- .../{SingleWorker.cpp => MultiWorker.cpp} | 135 +++++++------ src/workers/{SingleWorker.h => MultiWorker.h} | 34 +++- src/workers/Worker.cpp | 4 +- src/workers/Worker.h | 8 +- src/workers/Workers.cpp | 52 +++-- 13 files changed, 173 insertions(+), 345 deletions(-) delete mode 100644 src/workers/DoubleWorker.cpp delete mode 100644 src/workers/DoubleWorker.h rename src/workers/{SingleWorker.cpp => MultiWorker.cpp} (61%) rename src/workers/{SingleWorker.h => MultiWorker.h} (72%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8d381d44..ecb65b228 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,10 +55,9 @@ set(HEADERS src/Summary.h src/version.h src/workers/CpuThread.h - src/workers/DoubleWorker.h src/workers/Handle.h src/workers/Hashrate.h - src/workers/SingleWorker.h + src/workers/MultiWorker.h src/workers/Worker.h src/workers/Workers.h ) @@ -109,10 +108,9 @@ set(SOURCES src/net/SubmitResult.cpp src/Summary.cpp src/workers/CpuThread.cpp - src/workers/DoubleWorker.cpp src/workers/Handle.cpp src/workers/Hashrate.cpp - src/workers/SingleWorker.cpp + src/workers/MultiWorker.cpp src/workers/Worker.cpp src/workers/Workers.cpp src/xmrig.cpp diff --git a/src/interfaces/IWorker.h b/src/interfaces/IWorker.h index a90abe11c..90394c2cc 100644 --- a/src/interfaces/IWorker.h +++ b/src/interfaces/IWorker.h @@ -33,10 +33,11 @@ class IWorker public: virtual ~IWorker() {} - virtual bool start() = 0; + virtual bool selfTest() = 0; virtual size_t id() const = 0; virtual uint64_t hashCount() const = 0; virtual uint64_t timestamp() const = 0; + virtual void start() = 0; }; diff --git a/src/net/Job.cpp b/src/net/Job.cpp index 17d8266f9..1434c87f5 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -209,6 +209,17 @@ void Job::toHex(const unsigned char* in, unsigned int len, char* out) } +#ifdef APP_DEBUG +char *Job::toHex(const unsigned char* in, unsigned int len) +{ + char *out = new char[len * 2 + 1](); + toHex(in, len, out); + + return out; +} +#endif + + bool Job::operator==(const Job &other) const { return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0; diff --git a/src/net/Job.h b/src/net/Job.h index a60f061ce..ee4728e33 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -69,6 +69,10 @@ public: static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } static void toHex(const unsigned char* in, unsigned int len, char* out); +# ifdef APP_DEBUG + static char *toHex(const unsigned char* in, unsigned int len); +# endif + bool operator==(const Job &other) const; bool operator!=(const Job &other) const; diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp deleted file mode 100644 index 6ba5c47fe..000000000 --- a/src/workers/DoubleWorker.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2016-2018 XMRig , - * - * 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 . - */ - - -#include - - -#include "crypto/CryptoNight_test.h" -#include "workers/CpuThread.h" -#include "workers/DoubleWorker.h" -#include "workers/Workers.h" - - -class DoubleWorker::State -{ -public: - inline State() : - nonce1(0), - nonce2(0) - {} - - Job job; - uint32_t nonce1; - uint32_t nonce2; - uint8_t blob[84 * 2]; -}; - - -DoubleWorker::DoubleWorker(Handle *handle) - : Worker(handle) -{ - m_state = new State(); - m_pausedState = new State(); -} - - -DoubleWorker::~DoubleWorker() -{ - delete m_state; - delete m_pausedState; -} - - -bool DoubleWorker::start() -{ - if (!selfTest()) { - return false; - } - - while (Workers::sequence() > 0) { - if (Workers::isPaused()) { - do { - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - } - while (Workers::isPaused()); - - if (Workers::sequence() == 0) { - break; - } - - consumeJob(); - } - - while (!Workers::isOutdated(m_sequence)) { - if ((m_count & 0xF) == 0) { - storeStats(); - } - - m_count += 2; - *Job::nonce(m_state->blob) = ++m_state->nonce1; - *Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2; - - m_thread->fn(m_state->job.variant())(m_state->blob, m_state->job.size(), m_hash, m_ctx); - - if (*reinterpret_cast(m_hash + 24) < m_state->job.target()) { - Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff())); - } - - if (*reinterpret_cast(m_hash + 32 + 24) < m_state->job.target()) { - Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff())); - } - - std::this_thread::yield(); - } - - consumeJob(); - } - - return true; -} - - -bool DoubleWorker::resume(const Job &job) -{ - if (m_state->job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState->job.id()) { - *m_state = *m_pausedState; - return true; - } - - return false; -} - - -bool DoubleWorker::selfTest() -{ - if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { - return false; - } - - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx); - - if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, 64) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - - return memcmp(m_hash, test_output_v1, 64) == 0; - } - -# ifndef XMRIG_NO_AEON - if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, 64) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - - return memcmp(m_hash, test_output_v1_lite, 64) == 0; - } -# endif - -# ifndef XMRIG_NO_SUMO - return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, 64) == 0; -# else - return false; -# endif -} - - -void DoubleWorker::consumeJob() -{ - Job job = Workers::job(); - m_sequence = Workers::sequence(); - if (m_state->job == job) { - return; - } - - save(job); - - if (resume(job)) { - return; - } - - m_state->job = std::move(job); - memcpy(m_state->blob, m_state->job.blob(), m_state->job.size()); - memcpy(m_state->blob + m_state->job.size(), m_state->job.blob(), m_state->job.size()); - - if (m_state->job.isNicehash()) { - m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / m_totalWays * m_id); - m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / m_totalWays * (m_id + m_totalThreads)); - } - else { - m_state->nonce1 = 0xffffffffU / m_totalWays * m_id; - m_state->nonce2 = 0xffffffffU / m_totalWays * (m_id + m_totalThreads); - } -} - - -void DoubleWorker::save(const Job &job) -{ - if (job.poolId() == -1 && m_state->job.poolId() >= 0) { - *m_pausedState = *m_state; - } -} diff --git a/src/workers/DoubleWorker.h b/src/workers/DoubleWorker.h deleted file mode 100644 index e8847282b..000000000 --- a/src/workers/DoubleWorker.h +++ /dev/null @@ -1,59 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2016-2018 XMRig , - * - * 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 . - */ - -#ifndef __DOUBLEWORKER_H__ -#define __DOUBLEWORKER_H__ - - -#include "net/Job.h" -#include "net/JobResult.h" -#include "workers/Worker.h" - - -class Handle; - - -class DoubleWorker : public Worker -{ -public: - DoubleWorker(Handle *handle); - ~DoubleWorker(); - - bool start() override; - -private: - bool resume(const Job &job); - bool selfTest(); - void consumeJob(); - void save(const Job &job); - - class State; - - uint8_t m_hash[64]; - State *m_state; - State *m_pausedState; -}; - - -#endif /* __SINGLEWORKER_H__ */ diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 29f57fb25..d42ea3689 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,10 +25,10 @@ #include "workers/Handle.h" -Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays) : +Handle::Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays) : m_worker(nullptr), - m_totalThreads(totalThreads), m_totalWays(totalWays), + m_offset(offset), m_config(config) { } diff --git a/src/workers/Handle.h b/src/workers/Handle.h index b3a7c76f7..4bb899f9f 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -25,6 +25,7 @@ #define __HANDLE_H__ +#include #include #include @@ -38,21 +39,21 @@ class IWorker; class Handle { public: - Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays); + Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays); void join(); void start(void (*callback) (void *)); inline IWorker *worker() const { return m_worker; } inline size_t threadId() const { return m_config->index(); } - inline size_t totalThreads() const { return m_totalThreads; } inline size_t totalWays() const { return m_totalWays; } - inline void setWorker(IWorker *worker) { m_worker = worker; } + inline uint32_t offset() const { return m_offset; } + inline void setWorker(IWorker *worker) { assert(worker != nullptr); m_worker = worker; } inline xmrig::IThread *config() const { return m_config; } private: IWorker *m_worker; - size_t m_totalThreads; size_t m_totalWays; + uint32_t m_offset; uv_thread_t m_thread; xmrig::IThread *m_config; }; diff --git a/src/workers/SingleWorker.cpp b/src/workers/MultiWorker.cpp similarity index 61% rename from src/workers/SingleWorker.cpp rename to src/workers/MultiWorker.cpp index 815b965dd..0007b0cb5 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -28,22 +28,51 @@ #include "crypto/CryptoNight_test.h" #include "workers/CpuThread.h" -#include "workers/SingleWorker.h" +#include "workers/MultiWorker.h" #include "workers/Workers.h" -SingleWorker::SingleWorker(Handle *handle) +template +MultiWorker::MultiWorker(Handle *handle) : Worker(handle) { } -bool SingleWorker::start() +template +bool MultiWorker::selfTest() { - if (!selfTest()) { + if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { return false; } + m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctxLegacy); + + if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + + return memcmp(m_result.result, test_output_v1, 32) == 0; + } + +# ifndef XMRIG_NO_AEON + if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + + return memcmp(m_result.result, test_output_v1_lite, 32) == 0; + } +# endif + +# ifndef XMRIG_NO_SUMO + return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; +# else + return false; +# endif +} + + +template +void MultiWorker::start() +{ while (Workers::sequence() > 0) { if (Workers::isPaused()) { do { @@ -59,34 +88,35 @@ bool SingleWorker::start() } while (!Workers::isOutdated(m_sequence)) { - if ((m_count & 0xF) == 0) { + if ((m_count & 0x7) == 0) { storeStats(); } - m_count++; - *m_job.nonce() = ++m_result.nonce; + m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctxLegacy); - m_thread->fn(m_job.variant())(m_job.blob(), m_job.size(), m_result.result, m_ctx); - if (*reinterpret_cast(m_result.result + 24) < m_job.target()) { - Workers::submit(m_result); + for (size_t i = 0; i < N; ++i) { + if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash, m_state.job.diff())); + } + + *nonce(i) += 1; } + m_count += N; + std::this_thread::yield(); } consumeJob(); } - - return true; } -bool SingleWorker::resume(const Job &job) +template +bool MultiWorker::resume(const Job &job) { - if (m_job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_paused.id()) { - m_job = m_paused; - m_result = m_job; - m_result.nonce = *m_job.nonce(); + if (m_state.job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState.job.id()) { + m_state = m_pausedState; return true; } @@ -94,41 +124,12 @@ bool SingleWorker::resume(const Job &job) } -bool SingleWorker::selfTest() -{ - if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { - return false; - } - - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctx); - - if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx); - - return memcmp(m_result.result, test_output_v1, 32) == 0; - } - -# ifndef XMRIG_NO_AEON - if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx); - - return memcmp(m_result.result, test_output_v1_lite, 32) == 0; - } -# endif - -# ifndef XMRIG_NO_SUMO - return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; -# else - return false; -# endif -} - - -void SingleWorker::consumeJob() +template +void MultiWorker::consumeJob() { Job job = Workers::job(); m_sequence = Workers::sequence(); - if (m_job == job) { + if (m_state.job == job) { return; } @@ -138,21 +139,39 @@ void SingleWorker::consumeJob() return; } - m_job = std::move(job); - m_result = m_job; + m_state.job = job; - if (m_job.isNicehash()) { - m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_totalWays * m_id); + const size_t size = m_state.job.size(); + memcpy(m_state.blob, m_state.job.blob(), m_state.job.size()); + + if (N > 1) { + for (size_t i = 1; i < N; ++i) { + memcpy(m_state.blob + (i * size), m_state.blob, size); + } } - else { - m_result.nonce = 0xffffffffU / m_totalWays * m_id; + + for (size_t i = 0; i < N; ++i) { + if (m_state.job.isNicehash()) { + *nonce(i) = (*nonce(i) & 0xff000000U) + (0xffffffU / m_totalWays * (m_offset + i)); + } + else { + *nonce(i) = 0xffffffffU / m_totalWays * (m_offset + i); + } } } -void SingleWorker::save(const Job &job) +template +void MultiWorker::save(const Job &job) { - if (job.poolId() == -1 && m_job.poolId() >= 0) { - m_paused = m_job; + if (job.poolId() == -1 && m_state.job.poolId() >= 0) { + m_pausedState = m_state; } } + + +template class MultiWorker<1>; +template class MultiWorker<2>; +template class MultiWorker<3>; +template class MultiWorker<4>; +template class MultiWorker<5>; diff --git a/src/workers/SingleWorker.h b/src/workers/MultiWorker.h similarity index 72% rename from src/workers/SingleWorker.h rename to src/workers/MultiWorker.h index 061f50848..d384b0ba1 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/MultiWorker.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef __SINGLEWORKER_H__ -#define __SINGLEWORKER_H__ +#ifndef __MULTIWORKER_H__ +#define __MULTIWORKER_H__ #include "net/Job.h" @@ -34,23 +34,43 @@ class Handle; -class SingleWorker : public Worker +template +class MultiWorker : public Worker { public: - SingleWorker(Handle *handle); + MultiWorker(Handle *handle); - bool start() override; +protected: + bool selfTest() override; + void start() override; private: bool resume(const Job &job); - bool selfTest(); void consumeJob(); void save(const Job &job); + inline uint32_t *nonce(size_t index) + { + return reinterpret_cast(m_state.blob + (index * m_state.job.size()) + 39); + } + + struct State + { + alignas(16) uint8_t blob[96 * N]; + Job job; + }; + + +// cryptonight_ctx *m_ctx[N]; + + uint8_t m_hash[N * 32]; + State m_state; + State m_pausedState; + Job m_job; Job m_paused; JobResult m_result; }; -#endif /* __SINGLEWORKER_H__ */ +#endif /* __MULTIWORKER_H__ */ diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 594343904..e0ed846b2 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -34,8 +34,8 @@ Worker::Worker(Handle *handle) : m_id(handle->threadId()), - m_totalThreads(handle->totalThreads()), m_totalWays(handle->totalWays()), + m_offset(handle->offset()), m_hashCount(0), m_timestamp(0), m_count(0), @@ -47,7 +47,7 @@ Worker::Worker(Handle *handle) : } Platform::setThreadPriority(m_thread->priority()); - m_ctx = Mem::create(m_id); + m_ctxLegacy = Mem::create(m_id); } diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 88f6ee424..72b3beb2a 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -54,10 +54,10 @@ public: protected: void storeStats(); - cryptonight_ctx *m_ctx; - size_t m_id; - size_t m_totalThreads; - size_t m_totalWays; + const size_t m_id; + const size_t m_totalWays; + const uint32_t m_offset; + cryptonight_ctx *m_ctxLegacy; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 44ac399f3..21379db43 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -30,15 +30,13 @@ #include "core/Controller.h" #include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" +#include "log/Log.h" #include "Mem.h" -#include "workers/DoubleWorker.h" #include "workers/Handle.h" #include "workers/Hashrate.h" -#include "workers/SingleWorker.h" +#include "workers/MultiWorker.h" #include "workers/Workers.h" -#include "log/Log.h" - bool Workers::m_active = false; bool Workers::m_enabled = true; @@ -112,8 +110,6 @@ void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); - LOG_NOTICE("- %d", std::this_thread::get_id()); - size_t totalWays = 0; for (const xmrig::IThread *thread : threads) { totalWays += thread->multiway(); @@ -131,8 +127,12 @@ void Workers::start(xmrig::Controller *controller) uv_timer_init(uv_default_loop(), &m_timer); uv_timer_start(&m_timer, Workers::onTick, 500, 500); + uint32_t offset = 0; + for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, threads.size(), totalWays); + Handle *handle = new Handle(thread, offset, totalWays); + offset += thread->multiway(); + m_workers.push_back(handle); handle->start(Workers::onReady); } @@ -168,20 +168,42 @@ void Workers::onReady(void *arg) { auto handle = static_cast(arg); - LOG_NOTICE("%zu %d", handle->threadId(), std::this_thread::get_id()); + IWorker *worker = nullptr; - if (Mem::isDoubleHash()) { - handle->setWorker(new DoubleWorker(handle)); - } - else { - handle->setWorker(new SingleWorker(handle)); + switch (handle->config()->multiway()) { + case 1: + worker = new MultiWorker<1>(handle); + break; + + case 2: + worker = new MultiWorker<2>(handle); + break; + + case 3: + worker = new MultiWorker<3>(handle); + break; + + case 4: + worker = new MultiWorker<4>(handle); + break; + + case 5: + worker = new MultiWorker<5>(handle); + break; + + default: + break; } - const bool rc = handle->worker()->start(); + handle->setWorker(worker); - if (!rc) { + if (!worker->selfTest()) { LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); + + return; } + + worker->start(); } From 9125b6c2512bb5539424894c766ef178ded93fbd Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 11:08:47 +0700 Subject: [PATCH 09/25] Rewrite memory allocation. --- CMakeLists.txt | 1 + src/App.cpp | 8 +--- src/Mem.cpp | 79 ++++++++++++--------------------- src/Mem.h | 35 +++++++-------- src/Mem_unix.cpp | 60 ++++++++++--------------- src/Mem_win.cpp | 66 +++++++++++++-------------- src/Summary.cpp | 9 ++-- src/api/ApiRouter.cpp | 2 +- src/common/utils/mm_malloc.h | 43 ++++++++++++++++++ src/crypto/CryptoNight.h | 3 +- src/crypto/CryptoNight_arm.h | 8 +--- src/crypto/CryptoNight_monero.h | 2 +- src/crypto/CryptoNight_x86.h | 38 ++++++++-------- src/interfaces/IThread.h | 20 ++++++--- src/workers/CpuThread.h | 13 +----- src/workers/MultiWorker.cpp | 26 +++++++---- src/workers/MultiWorker.h | 14 +++--- src/workers/Worker.cpp | 7 --- src/workers/Worker.h | 2 - 19 files changed, 212 insertions(+), 224 deletions(-) create mode 100644 src/common/utils/mm_malloc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ecb65b228..c7017b01a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ set(HEADERS src/common/config/ConfigWatcher.h src/common/Platform.h src/common/utils/c_str.h + src/common/utils/mm_malloc.h src/common/xmrig.h src/Console.h src/core/Config.cpp diff --git a/src/App.cpp b/src/App.cpp index 3d0cb3df4..78d6b3287 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -76,8 +76,6 @@ App::App(int argc, char **argv) : App::~App() { - Mem::release(); - uv_tty_reset_mode(); delete m_console; @@ -101,11 +99,7 @@ int App::exec() background(); - Mem::allocate(m_controller->config()->algorithm(), - m_controller->config()->threadsCount(), - m_controller->config()->isDoubleHash(), - m_controller->config()->isHugePages() - ); + Mem::init(m_controller->config()->isHugePages()); Summary::print(m_controller); diff --git a/src/Mem.cpp b/src/Mem.cpp index 9de79dbd5..2efaac8a5 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -23,70 +23,49 @@ */ -#include - - +#include "common/utils/mm_malloc.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" #include "Mem.h" -bool Mem::m_doubleHash = false; -int Mem::m_algo = 0; -int Mem::m_flags = 0; -int Mem::m_threads = 0; -size_t Mem::m_offset = 0; -size_t Mem::m_size = 0; -alignas(16) uint8_t *Mem::m_memory = nullptr; +bool Mem::m_enabled = true; +int Mem::m_flags = 0; -cryptonight_ctx *Mem::create(int threadId) + +MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count) { + using namespace xmrig; + + MemInfo info; + info.size = cn_select_memory(algorithm) * count; + # ifndef XMRIG_NO_AEON - if (m_algo == xmrig::CRYPTONIGHT_LITE) { - return createLite(threadId); - } + info.size += info.size % cn_select_memory(); # endif - const size_t size = m_algo == xmrig::CRYPTONIGHT_HEAVY ? xmrig::cn_select_memory() - : xmrig::cn_select_memory(); + info.pages = info.size / cn_select_memory(); - cryptonight_ctx *ctx = reinterpret_cast(&m_memory[size - sizeof(cryptonight_ctx) * (threadId + 1)]); + allocate(info, m_enabled); - const int ratio = m_doubleHash ? 2 : 1; - ctx->memory = &m_memory[size * (threadId * ratio + 1)]; + for (size_t i = 0; i < count; ++i) { + cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 16)); + c->memory = info.memory + (i * cn_select_memory(algorithm)); - return ctx; -} - - - -void *Mem::calloc(size_t num, size_t size) -{ - void *mem = &m_memory[m_offset]; - m_offset += (num * size); - - memset(mem, 0, num * size); - - return mem; -} - - -#ifndef XMRIG_NO_AEON -cryptonight_ctx *Mem::createLite(int threadId) { - cryptonight_ctx *ctx; - - if (!m_doubleHash) { - const size_t offset = MONERO_MEMORY * (threadId + 1); - - ctx = reinterpret_cast(&m_memory[offset + AEON_MEMORY]); - ctx->memory = &m_memory[offset]; - return ctx; + ctx[i] = c; } - ctx = reinterpret_cast(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); - ctx->memory = &m_memory[MONERO_MEMORY * (threadId + 1)]; - - return ctx; + return info; } -#endif + + +void Mem::release(cryptonight_ctx **ctx, size_t count, MemInfo &info) +{ + release(info); + + for (size_t i = 0; i < count; ++i) { + _mm_free(ctx[i]); + } +} + diff --git a/src/Mem.h b/src/Mem.h index 06b470c8f..6fd18fc1b 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -36,6 +36,16 @@ struct cryptonight_ctx; +struct MemInfo +{ + alignas(16) uint8_t *memory; + + size_t hugePages; + size_t pages; + size_t size; +}; + + class Mem { public: @@ -45,29 +55,18 @@ public: Lock = 4 }; - static bool allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled); - static cryptonight_ctx *create(int threadId); - static void *calloc(size_t num, size_t size); - static void release(); + static MemInfo create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count); + static void init(bool enabled); + static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info); - static inline bool isDoubleHash() { return m_doubleHash; } static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; } - static inline bool isHugepagesEnabled() { return (m_flags & HugepagesEnabled) != 0; } - static inline int flags() { return m_flags; } - static inline int threads() { return m_threads; } private: - static bool m_doubleHash; - static int m_algo; - static int m_flags; - static int m_threads; - static size_t m_offset; - static size_t m_size; - alignas(16) static uint8_t *m_memory; + static void allocate(MemInfo &info, bool enabled); + static void release(MemInfo &info); -# ifndef XMRIG_NO_AEON - static cryptonight_ctx *createLite(int threadId); -# endif + static int m_flags; + static bool m_enabled; }; diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index df7aaad2e..550033c43 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -27,75 +27,63 @@ #include -#if defined(XMRIG_ARM) && !defined(__clang__) -# include "aligned_malloc.h" -#else -# include -#endif - - +#include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" #include "log/Log.h" #include "Mem.h" -bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) +void Mem::init(bool enabled) { - m_algo = algo; - m_threads = threads; - m_doubleHash = doubleHash; + m_enabled = enabled; +} - const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; - m_size = MONERO_MEMORY * (threads * ratio + 1); - if (algo == xmrig::CRYPTONIGHT_HEAVY) { - m_size *= 2; - } +void Mem::allocate(MemInfo &info, bool enabled) +{ + info.hugePages = 0; if (!enabled) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - return true; - } + info.memory = static_cast(_mm_malloc(info.size, 16)); - m_flags |= HugepagesAvailable; + return; + } # if defined(__APPLE__) - m_memory = static_cast(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0)); + info.memory = static_cast(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0)); # elif defined(__FreeBSD__) - m_memory = static_cast(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0)); + info.memory = static_cast(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0)); # else - m_memory = static_cast(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0)); + info.memory = static_cast(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0)); # endif - if (m_memory == MAP_FAILED) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - return true; + + if (info.memory == MAP_FAILED) { + return allocate(info, false);; } - m_flags |= HugepagesEnabled; + info.hugePages = info.pages; - if (madvise(m_memory, m_size, MADV_RANDOM | MADV_WILLNEED) != 0) { + if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) { LOG_ERR("madvise failed"); } - if (mlock(m_memory, m_size) == 0) { + if (mlock(info.memory, info.size) == 0) { m_flags |= Lock; } - - return true; } -void Mem::release() +void Mem::release(MemInfo &info) { - if (m_flags & HugepagesEnabled) { + if (info.hugePages) { if (m_flags & Lock) { - munlock(m_memory, m_size); + munlock(info.memory, info.size); } - munmap(m_memory, m_size); + munmap(info.memory, info.size); } else { - _mm_free(m_memory); + _mm_free(info.memory); } } diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 1f3066ea3..d0b698f67 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -28,14 +28,11 @@ #include #include -#ifdef __GNUC__ -# include -#else -# include -#endif +#include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" +#include "crypto/CryptoNight_constants.h" #include "log/Log.h" #include "Mem.h" @@ -145,46 +142,43 @@ static BOOL TrySetLockPagesPrivilege() { } -bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) +void Mem::init(bool enabled) { - m_algo = algo; - m_threads = threads; - m_doubleHash = doubleHash; + m_enabled = enabled; - const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; - m_size = MONERO_MEMORY * (threads * ratio + 1); - - if (algo == xmrig::CRYPTONIGHT_HEAVY) { - m_size *= 2; - } - - if (!enabled) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - return true; - } - - if (TrySetLockPagesPrivilege()) { + if (enabled && TrySetLockPagesPrivilege()) { m_flags |= HugepagesAvailable; } - - m_memory = static_cast(VirtualAlloc(NULL, m_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE)); - if (!m_memory) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - } - else { - m_flags |= HugepagesEnabled; - } - - return true; } -void Mem::release() +void Mem::allocate(MemInfo &info, bool enabled) { - if (m_flags & HugepagesEnabled) { - VirtualFree(m_memory, 0, MEM_RELEASE); + info.hugePages = 0; + + if (!enabled) { + info.memory = static_cast(_mm_malloc(info.size, 16)); + + return; + } + + info.memory = static_cast(VirtualAlloc(nullptr, info.size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE)); + if (info.memory) { + info.hugePages = info.pages; + + return; + } + + allocate(info, false); +} + + +void Mem::release(MemInfo &info) +{ + if (info.hugePages) { + VirtualFree(info.memory, 0, MEM_RELEASE); } else { - _mm_free(m_memory); + _mm_free(info.memory); } } diff --git a/src/Summary.cpp b/src/Summary.cpp index 5acda5c2f..a54214e46 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -58,14 +58,15 @@ static void print_versions(xmrig::Config *config) static void print_memory(xmrig::Config *config) { +# ifdef _WIN32 if (config->isColors()) { - Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s", - Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable", - Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled"); + Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s", + Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable"); } else { - Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled"); + Log::i()->text(" * HUGE PAGES: %s", Mem::isHugepagesAvailable() ? "available" : "unavailable"); } +# endif } diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index cb7a80051..0893bc8ba 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -267,7 +267,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("cpu", cpu, allocator); doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator); - doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator); + doc.AddMember("hugepages", false, allocator); doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); } diff --git a/src/common/utils/mm_malloc.h b/src/common/utils/mm_malloc.h new file mode 100644 index 000000000..30c721a34 --- /dev/null +++ b/src/common/utils/mm_malloc.h @@ -0,0 +1,43 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * 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 . + */ + +#ifndef __MM_MALLOC_PORTABLE_H__ +#define __MM_MALLOC_PORTABLE_H__ + + +#ifdef _WIN32 +# ifdef __GNUC__ +# include +# else +# include +# endif +#else +# if defined(XMRIG_ARM) && !defined(__clang__) +# include "aligned_malloc.h" +# else +# include +# endif +#endif + + +#endif /* __MM_MALLOC_PORTABLE_H__ */ diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index d0d61ae3b..5a4a266d5 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -40,8 +40,7 @@ struct cryptonight_ctx { - alignas(16) uint8_t state0[200]; - alignas(16) uint8_t state1[200]; + alignas(16) uint8_t state[200]; alignas(16) uint8_t* memory; }; diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index fd8b58fff..d9677d06f 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -27,13 +27,7 @@ #define __CRYPTONIGHT_ARM_H__ -#if defined(XMRIG_ARM) && !defined(__clang__) -# include "aligned_malloc.h" -#else -# include -#endif - - +#include "common/utils/mm_malloc.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_monero.h" diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h index a667a3b36..a34f3ba8c 100644 --- a/src/crypto/CryptoNight_monero.h +++ b/src/crypto/CryptoNight_monero.h @@ -32,7 +32,7 @@ uint64_t tweak1_2_##part = 0; \ if (VARIANT > 0) { \ tweak1_2_##part = (*reinterpret_cast(input + 35 + part * size) ^ \ - *(reinterpret_cast(ctx->state##part) + 24)); \ + *(reinterpret_cast(ctx[part]->state) + 24)); \ } #else # define VARIANT1_INIT(part) \ diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 417404a6d..824dd99c6 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -403,7 +403,7 @@ static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) template -inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -414,14 +414,14 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); + keccak(input, (int) size, ctx[0]->state, 200); VARIANT1_INIT(0) - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = reinterpret_cast(ctx->state0); + const uint8_t* l0 = ctx[0]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; @@ -476,15 +476,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } } - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } template -inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -495,16 +495,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); - keccak(input + size, (int) size, ctx->state1, 200); + keccak(input, (int) size, ctx[0]->state, 200); + keccak(input + size, (int) size, ctx[1]->state, 200); VARIANT1_INIT(0); VARIANT1_INIT(1); - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEM; - uint64_t* h0 = reinterpret_cast(ctx->state0); - uint64_t* h1 = reinterpret_cast(ctx->state1); + const uint8_t* l0 = ctx[0]->memory; + const uint8_t* l1 = ctx[1]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); @@ -606,25 +606,25 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si keccakf(h0, 24); keccakf(h1, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); } template -inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { } diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index 5b3efa0de..f517ed18a 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -43,14 +43,22 @@ public: CUDA }; + enum Multiway { + SingleWay = 1, + DoubleWay, + TripleWay, + QuadWay, + PentaWay + }; + virtual ~IThread() {} - virtual Algo algorithm() const = 0; - virtual int multiway() const = 0; - virtual int priority() const = 0; - virtual int64_t affinity() const = 0; - virtual size_t index() const = 0; - virtual Type type() const = 0; + virtual Algo algorithm() const = 0; + virtual int priority() const = 0; + virtual int64_t affinity() const = 0; + virtual Multiway multiway() const = 0; + virtual size_t index() const = 0; + virtual Type type() const = 0; # ifndef XMRIG_NO_API virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index 9d1bc4e73..e14c79f14 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -38,15 +38,6 @@ namespace xmrig { class CpuThread : public IThread { public: - enum Multiway { - SingleWay = 1, - DoubleWay, - TripleWay, - QuadWay, - PentaWay - }; - - struct Data { inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} @@ -68,7 +59,7 @@ public: CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); ~CpuThread(); - typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx); + typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx); static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); @@ -80,9 +71,9 @@ public: inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); } inline Algo algorithm() const override { return m_algorithm; } - inline int multiway() const override { return m_multiway; } inline int priority() const override { return m_priority; } inline int64_t affinity() const override { return m_affinity; } + inline Multiway multiway() const override { return m_multiway; } inline size_t index() const override { return m_index; } inline Type type() const override { return CPU; } diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 0007b0cb5..a75adecc4 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -36,6 +36,14 @@ template MultiWorker::MultiWorker(Handle *handle) : Worker(handle) { + m_memory = Mem::create(m_ctx, m_thread->algorithm(), N); +} + + +template +MultiWorker::~MultiWorker() +{ + Mem::release(m_ctx, N, m_memory); } @@ -46,24 +54,24 @@ bool MultiWorker::selfTest() return false; } - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctxLegacy); + m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx); - if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - return memcmp(m_result.result, test_output_v1, 32) == 0; + return memcmp(m_hash, test_output_v1, sizeof m_hash) == 0; } # ifndef XMRIG_NO_AEON - if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - return memcmp(m_result.result, test_output_v1_lite, 32) == 0; + return memcmp(m_hash, test_output_v1_lite, sizeof m_hash) == 0; } # endif # ifndef XMRIG_NO_SUMO - return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; + return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, sizeof m_hash) == 0; # else return false; # endif @@ -92,7 +100,7 @@ void MultiWorker::start() storeStats(); } - m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctxLegacy); + m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx); for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index d384b0ba1..ba57f81e4 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -26,6 +26,7 @@ #define __MULTIWORKER_H__ +#include "Mem.h" #include "net/Job.h" #include "net/JobResult.h" #include "workers/Worker.h" @@ -39,6 +40,7 @@ class MultiWorker : public Worker { public: MultiWorker(Handle *handle); + ~MultiWorker(); protected: bool selfTest() override; @@ -61,15 +63,11 @@ private: }; -// cryptonight_ctx *m_ctx[N]; - - uint8_t m_hash[N * 32]; - State m_state; + cryptonight_ctx *m_ctx[N]; + MemInfo m_memory; State m_pausedState; - - Job m_job; - Job m_paused; - JobResult m_result; + State m_state; + uint8_t m_hash[N * 32]; }; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index e0ed846b2..567b3e085 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -26,7 +26,6 @@ #include "common/Platform.h" #include "Cpu.h" -#include "Mem.h" #include "workers/CpuThread.h" #include "workers/Handle.h" #include "workers/Worker.h" @@ -47,12 +46,6 @@ Worker::Worker(Handle *handle) : } Platform::setThreadPriority(m_thread->priority()); - m_ctxLegacy = Mem::create(m_id); -} - - -Worker::~Worker() -{ } diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 72b3beb2a..0ae305302 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -45,7 +45,6 @@ class Worker : public IWorker { public: Worker(Handle *handle); - ~Worker(); inline size_t id() const override { return m_id; } inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } @@ -57,7 +56,6 @@ protected: const size_t m_id; const size_t m_totalWays; const uint32_t m_offset; - cryptonight_ctx *m_ctxLegacy; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; From 8716f362f893cd7a40c3000d6c1ef23bdb7b7208 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 11:36:48 +0700 Subject: [PATCH 10/25] Fixed HW AES detection. --- src/core/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index ddce69806..1eb8e6e5a 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -157,7 +157,7 @@ bool xmrig::Config::adjust() } if (m_aesMode == AES_AUTO) { - m_aesMode = Cpu::hasAES() ? AES_SOFT : AES_SOFT; + m_aesMode = Cpu::hasAES() ? AES_HW : AES_SOFT; } if (!m_threads.cpu.empty()) { From 6b4f2d0a9137528b359506808430caef921a2efa Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 12:58:17 +0700 Subject: [PATCH 11/25] Fixed ARM build. --- src/Mem.cpp | 2 +- src/Mem_unix.cpp | 2 +- src/Mem_win.cpp | 2 +- src/crypto/CryptoNight_arm.h | 38 ++++++++++++++++----------------- src/crypto/CryptoNight_monero.h | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Mem.cpp b/src/Mem.cpp index 2efaac8a5..bb2da646a 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -50,7 +50,7 @@ MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count) allocate(info, m_enabled); for (size_t i = 0; i < count; ++i) { - cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 16)); + cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 4096)); c->memory = info.memory + (i * cn_select_memory(algorithm)); ctx[i] = c; diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 550033c43..229a0d463 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -45,7 +45,7 @@ void Mem::allocate(MemInfo &info, bool enabled) info.hugePages = 0; if (!enabled) { - info.memory = static_cast(_mm_malloc(info.size, 16)); + info.memory = static_cast(_mm_malloc(info.size, 4096)); return; } diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index d0b698f67..9a81b0396 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -157,7 +157,7 @@ void Mem::allocate(MemInfo &info, bool enabled) info.hugePages = 0; if (!enabled) { - info.memory = static_cast(_mm_malloc(info.size, 16)); + info.memory = static_cast(_mm_malloc(info.size, 4096)); return; } diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index d9677d06f..101a1f58b 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -455,7 +455,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) template -inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -466,14 +466,14 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); + keccak(input, (int) size, ctx[0]->state, 200); VARIANT1_INIT(0); - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = reinterpret_cast(ctx->state0); + const uint8_t* l0 = ctx[0]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; @@ -526,15 +526,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } } - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } template -inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -545,16 +545,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); - keccak(input + size, (int) size, ctx->state1, 200); + keccak(input, (int) size, ctx[0]->state, 200); + keccak(input + size, (int) size, ctx[1]->state, 200); VARIANT1_INIT(0); VARIANT1_INIT(1); - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEM; - uint64_t* h0 = reinterpret_cast(ctx->state0); - uint64_t* h1 = reinterpret_cast(ctx->state1); + const uint8_t* l0 = ctx[0]->memory; + const uint8_t* l1 = ctx[1]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); @@ -655,25 +655,25 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si keccakf(h0, 24); keccakf(h1, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); } template -inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h index a34f3ba8c..ea1622ab9 100644 --- a/src/crypto/CryptoNight_monero.h +++ b/src/crypto/CryptoNight_monero.h @@ -39,7 +39,7 @@ uint64_t tweak1_2_##part = 0; \ if (VARIANT > 0) { \ volatile const uint64_t a = *reinterpret_cast(input + 35 + part * size); \ - volatile const uint64_t b = *(reinterpret_cast(ctx->state##part) + 24); \ + volatile const uint64_t b = *(reinterpret_cast(ctx[part]->state) + 24); \ tweak1_2_##part = a ^ b; \ } #endif From e2d85d78a7e89ad062f68706a93a6aa3367cb4c6 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 14:49:39 +0700 Subject: [PATCH 12/25] Added information about started threads. --- src/workers/MultiWorker.h | 1 - src/workers/Worker.h | 3 +++ src/workers/Workers.cpp | 41 +++++++++++++++++++++++++++++++++++---- src/workers/Workers.h | 25 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index ba57f81e4..2c231e8df 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -64,7 +64,6 @@ private: cryptonight_ctx *m_ctx[N]; - MemInfo m_memory; State m_pausedState; State m_state; uint8_t m_hash[N * 32]; diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 0ae305302..aad9e3c5e 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -30,6 +30,7 @@ #include "interfaces/IWorker.h" +#include "Mem.h" struct cryptonight_ctx; @@ -46,6 +47,7 @@ class Worker : public IWorker public: Worker(Handle *handle); + inline const MemInfo &memory() const { return m_memory; } inline size_t id() const override { return m_id; } inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } @@ -56,6 +58,7 @@ protected: const size_t m_id; const size_t m_totalWays; const uint32_t m_offset; + MemInfo m_memory; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 21379db43..6d6deb3b3 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -43,6 +43,7 @@ bool Workers::m_enabled = true; Hashrate *Workers::m_hashrate = nullptr; IJobResultListener *Workers::m_listener = nullptr; Job Workers::m_job; +Workers::LaunchStatus Workers::m_status; std::atomic Workers::m_paused; std::atomic Workers::m_sequence; std::list Workers::m_queue; @@ -109,10 +110,12 @@ void Workers::setJob(const Job &job, bool donate) void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); + m_status.algo = controller->config()->algorithm(); + m_status.colors = controller->config()->isHugePages(); + m_status.threads = threads.size(); - size_t totalWays = 0; for (const xmrig::IThread *thread : threads) { - totalWays += thread->multiway(); + m_status.ways += thread->multiway(); } m_hashrate = new Hashrate(threads.size(), controller); @@ -130,7 +133,7 @@ void Workers::start(xmrig::Controller *controller) uint32_t offset = 0; for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, offset, totalWays); + Handle *handle = new Handle(thread, offset, m_status.ways); offset += thread->multiway(); m_workers.push_back(handle); @@ -203,7 +206,7 @@ void Workers::onReady(void *arg) return; } - worker->start(); + start(worker); } @@ -244,3 +247,33 @@ void Workers::onTick(uv_timer_t *handle) Api::tick(m_hashrate); # endif } + + +void Workers::start(IWorker *worker) +{ + const Worker *w = static_cast(worker); + + uv_mutex_lock(&m_mutex); + m_status.started++; + m_status.pages += w->memory().pages; + m_status.hugePages += w->memory().hugePages; + + if (m_status.started == m_status.threads) { + const double percent = (double) m_status.hugePages / m_status.pages * 100.0; + + if (m_status.colors) { + LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", + m_status.threads, m_status.ways, + (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), + m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + } + else { + LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB", + m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + } + } + + uv_mutex_unlock(&m_mutex); + + worker->start(); +} diff --git a/src/workers/Workers.h b/src/workers/Workers.h index ecec9e302..81b3411a2 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -37,6 +37,7 @@ class Handle; class Hashrate; class IJobResultListener; +class IWorker; namespace xmrig { @@ -66,12 +67,36 @@ private: static void onReady(void *arg); static void onResult(uv_async_t *handle); static void onTick(uv_timer_t *handle); + static void start(IWorker *worker); + + class LaunchStatus + { + public: + inline LaunchStatus() : + colors(true), + hugePages(0), + pages(0), + started(0), + threads(0), + ways(0), + algo(xmrig::CRYPTONIGHT) + {} + + bool colors; + size_t hugePages; + size_t pages; + size_t started; + size_t threads; + size_t ways; + xmrig::Algo algo; + }; static bool m_active; static bool m_enabled; static Hashrate *m_hashrate; static IJobResultListener *m_listener; static Job m_job; + static LaunchStatus m_status; static std::atomic m_paused; static std::atomic m_sequence; static std::list m_queue; From 6de83dddd6d96e6c2b48a4f04318ec6ac1cb821a Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 15:01:41 +0700 Subject: [PATCH 13/25] Fix wrong memory usage displayed for cn-lite. --- src/workers/Workers.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 6d6deb3b3..40dbb00c6 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -260,16 +260,17 @@ void Workers::start(IWorker *worker) if (m_status.started == m_status.threads) { const double percent = (double) m_status.hugePages / m_status.pages * 100.0; + const size_t ratio = m_status.algo == xmrig::CRYPTONIGHT_LITE ? 1 : 2; if (m_status.colors) { LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", m_status.threads, m_status.ways, (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), - m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); } else { LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB", - m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); } } From f0158ae5059573fe2627a2c085c8e8dbca708ef1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 15:10:41 +0700 Subject: [PATCH 14/25] Fix again. --- src/workers/Workers.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 40dbb00c6..e26b2030d 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -28,6 +28,7 @@ #include "api/Api.h" #include "core/Config.h" #include "core/Controller.h" +#include "crypto/CryptoNight_constants.h" #include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" #include "log/Log.h" @@ -260,17 +261,17 @@ void Workers::start(IWorker *worker) if (m_status.started == m_status.threads) { const double percent = (double) m_status.hugePages / m_status.pages * 100.0; - const size_t ratio = m_status.algo == xmrig::CRYPTONIGHT_LITE ? 1 : 2; + const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1048576; if (m_status.colors) { LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", m_status.threads, m_status.ways, (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), - m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); + m_status.hugePages, m_status.pages, percent, memory); } else { LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB", - m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); + m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, memory); } } From f8bf48a522c3bcf6f6a3b2e3f83363cbeb3c89eb Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 19:25:09 +0700 Subject: [PATCH 15/25] Added config only boolean option "hw-aes". --- src/core/Config.cpp | 58 +++++++++++++++----------------- src/core/ConfigLoader_platform.h | 1 + src/interfaces/IConfig.h | 1 + 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 1eb8e6e5a..f75e058ae 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -67,53 +67,49 @@ bool xmrig::Config::reload(const char *json) void xmrig::Config::getJSON(rapidjson::Document &doc) const { + using namespace rapidjson; + doc.SetObject(); auto &allocator = doc.GetAllocator(); - doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator); + doc.AddMember("algo", StringRef(algoName()), allocator); - rapidjson::Value api(rapidjson::kObjectType); + Value api(kObjectType); api.AddMember("port", apiPort(), allocator); - api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); - api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator); + api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator); api.AddMember("ipv6", isApiIPv6(), allocator); api.AddMember("restricted", isApiRestricted(), allocator); doc.AddMember("api", api, allocator); doc.AddMember("av", algoVariant(), allocator); doc.AddMember("background", isBackground(), allocator); - - doc.AddMember("colors", isColors(), allocator); + doc.AddMember("colors", isColors(), allocator); if (affinity() != -1L) { snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity()); - doc.AddMember("cpu-affinity", rapidjson::StringRef(affinity_tmp), allocator); + doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator); } else { - doc.AddMember("cpu-affinity", rapidjson::kNullType, allocator); - } - - if (priority() != -1) { - doc.AddMember("cpu-priority", priority(), allocator); - } - else { - doc.AddMember("cpu-priority", rapidjson::kNullType, allocator); + doc.AddMember("cpu-affinity", kNullType, allocator); } + doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator); doc.AddMember("donate-level", donateLevel(), allocator); doc.AddMember("huge-pages", isHugePages(), allocator); - doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator); + doc.AddMember("log-file", logFile() ? Value(StringRef(logFile())).Move() : Value(kNullType).Move(), allocator); doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator); - rapidjson::Value pools(rapidjson::kArrayType); + Value pools(kArrayType); for (const Pool &pool : m_pools) { - rapidjson::Value obj(rapidjson::kObjectType); + Value obj(kObjectType); - obj.AddMember("url", rapidjson::StringRef(pool.url()), allocator); - obj.AddMember("user", rapidjson::StringRef(pool.user()), allocator); - obj.AddMember("pass", rapidjson::StringRef(pool.password()), allocator); + obj.AddMember("url", StringRef(pool.url()), allocator); + obj.AddMember("user", StringRef(pool.user()), allocator); + obj.AddMember("pass", StringRef(pool.password()), allocator); if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) { obj.AddMember("keepalive", pool.keepAlive() > 0, allocator); @@ -134,7 +130,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("safe", m_safe, allocator); doc.AddMember("threads", threadsCount(), allocator); - doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); # ifdef HAVE_SYSLOG_H doc.AddMember("syslog", isSyslog(), allocator); @@ -156,13 +152,11 @@ bool xmrig::Config::adjust() return false; } - if (m_aesMode == AES_AUTO) { - m_aesMode = Cpu::hasAES() ? AES_HW : AES_SOFT; - } - if (!m_threads.cpu.empty()) { + const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; + for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, m_aesMode == AES_SOFT)); + m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, softAES)); } return true; @@ -198,18 +192,22 @@ bool xmrig::Config::parseBoolean(int key, bool enable) } switch (key) { - case xmrig::IConfig::SafeKey: /* --safe */ + case IConfig::SafeKey: /* --safe */ m_safe = enable; break; - case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */ + case IConfig::HugePagesKey: /* --no-huge-pages */ m_hugePages = enable; break; - case xmrig::IConfig::DryRunKey: /* --dry-run */ + case IConfig::DryRunKey: /* --dry-run */ m_dryRun = enable; break; + case IConfig::HardwareAESKey: /* hw-aes config only */ + m_aesMode = enable ? AES_HW : AES_SOFT; + break; + default: break; } diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index a090fb99d..7e1a4baa8 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -150,6 +150,7 @@ static struct option const config_options[] = { { "syslog", 0, nullptr, xmrig::IConfig::SyslogKey }, { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, + { "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey }, { 0, 0, 0, 0 } }; diff --git a/src/interfaces/IConfig.h b/src/interfaces/IConfig.h index 89aa62177..f7433d7f4 100644 --- a/src/interfaces/IConfig.h +++ b/src/interfaces/IConfig.h @@ -74,6 +74,7 @@ public: MaxCPUUsageKey = 1004, SafeKey = 1005, ThreadsKey = 't', + HardwareAESKey = 1011, // xmrig-proxy AccessLogFileKey = 'A', From dba1acd30201bf0d3bf09b44a89c72abb197b595 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 21:41:03 +0700 Subject: [PATCH 16/25] Finalize config changes. --- src/core/Config.cpp | 32 ++++++++++++++++++++++---------- src/core/Config.h | 15 ++++++++++----- src/interfaces/IThread.h | 13 +++++++------ src/workers/CpuThread.cpp | 18 +++++++++++++++++- src/workers/CpuThread.h | 3 +++ 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f75e058ae..b3564f926 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -43,12 +43,10 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : xmrig::CommonConfig(), m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), - m_doubleHash(false), m_dryRun(false), m_hugePages(true), m_safe(false), m_maxCpuUsage(75), - m_printTime(60), m_priority(-1) { } @@ -129,8 +127,21 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("retries", retries(), allocator); doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("safe", m_safe, allocator); - doc.AddMember("threads", threadsCount(), allocator); - doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); + + if (threadsMode() == Advanced) { + Value threads(kArrayType); + + for (const IThread *thread : m_threads.list) { + threads.PushBack(thread->toConfig(doc), doc.GetAllocator()); + } + + doc.AddMember("threads", threads, allocator); + } + else { + doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator); + } + + doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); # ifdef HAVE_SYSLOG_H doc.AddMember("syslog", isSyslog(), allocator); @@ -153,6 +164,7 @@ bool xmrig::Config::adjust() } if (!m_threads.cpu.empty()) { + m_threads.mode = Advanced; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { @@ -162,16 +174,16 @@ bool xmrig::Config::adjust() return true; } - m_algoVariant = getAlgoVariant(); - if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) { - m_doubleHash = true; - } + m_algoVariant = getAlgoVariant(); + m_threads.mode = m_threads.count ? Simple : Automatic; + + const bool doubleHash = m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT; if (!m_threads.count) { - m_threads.count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + m_threads.count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); } else if (m_safe) { - const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + const size_t count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); if (m_threads.count > count) { m_threads.count = count; } diff --git a/src/core/Config.h b/src/core/Config.h index 720557a7d..13320a800 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -61,6 +61,13 @@ class IWatcherListener; class Config : public CommonConfig { public: + enum ThreadsMode { + Automatic, + Simple, + Advanced + }; + + Config(); ~Config(); @@ -70,14 +77,13 @@ public: inline AesMode aesMode() const { return m_aesMode; } inline AlgoVariant algoVariant() const { return m_algoVariant; } - inline bool isDoubleHash() const { return m_doubleHash; } inline bool isDryRun() const { return m_dryRun; } inline bool isHugePages() const { return m_hugePages; } inline const std::vector &threads() const { return m_threads.list; } - inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } inline int threadsCount() const { return m_threads.list.size(); } inline int64_t affinity() const { return m_threads.mask; } + inline ThreadsMode threadsMode() const { return m_threads.mode; } static Config *load(int argc, char **argv, IWatcherListener *listener); @@ -99,23 +105,22 @@ private: struct Threads { - inline Threads() : mask(-1L), count(0) {} + inline Threads() : mask(-1L), count(0), mode(Automatic) {} int64_t mask; size_t count; std::vector cpu; std::vector list; + ThreadsMode mode; }; AesMode m_aesMode; AlgoVariant m_algoVariant; - bool m_doubleHash; bool m_dryRun; bool m_hugePages; bool m_safe; int m_maxCpuUsage; - int m_printTime; int m_priority; Threads m_threads; }; diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index f517ed18a..2e9e3c398 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -53,12 +53,13 @@ public: virtual ~IThread() {} - virtual Algo algorithm() const = 0; - virtual int priority() const = 0; - virtual int64_t affinity() const = 0; - virtual Multiway multiway() const = 0; - virtual size_t index() const = 0; - virtual Type type() const = 0; + virtual Algo algorithm() const = 0; + virtual int priority() const = 0; + virtual int64_t affinity() const = 0; + virtual Multiway multiway() const = 0; + virtual rapidjson::Value toConfig(rapidjson::Document &doc) const = 0; + virtual size_t index() const = 0; + virtual Type type() const = 0; # ifndef XMRIG_NO_API virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 07fbbb64e..ac733ef6c 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -245,7 +245,9 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { - rapidjson::Value obj(rapidjson::kObjectType); + using namespace rapidjson; + + Value obj(kObjectType); auto &allocator = doc.GetAllocator(); obj.AddMember("type", "cpu", allocator); @@ -259,3 +261,17 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const return obj; } #endif + + +rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + Value obj(kObjectType); + auto &allocator = doc.GetAllocator(); + + obj.AddMember("low_power_mode", multiway(), allocator); + obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); + + return obj; +} diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index e14c79f14..ba36cc878 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -77,10 +77,13 @@ public: inline size_t index() const override { return m_index; } inline Type type() const override { return CPU; } +protected: # ifndef XMRIG_NO_API rapidjson::Value toAPI(rapidjson::Document &doc) const override; # endif + rapidjson::Value toConfig(rapidjson::Document &doc) const override; + private: const Algo m_algorithm; const AlgoVariant m_av; From 9e3f2ae9f9adfdb35e26a7519acc92b261288d90 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 16 Apr 2018 15:40:37 +0700 Subject: [PATCH 17/25] Added x3 x4 x5 hashing modes. --- cmake/flags.cmake | 4 +- src/api/ApiRouter.cpp | 8 +- src/crypto/CryptoNight_test.h | 69 +++++-- src/crypto/CryptoNight_x86.h | 362 +++++++++++++++++++++++++++++++++- src/crypto/soft_aes.h | 17 ++ src/workers/MultiWorker.cpp | 2 +- 6 files changed, 442 insertions(+), 20 deletions(-) diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 13e505646..498f2165b 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -13,10 +13,10 @@ endif() if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s") if (XMRIG_ARMv8) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto") diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 0893bc8ba..8206aa3eb 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -298,13 +298,17 @@ void ApiRouter::getResults(rapidjson::Document &doc) const void ApiRouter::getThreads(rapidjson::Document &doc) const { - doc.SetArray(); + doc.SetObject(); + auto &allocator = doc.GetAllocator(); const std::vector &threads = m_controller->config()->threads(); + rapidjson::Value list(rapidjson::kArrayType); for (const xmrig::IThread *thread : threads) { - doc.PushBack(thread->toAPI(doc), doc.GetAllocator()); + list.PushBack(thread->toAPI(doc), allocator); } + + doc.AddMember("threads", list, allocator); } diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 5717f1d35..52dd2965b 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -26,7 +26,7 @@ #define __CRYPTONIGHT_TEST_H__ -const static uint8_t test_input[152] = { +const static uint8_t test_input[380] = { 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, @@ -36,52 +36,97 @@ const static uint8_t test_input[152] = { 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01 + 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, + 0x07, 0x07, 0xB4, 0x87, 0xD0, 0xD6, 0x05, 0x26, 0xE0, 0xC6, 0xDD, 0x9B, 0xC7, 0x18, 0xC3, 0xCF, + 0x52, 0x04, 0xBD, 0x4F, 0x9B, 0x27, 0xF6, 0x73, 0xB9, 0x3F, 0xEF, 0x7B, 0xB2, 0xF7, 0x2B, 0xBB, + 0x3F, 0x3E, 0x9C, 0x3E, 0x9D, 0x33, 0x1E, 0xDE, 0xAD, 0xBE, 0xEF, 0x4E, 0x00, 0x91, 0x81, 0x29, + 0x74, 0xB2, 0x70, 0xE7, 0x6D, 0xD2, 0x2A, 0x5F, 0x52, 0x04, 0x93, 0xE6, 0x18, 0x89, 0x40, 0xD8, + 0xC6, 0xE3, 0x90, 0x6E, 0xAA, 0x6A, 0xB7, 0xE2, 0x08, 0x7E, 0x78, 0x0E, + 0x01, 0x00, 0xEE, 0xB2, 0xD1, 0xD6, 0x05, 0xFF, 0x27, 0x7F, 0x26, 0xDB, 0xAA, 0xB2, 0xC9, 0x26, + 0x30, 0xC6, 0xCF, 0x11, 0x64, 0xEA, 0x6C, 0x8A, 0xE0, 0x98, 0x01, 0xF8, 0x75, 0x4B, 0x49, 0xAF, + 0x79, 0x70, 0xAE, 0xEE, 0xA7, 0x62, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x47, 0x8C, 0x63, 0xE7, 0xD8, + 0x40, 0x02, 0x3C, 0xDA, 0xEA, 0x92, 0x52, 0x53, 0xAC, 0xFD, 0xC7, 0x8A, 0x4C, 0x31, 0xB2, 0xF2, + 0xEC, 0x72, 0x7B, 0xFF, 0xCE, 0xC0, 0xE7, 0x12, 0xD4, 0xE9, 0x2A, 0x01, + 0x07, 0x07, 0xA9, 0xB7, 0xD1, 0xD6, 0x05, 0x3F, 0x0D, 0x5E, 0xFD, 0xC7, 0x03, 0xFC, 0xFC, 0xD2, + 0xCE, 0xBC, 0x44, 0xD8, 0xAB, 0x44, 0xA6, 0xA0, 0x3A, 0xE4, 0x4D, 0x8F, 0x15, 0xAF, 0x62, 0x17, + 0xD1, 0xE0, 0x92, 0x85, 0xE4, 0x73, 0xF9, 0x00, 0x00, 0x00, 0xA0, 0xFC, 0x09, 0xDE, 0xAB, 0xF5, + 0x8B, 0x6F, 0x1D, 0xCA, 0xA8, 0xBA, 0xAC, 0x74, 0xDD, 0x74, 0x19, 0xD5, 0xD6, 0x10, 0xEC, 0x38, + 0xCF, 0x50, 0x29, 0x6A, 0x07, 0x0B, 0x93, 0x8F, 0x8F, 0xA8, 0x10, 0x04 }; -const static uint8_t test_output_v0[64] = { +const static uint8_t test_output_v0[160] = { 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, - 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00 + 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00, + 0xA1, 0xB4, 0xFA, 0xE3, 0xE5, 0x76, 0xCE, 0xCF, 0xB7, 0x9C, 0xAF, 0x3E, 0x29, 0x92, 0xE4, 0xE0, + 0x31, 0x24, 0x05, 0x48, 0xBF, 0x8D, 0x5F, 0x7B, 0x11, 0x03, 0x60, 0xAA, 0xD7, 0x50, 0x3F, 0x0C, + 0x2D, 0x30, 0xF3, 0x87, 0x4F, 0x86, 0xA1, 0x4A, 0xB5, 0xA2, 0x1A, 0x08, 0xD0, 0x44, 0x2C, 0x9D, + 0x16, 0xE9, 0x28, 0x49, 0xA1, 0xFF, 0x85, 0x6F, 0x12, 0xBB, 0x7D, 0xAB, 0x11, 0x1C, 0xE7, 0xF7, + 0x2D, 0x9D, 0x19, 0xE4, 0xD2, 0x26, 0x44, 0x1E, 0xCD, 0x22, 0x08, 0x24, 0xA8, 0x97, 0x46, 0x62, + 0x04, 0x84, 0x90, 0x4A, 0xEE, 0x99, 0x14, 0xED, 0xB8, 0xC6, 0x0D, 0x37, 0xA1, 0x66, 0x17, 0xB0 }; // Monero v7 -const static uint8_t test_output_v1[64] = { +const static uint8_t test_output_v1[160] = { 0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D, 0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22, 0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9, - 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9 + 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, + 0xE7, 0x8C, 0x5A, 0x6E, 0x38, 0x30, 0x68, 0x4A, 0x73, 0xFC, 0x1B, 0xC6, 0x6D, 0xFC, 0x8D, 0x98, + 0xB4, 0xC2, 0x23, 0x39, 0xAD, 0xE0, 0x9D, 0xF6, 0x6D, 0x8C, 0x6A, 0xAA, 0xF9, 0xB2, 0xE3, 0x4C, + 0xB6, 0x90, 0x6C, 0xE6, 0x15, 0x5E, 0x46, 0x07, 0x9C, 0xB2, 0x6B, 0xAC, 0x3B, 0xAC, 0x1A, 0xDE, + 0x92, 0x2C, 0xD6, 0x0C, 0x46, 0x9D, 0x9B, 0xC2, 0x84, 0x52, 0x65, 0xF6, 0xBD, 0xFA, 0x0D, 0x74, + 0x00, 0x66, 0x10, 0x07, 0xF1, 0x19, 0x06, 0x3A, 0x6C, 0xFF, 0xEE, 0xB2, 0x40, 0xE5, 0x88, 0x2B, + 0x6C, 0xAB, 0x6B, 0x1D, 0x88, 0xB8, 0x44, 0x25, 0xF4, 0xEA, 0xB7, 0xEC, 0xBA, 0x12, 0x8A, 0x24 }; #ifndef XMRIG_NO_AEON -const static uint8_t test_output_v0_lite[64] = { +const static uint8_t test_output_v0_lite[160] = { 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, - 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88 + 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, + 0x38, 0x08, 0xE1, 0x17, 0x0B, 0x99, 0x8D, 0x1A, 0x3C, 0xCE, 0x35, 0xC5, 0xC7, 0x3A, 0x00, 0x2E, + 0xCB, 0x54, 0xF0, 0x78, 0x2E, 0x9E, 0xDB, 0xC7, 0xDF, 0x2E, 0x71, 0x9A, 0x16, 0x97, 0xC4, 0x18, + 0x4B, 0x97, 0x07, 0xFE, 0x5D, 0x98, 0x9A, 0xD6, 0xD8, 0xE5, 0x92, 0x66, 0x87, 0x7F, 0x19, 0x37, + 0xA2, 0x5E, 0xE6, 0x96, 0xB5, 0x97, 0x33, 0x89, 0xE0, 0xA7, 0xC9, 0xDD, 0x4A, 0x7E, 0x9E, 0x53, + 0xBE, 0x91, 0x2B, 0xF5, 0xF5, 0xAF, 0xDD, 0x09, 0xA2, 0xF4, 0xA4, 0x56, 0xEB, 0x96, 0x22, 0xC9, + 0x94, 0xFB, 0x7B, 0x28, 0xC9, 0x97, 0x65, 0x04, 0xAC, 0x4F, 0x84, 0x71, 0xDA, 0x6E, 0xD8, 0xC5 }; // AEON v7 -const static uint8_t test_output_v1_lite[64] = { +const static uint8_t test_output_v1_lite[160] = { 0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45, 0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F, 0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22, - 0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41 + 0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41, + 0x16, 0x08, 0x74, 0xC7, 0xA2, 0xD2, 0xA3, 0x97, 0x95, 0x76, 0xCA, 0x4D, 0x06, 0x39, 0x7A, 0xAB, + 0x6C, 0x87, 0x58, 0x33, 0x4D, 0xC8, 0x5A, 0xAB, 0x04, 0x27, 0xFE, 0x8B, 0x1C, 0x23, 0x2F, 0x32, + 0xC0, 0x44, 0xFF, 0x0D, 0xB5, 0x3B, 0x27, 0x96, 0x06, 0x89, 0x7B, 0xA3, 0x0B, 0xD0, 0xCE, 0x9E, + 0x90, 0x22, 0x77, 0x5A, 0xAD, 0xA1, 0xE5, 0xB6, 0xFC, 0xCB, 0x39, 0x7E, 0x2B, 0x10, 0xEE, 0xB4, + 0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9, + 0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6 }; #endif #ifndef XMRIG_NO_SUMO -const static uint8_t test_output_heavy[64] = { +const static uint8_t test_output_heavy[160] = { 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, 0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D, 0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64, - 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2 + 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2, + 0x3E, 0xE1, 0x23, 0x03, 0x5A, 0x63, 0x7B, 0x66, 0xF6, 0xD7, 0xC2, 0x2A, 0x34, 0x5E, 0x88, 0xE7, + 0xFA, 0xC4, 0x25, 0x36, 0x54, 0xCB, 0xD2, 0x5C, 0x2F, 0x80, 0x2A, 0xF9, 0xCC, 0x43, 0xF7, 0xCD, + 0xE5, 0x18, 0xA8, 0x05, 0x60, 0x18, 0xA5, 0x73, 0x72, 0x9B, 0x32, 0xDC, 0x69, 0x83, 0xC1, 0xE1, + 0x1F, 0xDB, 0xDA, 0x6B, 0xAC, 0xEC, 0x9F, 0x67, 0xF8, 0x27, 0x1D, 0xC7, 0xE6, 0x46, 0x42, 0xF9, + 0x53, 0x62, 0x0A, 0x54, 0x7D, 0x43, 0xEA, 0x18, 0x94, 0xED, 0xD8, 0x92, 0x06, 0x6A, 0xA1, 0x51, + 0xAD, 0xB1, 0xFD, 0x89, 0xFB, 0x5C, 0xB4, 0x25, 0x6A, 0xDD, 0xB0, 0x09, 0xC5, 0x72, 0x87, 0xEB }; #endif diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 824dd99c6..3dafe7243 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -427,7 +427,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si uint64_t ah0 = h0[1] ^ h0[5]; __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - uint64_t idx0 = h0[0] ^ h0[4]; + uint64_t idx0 = al0; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx; @@ -517,8 +517,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - uint64_t idx0 = h0[0] ^ h0[4]; - uint64_t idx1 = h1[0] ^ h1[4]; + uint64_t idx0 = al0; + uint64_t idx1 = al1; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx0, cx1; @@ -611,21 +611,377 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si } +#define CN_STEP1(a, b, c, l, ptr, idx) \ + ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ + c = _mm_load_si128(ptr); + + +#define CN_STEP2(a, b, c, l, ptr, idx) \ + if (SOFT_AES) { \ + c = soft_aesenc(c, a); \ + } else { \ + c = _mm_aesenc_si128(c, a); \ + } \ + \ + b = _mm_xor_si128(b, c); \ + \ + if (VARIANT > 0) { \ + cryptonight_monero_tweak(reinterpret_cast(ptr), b); \ + } else { \ + _mm_store_si128(ptr, b); \ + } + + +#define CN_STEP3(a, b, c, l, ptr, idx) \ + idx = EXTRACT64(c); \ + ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ + b = _mm_load_si128(ptr); + + +#define CN_STEP4(a, b, c, l, mc, ptr, idx) \ + lo = __umul128(idx, EXTRACT64(b), &hi); \ + a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \ + \ + if (VARIANT > 0) { \ + _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ + } else { \ + _mm_store_si128(ptr, a); \ + } \ + \ + a = _mm_xor_si128(a, b); \ + idx = EXTRACT64(a); \ + \ + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \ + int64_t n = ((int64_t*)&l[idx & MASK])[0]; \ + int32_t d = ((int32_t*)&l[idx & MASK])[2]; \ + int64_t q = n / (d | 0x5); \ + ((int64_t*)&l[idx & MASK])[0] = n ^ q; \ + idx = d ^ q; \ + } + + +#define CONST_INIT(ctx, n) \ + __m128i mc##n; \ + if (VARIANT > 0) { \ + mc##n = _mm_set_epi64x(*reinterpret_cast(input + n * size + 35) ^ \ + *(reinterpret_cast((ctx)->state) + 24), 0); \ + } + + template inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32 * 3); + return; + } + + for (size_t i = 0; i < 3; i++) { + keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + } + + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + + uint8_t* l0 = ctx[0]->memory; + uint8_t* l1 = ctx[1]->memory; + uint8_t* l2 = ctx[2]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint64_t* h2 = reinterpret_cast(ctx[2]->state); + + __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); + __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); + __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); + __m128i cx0 = _mm_set_epi64x(0, 0); + __m128i cx1 = _mm_set_epi64x(0, 0); + __m128i cx2 = _mm_set_epi64x(0, 0); + + uint64_t idx0, idx1, idx2; + idx0 = EXTRACT64(ax0); + idx1 = EXTRACT64(ax1); + idx2 = EXTRACT64(ax2); + + for (size_t i = 0; i < ITERATIONS / 2; i++) { + uint64_t hi, lo; + __m128i *ptr0, *ptr1, *ptr2; + + // EVEN ROUND + CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); + + CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); + + CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); + + CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); + + // ODD ROUND + CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); + + CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); + + CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); + + CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); + } + + for (size_t i = 0; i < 3; i++) { + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); + extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); + } } template inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32 * 4); + return; + } + + for (size_t i = 0; i < 4; i++) { + keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + } + + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + CONST_INIT(ctx[3], 3); + + uint8_t* l0 = ctx[0]->memory; + uint8_t* l1 = ctx[1]->memory; + uint8_t* l2 = ctx[2]->memory; + uint8_t* l3 = ctx[3]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint64_t* h2 = reinterpret_cast(ctx[2]->state); + uint64_t* h3 = reinterpret_cast(ctx[3]->state); + + __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); + __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); + __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); + __m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]); + __m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]); + __m128i cx0 = _mm_set_epi64x(0, 0); + __m128i cx1 = _mm_set_epi64x(0, 0); + __m128i cx2 = _mm_set_epi64x(0, 0); + __m128i cx3 = _mm_set_epi64x(0, 0); + + uint64_t idx0, idx1, idx2, idx3; + idx0 = _mm_cvtsi128_si64(ax0); + idx1 = _mm_cvtsi128_si64(ax1); + idx2 = _mm_cvtsi128_si64(ax2); + idx3 = _mm_cvtsi128_si64(ax3); + + for (size_t i = 0; i < ITERATIONS / 2; i++) + { + uint64_t hi, lo; + __m128i *ptr0, *ptr1, *ptr2, *ptr3; + + // EVEN ROUND + CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3); + + CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); + + CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); + + CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); + + // ODD ROUND + CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3); + + CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3); + + CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3); + + CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3); + } + + for (size_t i = 0; i < 4; i++) { + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); + extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); + } } template inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32 * 5); + return; + } + + for (size_t i = 0; i < 5; i++) { + keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + } + + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + CONST_INIT(ctx[3], 3); + CONST_INIT(ctx[4], 4); + + uint8_t* l0 = ctx[0]->memory; + uint8_t* l1 = ctx[1]->memory; + uint8_t* l2 = ctx[2]->memory; + uint8_t* l3 = ctx[3]->memory; + uint8_t* l4 = ctx[4]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint64_t* h2 = reinterpret_cast(ctx[2]->state); + uint64_t* h3 = reinterpret_cast(ctx[3]->state); + uint64_t* h4 = reinterpret_cast(ctx[4]->state); + + __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); + __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); + __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); + __m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]); + __m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]); + __m128i ax4 = _mm_set_epi64x(h4[1] ^ h4[5], h4[0] ^ h4[4]); + __m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]); + __m128i cx0 = _mm_set_epi64x(0, 0); + __m128i cx1 = _mm_set_epi64x(0, 0); + __m128i cx2 = _mm_set_epi64x(0, 0); + __m128i cx3 = _mm_set_epi64x(0, 0); + __m128i cx4 = _mm_set_epi64x(0, 0); + + uint64_t idx0, idx1, idx2, idx3, idx4; + idx0 = _mm_cvtsi128_si64(ax0); + idx1 = _mm_cvtsi128_si64(ax1); + idx2 = _mm_cvtsi128_si64(ax2); + idx3 = _mm_cvtsi128_si64(ax3); + idx4 = _mm_cvtsi128_si64(ax4); + + for (size_t i = 0; i < ITERATIONS / 2; i++) + { + uint64_t hi, lo; + __m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4; + + // EVEN ROUND + CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP1(ax4, bx4, cx4, l4, ptr4, idx4); + + CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP2(ax4, bx4, cx4, l4, ptr4, idx4); + + CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP3(ax4, bx4, cx4, l4, ptr4, idx4); + + CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); + CN_STEP4(ax4, bx4, cx4, l4, mc4, ptr4, idx4); + + // ODD ROUND + CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3); + CN_STEP1(ax4, cx4, bx4, l4, ptr4, idx4); + + CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3); + CN_STEP2(ax4, cx4, bx4, l4, ptr4, idx4); + + CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3); + CN_STEP3(ax4, cx4, bx4, l4, ptr4, idx4); + + CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3); + CN_STEP4(ax4, cx4, bx4, l4, mc4, ptr4, idx4); + } + + for (size_t i = 0; i < 5; i++) { + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); + extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); + } } #endif /* __CRYPTONIGHT_X86_H__ */ diff --git a/src/crypto/soft_aes.h b/src/crypto/soft_aes.h index 0703f98de..26c1b06ad 100644 --- a/src/crypto/soft_aes.h +++ b/src/crypto/soft_aes.h @@ -105,6 +105,23 @@ static inline __m128i soft_aesenc(const uint32_t* in, __m128i key) return _mm_xor_si128(out, key); } +static inline __m128i soft_aesenc(__m128i in, __m128i key) +{ + uint32_t x0, x1, x2, x3; + x0 = _mm_cvtsi128_si32(in); + x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0x55)); + x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xAA)); + x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xFF)); + + __m128i out = _mm_set_epi32( + (saes_table[0][x3 & 0xff] ^ saes_table[1][(x0 >> 8) & 0xff] ^ saes_table[2][(x1 >> 16) & 0xff] ^ saes_table[3][x2 >> 24]), + (saes_table[0][x2 & 0xff] ^ saes_table[1][(x3 >> 8) & 0xff] ^ saes_table[2][(x0 >> 16) & 0xff] ^ saes_table[3][x1 >> 24]), + (saes_table[0][x1 & 0xff] ^ saes_table[1][(x2 >> 8) & 0xff] ^ saes_table[2][(x3 >> 16) & 0xff] ^ saes_table[3][x0 >> 24]), + (saes_table[0][x0 & 0xff] ^ saes_table[1][(x1 >> 8) & 0xff] ^ saes_table[2][(x2 >> 16) & 0xff] ^ saes_table[3][x3 >> 24])); + + return _mm_xor_si128(out, key); +} + static inline uint32_t sub_word(uint32_t key) { return (saes_sbox[key >> 24 ] << 24) | diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index a75adecc4..09dd568ff 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -104,7 +104,7 @@ void MultiWorker::start() for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash, m_state.job.diff())); + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff())); } *nonce(i) += 1; From b32ec5342eefa6cec814708f81f37819787b0972 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 09:42:53 +0700 Subject: [PATCH 18/25] Fixed automatic threads mode for --av above 4 --- CMakeLists.txt | 2 +- src/Cpu.cpp | 39 +++++++++----------- src/Cpu.h | 7 ++-- src/core/Config.cpp | 7 ++-- src/workers/CpuThread.cpp | 75 ++++++++++++++++++++------------------- src/workers/CpuThread.h | 2 ++ 6 files changed, 63 insertions(+), 69 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7017b01a..ae2a4ed75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,7 @@ endif() add_definitions(/D__STDC_FORMAT_MACROS) add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/Cpu.cpp b/src/Cpu.cpp index f8fb092ca..eebe585d8 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -26,26 +26,27 @@ #include #include + #include "Cpu.h" -bool Cpu::m_l2_exclusive = false; -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -int Cpu::m_totalThreads = 0; +bool Cpu::m_l2_exclusive = false; +char Cpu::m_brand[64] = { 0 }; +int Cpu::m_flags = 0; +int Cpu::m_l2_cache = 0; +int Cpu::m_l3_cache = 0; +int Cpu::m_sockets = 1; +int Cpu::m_totalCores = 0; +size_t Cpu::m_totalThreads = 0; -int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) +size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) { if (m_totalThreads == 1) { return 1; } - int cache = 0; + size_t cache = 0; if (m_l3_cache) { cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache; } @@ -53,22 +54,14 @@ int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) cache = m_l2_cache; } - int count = 0; - int size = 2048; - - if (algo == xmrig::CRYPTONIGHT_LITE) { - size = 1024; - } - else if (algo == xmrig::CRYPTONIGHT_HEAVY) { - size = 4096; - } - - if (doubleHash) { - size *= 2; - } + size_t count = 0; if (cache) { count = cache / size; + + if (cache % size >= size / 2) { + count++; + } } else { count = m_totalThreads / 2; diff --git a/src/Cpu.h b/src/Cpu.h index 97e593ed8..a125bae80 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -28,9 +28,6 @@ #include -#include "common/xmrig.h" - - class Cpu { public: @@ -40,7 +37,7 @@ public: BMI2 = 4 }; - static int optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage); + static size_t optimalThreadsCount(size_t size, int maxCpuUsage); static void init(); static inline bool hasAES() { return (m_flags & AES) != 0; } @@ -62,7 +59,7 @@ private: static int m_l3_cache; static int m_sockets; static int m_totalCores; - static int m_totalThreads; + static size_t m_totalThreads; }; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index b3564f926..4d48af298 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -30,6 +30,7 @@ #include "core/Config.h" #include "core/ConfigCreator.h" #include "Cpu.h" +#include "crypto/CryptoNight_constants.h" #include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" @@ -177,13 +178,13 @@ bool xmrig::Config::adjust() m_algoVariant = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; - const bool doubleHash = m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT; + const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm) / 1024; if (!m_threads.count) { - m_threads.count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); + m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); } else if (m_safe) { - const size_t count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); + const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); if (m_threads.count > count) { m_threads.count = count; } diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index ac733ef6c..3632e193c 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -54,6 +54,12 @@ xmrig::CpuThread::~CpuThread() } +bool xmrig::CpuThread::isSoftAES(AlgoVariant av) +{ + return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA; +} + + xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) { assert(variant == VARIANT_NONE || variant == VARIANT_V1); @@ -138,42 +144,6 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A { assert(av > AV_AUTO && av < AV_MAX); - Multiway multiway = SingleWay; - bool softAES = false; - - switch (av) { - case AV_SINGLE_SOFT: - softAES = true; - break; - - case AV_DOUBLE_SOFT: - softAES = true; - case AV_DOUBLE: - multiway = DoubleWay; - break; - - case AV_TRIPLE_SOFT: - softAES = true; - case AV_TRIPLE: - multiway = TripleWay; - break; - - case AV_QUAD_SOFT: - softAES = true; - case AV_QUAD: - multiway = QuadWay; - break; - - case AV_PENTA_SOFT: - softAES = true; - case AV_PENTA: - multiway = PentaWay; - break; - - default: - break; - } - int64_t cpuId = -1L; if (affinity != -1L) { @@ -193,7 +163,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } } - return new CpuThread(index, algorithm, av, multiway, cpuId, priority, softAES, false); + return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false); } @@ -242,6 +212,37 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) } +xmrig::IThread::Multiway xmrig::CpuThread::multiway(AlgoVariant av) +{ + switch (av) { + case AV_SINGLE: + case AV_SINGLE_SOFT: + return SingleWay; + + case AV_DOUBLE_SOFT: + case AV_DOUBLE: + return DoubleWay; + + case AV_TRIPLE_SOFT: + case AV_TRIPLE: + return TripleWay; + + case AV_QUAD_SOFT: + case AV_QUAD: + return QuadWay; + + case AV_PENTA_SOFT: + case AV_PENTA: + return PentaWay; + + default: + break; + } + + return SingleWay; +} + + #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index ba36cc878..0e364764c 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -61,10 +61,12 @@ public: typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx); + static bool isSoftAES(AlgoVariant av); static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); + static Multiway multiway(AlgoVariant av); inline bool isPrefetch() const { return m_prefetch; } inline bool isSoftAES() const { return m_softAES; } From c221bf09f626eda15bbfd212dfd96d3a09b68867 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 10:29:37 +0700 Subject: [PATCH 19/25] Use direct access to hashrate in API. --- src/api/Api.cpp | 10 ---------- src/api/Api.h | 1 - src/api/ApiRouter.cpp | 41 ++++++++++++---------------------------- src/api/ApiRouter.h | 5 ----- src/workers/Hashrate.cpp | 18 +++++++++--------- src/workers/Hashrate.h | 6 +++--- src/workers/Workers.cpp | 4 ---- src/workers/Workers.h | 2 ++ 8 files changed, 26 insertions(+), 61 deletions(-) diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 6f9991ee1..3fff45b52 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -62,16 +62,6 @@ void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) } -void Api::tick(const Hashrate *hashrate) -{ - if (!m_router) { - return; - } - - m_router->tick(hashrate); -} - - void Api::tick(const NetworkState &network) { if (!m_router) { diff --git a/src/api/Api.h b/src/api/Api.h index 43c7b17e1..316bb0fa2 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -47,7 +47,6 @@ public: static void release(); static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); - static void tick(const Hashrate *hashrate); static void tick(const NetworkState &results); private: diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 8206aa3eb..08cd9bf6f 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -47,6 +47,7 @@ #include "rapidjson/stringbuffer.h" #include "version.h" #include "workers/Hashrate.h" +#include "workers/Workers.h" extern "C" @@ -68,10 +69,6 @@ static inline double normalize(double d) ApiRouter::ApiRouter(xmrig::Controller *controller) : m_controller(controller) { - m_threads = controller->config()->threadsCount(); - m_hashrate = new double[m_threads * 3](); - - memset(m_totalHashrate, 0, sizeof(m_totalHashrate)); memset(m_workerId, 0, sizeof(m_workerId)); setWorkerId(controller->config()->apiWorkerId()); @@ -81,7 +78,6 @@ ApiRouter::ApiRouter(xmrig::Controller *controller) : ApiRouter::~ApiRouter() { - delete [] m_hashrate; } @@ -129,21 +125,6 @@ void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) } -void ApiRouter::tick(const Hashrate *hashrate) -{ - for (int i = 0; i < m_threads; ++i) { - m_hashrate[i * 3] = hashrate->calc((size_t) i, Hashrate::ShortInterval); - m_hashrate[i * 3 + 1] = hashrate->calc((size_t) i, Hashrate::MediumInterval); - m_hashrate[i * 3 + 2] = hashrate->calc((size_t) i, Hashrate::LargeInterval); - } - - m_totalHashrate[0] = hashrate->calc(Hashrate::ShortInterval); - m_totalHashrate[1] = hashrate->calc(Hashrate::MediumInterval); - m_totalHashrate[2] = hashrate->calc(Hashrate::LargeInterval); - m_highestHashrate = hashrate->highest(); -} - - void ApiRouter::tick(const NetworkState &network) { m_network = network; @@ -225,21 +206,23 @@ void ApiRouter::getHashrate(rapidjson::Document &doc) const rapidjson::Value total(rapidjson::kArrayType); rapidjson::Value threads(rapidjson::kArrayType); - for (int i = 0; i < 3; ++i) { - total.PushBack(normalize(m_totalHashrate[i]), allocator); - } + const Hashrate *hr = Workers::hashrate(); - for (int i = 0; i < m_threads * 3; i += 3) { + total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); + total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); + total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); + + for (size_t i = 0; i < Workers::threads(); i++) { rapidjson::Value thread(rapidjson::kArrayType); - thread.PushBack(normalize(m_hashrate[i]), allocator); - thread.PushBack(normalize(m_hashrate[i + 1]), allocator); - thread.PushBack(normalize(m_hashrate[i + 2]), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); threads.PushBack(thread, allocator); } - hashrate.AddMember("total", total, allocator); - hashrate.AddMember("highest", normalize(m_highestHashrate), allocator); + hashrate.AddMember("total", total, allocator); + hashrate.AddMember("highest", normalize(hr->highest()), allocator); hashrate.AddMember("threads", threads, allocator); doc.AddMember("hashrate", hashrate, allocator); } diff --git a/src/api/ApiRouter.h b/src/api/ApiRouter.h index e14f9e879..3ed458d41 100644 --- a/src/api/ApiRouter.h +++ b/src/api/ApiRouter.h @@ -49,7 +49,6 @@ public: void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const; void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); - void tick(const Hashrate *hashrate); void tick(const NetworkState &results); protected: @@ -69,10 +68,6 @@ private: char m_id[17]; char m_workerId[128]; - double *m_hashrate; - double m_highestHashrate; - double m_totalHashrate[3]; - int m_threads; NetworkState m_network; xmrig::Controller *m_controller; }; diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index ef06eb52c..7d2e6a4c5 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -22,6 +22,7 @@ */ +#include #include #include #include @@ -45,7 +46,7 @@ inline const char *format(double h, char* buf, size_t size) } -Hashrate::Hashrate(int threads, xmrig::Controller *controller) : +Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) : m_highest(0.0), m_threads(threads), m_controller(controller) @@ -54,13 +55,10 @@ Hashrate::Hashrate(int threads, xmrig::Controller *controller) : m_timestamps = new uint64_t*[threads]; m_top = new uint32_t[threads]; - for (int i = 0; i < threads; i++) { - m_counts[i] = new uint64_t[kBucketSize]; - m_timestamps[i] = new uint64_t[kBucketSize]; - m_top[i] = 0; - - memset(m_counts[0], 0, sizeof(uint64_t) * kBucketSize); - memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize); + for (size_t i = 0; i < threads; i++) { + m_counts[i] = new uint64_t[kBucketSize](); + m_timestamps[i] = new uint64_t[kBucketSize](); + m_top[i] = 0; } const int printTime = controller->config()->printTime(); @@ -79,7 +77,7 @@ double Hashrate::calc(size_t ms) const double result = 0.0; double data; - for (int i = 0; i < m_threads; ++i) { + for (size_t i = 0; i < m_threads; ++i) { data = calc(i, ms); if (isnormal(data)) { result += data; @@ -92,6 +90,8 @@ double Hashrate::calc(size_t ms) const double Hashrate::calc(size_t threadId, size_t ms) const { + assert(threadId < m_threads); + using namespace std::chrono; const uint64_t now = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); diff --git a/src/workers/Hashrate.h b/src/workers/Hashrate.h index 5f4f0eaa3..e79c757a4 100644 --- a/src/workers/Hashrate.h +++ b/src/workers/Hashrate.h @@ -43,7 +43,7 @@ public: LargeInterval = 900000 }; - Hashrate(int threads, xmrig::Controller *controller); + Hashrate(size_t threads, xmrig::Controller *controller); double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; void add(size_t threadId, uint64_t count, uint64_t timestamp); @@ -52,7 +52,7 @@ public: void updateHighest(); inline double highest() const { return m_highest; } - inline int threads() const { return m_threads; } + inline size_t threads() const { return m_threads; } private: static void onReport(uv_timer_t *handle); @@ -61,7 +61,7 @@ private: constexpr static size_t kBucketMask = kBucketSize - 1; double m_highest; - int m_threads; + size_t m_threads; uint32_t* m_top; uint64_t** m_counts; uint64_t** m_timestamps; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index e26b2030d..068c42584 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -243,10 +243,6 @@ void Workers::onTick(uv_timer_t *handle) if ((m_ticks++ & 0xF) == 0) { m_hashrate->updateHighest(); } - -# ifndef XMRIG_NO_API - Api::tick(m_hashrate); -# endif } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 81b3411a2..0dce78b60 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -59,6 +59,8 @@ public: static inline bool isEnabled() { return m_enabled; } static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } + static inline Hashrate *hashrate() { return m_hashrate; } + static inline size_t threads() { return m_status.threads; } static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } From c0a72edf9a7a6002947dbee3956f1a2c9935204d Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 10:51:29 +0700 Subject: [PATCH 20/25] Added hashrate information to "GET /1/threads" endpoint. --- src/api/ApiRouter.cpp | 13 +++++++++++-- src/workers/Workers.cpp | 20 ++++++++++++++++++++ src/workers/Workers.h | 3 ++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 08cd9bf6f..b8caac9ca 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -250,7 +250,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("cpu", cpu, allocator); doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator); - doc.AddMember("hugepages", false, allocator); + doc.AddMember("hugepages", Workers::hugePages() > 0, allocator); doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); } @@ -283,12 +283,21 @@ void ApiRouter::getThreads(rapidjson::Document &doc) const { doc.SetObject(); auto &allocator = doc.GetAllocator(); + const Hashrate *hr = Workers::hashrate(); const std::vector &threads = m_controller->config()->threads(); rapidjson::Value list(rapidjson::kArrayType); for (const xmrig::IThread *thread : threads) { - list.PushBack(thread->toAPI(doc), allocator); + rapidjson::Value value = thread->toAPI(doc); + + rapidjson::Value hashrate(rapidjson::kArrayType); + hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::ShortInterval)), allocator); + hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::MediumInterval)), allocator); + hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::LargeInterval)), allocator); + + value.AddMember("hashrate", hashrate, allocator); + list.PushBack(value, allocator); } doc.AddMember("threads", list, allocator); diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 068c42584..82ad54ebf 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -66,6 +66,26 @@ Job Workers::job() } +size_t Workers::hugePages() +{ + uv_mutex_lock(&m_mutex); + const size_t hugePages = m_status.hugePages; + uv_mutex_unlock(&m_mutex); + + return hugePages; +} + + +size_t Workers::threads() +{ + uv_mutex_lock(&m_mutex); + const size_t threads = m_status.threads; + uv_mutex_unlock(&m_mutex); + + return threads; +} + + void Workers::printHashrate(bool detail) { m_hashrate->print(); diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 0dce78b60..f96aa2cab 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -49,6 +49,8 @@ class Workers { public: static Job job(); + static size_t hugePages(); + static size_t threads(); static void printHashrate(bool detail); static void setEnabled(bool enabled); static void setJob(const Job &job, bool donate); @@ -60,7 +62,6 @@ public: static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } static inline Hashrate *hashrate() { return m_hashrate; } - static inline size_t threads() { return m_status.threads; } static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } From d04a1fcb8f163239ef955ec0bb4263e3d1f938fe Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 14:36:32 +0700 Subject: [PATCH 21/25] Add extra information to threads API. --- src/Cpu_mac.cpp | 9 ++------- src/api/ApiRouter.cpp | 2 ++ src/workers/Workers.cpp | 21 +++++++++++++++++++++ src/workers/Workers.h | 5 +++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Cpu_mac.cpp b/src/Cpu_mac.cpp index 357e15efe..085148bc4 100644 --- a/src/Cpu_mac.cpp +++ b/src/Cpu_mac.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 XMRig , * * 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 @@ -38,8 +38,3 @@ void Cpu::init() initCommon(); } - - -void Cpu::setAffinity(int id, uint64_t mask) -{ -} diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index b8caac9ca..42256cc9b 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -285,6 +285,8 @@ void ApiRouter::getThreads(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); const Hashrate *hr = Workers::hashrate(); + Workers::threadsSummary(doc); + const std::vector &threads = m_controller->config()->threads(); rapidjson::Value list(rapidjson::kArrayType); diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 82ad54ebf..e1609c0ee 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -33,6 +33,7 @@ #include "interfaces/IThread.h" #include "log/Log.h" #include "Mem.h" +#include "rapidjson/document.h" #include "workers/Handle.h" #include "workers/Hashrate.h" #include "workers/MultiWorker.h" @@ -188,6 +189,26 @@ void Workers::submit(const JobResult &result) } +#ifndef XMRIG_NO_API +void Workers::threadsSummary(rapidjson::Document &doc) +{ + uv_mutex_lock(&m_mutex); + const size_t pages[2] = { m_status.hugePages, m_status.pages }; + const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo); + uv_mutex_unlock(&m_mutex); + + auto &allocator = doc.GetAllocator(); + + rapidjson::Value hugepages(rapidjson::kArrayType); + hugepages.PushBack(pages[0], allocator); + hugepages.PushBack(pages[1], allocator); + + doc.AddMember("hugepages", hugepages, allocator); + doc.AddMember("memory", memory, allocator); +} +#endif + + void Workers::onReady(void *arg) { auto handle = static_cast(arg); diff --git a/src/workers/Workers.h b/src/workers/Workers.h index f96aa2cab..bbe9a7609 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -32,6 +32,7 @@ #include "net/Job.h" #include "net/JobResult.h" +#include "rapidjson/fwd.h" class Handle; @@ -66,6 +67,10 @@ public: static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } +# ifndef XMRIG_NO_API + static void threadsSummary(rapidjson::Document &doc); +# endif + private: static void onReady(void *arg); static void onResult(uv_async_t *handle); From bc67216f7f14aac3f7ebfa102ded0f1278f3867e Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 18 Apr 2018 09:58:06 +0700 Subject: [PATCH 22/25] Added API docs and bug fixes. --- CMakeLists.txt | 2 +- doc/API.md | 53 ++++++++++++++++++++++ doc/api/1/config.json | 63 ++++++++++++++++++++++++++ doc/api/1/summary.json | 73 ++++++++++++++++++++++++++++++ doc/api/1/threads.json | 65 ++++++++++++++++++++++++++ src/common/config/CommonConfig.cpp | 2 +- src/core/ConfigLoader_platform.h | 4 +- src/workers/Workers.cpp | 4 +- 8 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 doc/API.md create mode 100644 doc/api/1/config.json create mode 100644 doc/api/1/summary.json create mode 100644 doc/api/1/threads.json diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2a4ed75..c7017b01a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,7 @@ endif() add_definitions(/D__STDC_FORMAT_MACROS) add_definitions(/DUNICODE) -add_definitions(/DAPP_DEBUG) +#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/doc/API.md b/doc/API.md new file mode 100644 index 000000000..3357eabb5 --- /dev/null +++ b/doc/API.md @@ -0,0 +1,53 @@ +# HTTP API + +If you want use API you need choice a port where is internal HTTP server will listen for incoming connections. API will not available if miner built without `libmicrohttpd`. + +Example configuration: + +```json +"api": { + "port": 44444, + "access-token": "TOKEN", + "worker-id": null, + "ipv6": false, + "restricted": false +}, +``` + +* **port** Port for incoming connections `http://:`. +* **access-token** [Bearer](https://gist.github.com/xmrig/c75fdd1f8e0f3bac05500be2ab718f8e#file-api-html-L54) access token to secure access to API. +* **worker-id** Optional worker name, if not set will be detected automatically. +* **ipv6** Enable (`true`) or disable (`false`) IPv6 for API. +* **restricted** Use `false` to allow remote configuration. + +If you prefer use command line options instead of config file, you can use options: `--api-port`, `--api-access-token`, `--api-worker-id`, `--api-ipv6` and `api-no-restricted`. + +## Endpoints + +### GET /1/summary + +Get miner summary information. [Example](api/1/summary.json). + +### GET /1/threads + +Get detailed information about miner threads. [Example](api/1/threads.json). + + +## Restricted endpoints + +All API endpoints below allow access to sensitive information and remote configure miner. You should set `access-token` and allow unrestricted access (`"restricted": false`). + +### GET /1/config + +Get current miner configuration. [Example](api/1/config.json). + + +### PUT /1/config + +Update current miner configuration. Common use case, get current configuration, make changes, and upload it to miner. + +Curl example: + +``` +curl -v --data-binary @config.json -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer SECRET" http://127.0.0.1:44444/1/config +``` \ No newline at end of file diff --git a/doc/api/1/config.json b/doc/api/1/config.json new file mode 100644 index 000000000..2c74cfbab --- /dev/null +++ b/doc/api/1/config.json @@ -0,0 +1,63 @@ +{ + "algo": "cryptonight", + "api": { + "port": 44444, + "access-token": "TOKEN", + "worker-id": null, + "ipv6": false, + "restricted": false + }, + "av": 1, + "background": false, + "colors": true, + "cpu-affinity": null, + "cpu-priority": null, + "donate-level": 5, + "huge-pages": true, + "hw-aes": null, + "log-file": null, + "max-cpu-usage": 75, + "pools": [ + { + "url": "pool.monero.hashvault.pro:3333", + "user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", + "pass": "x", + "keepalive": false, + "nicehash": false, + "variant": -1 + }, + { + "url": "pool.supportxmr.com:3333", + "user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", + "pass": "x", + "keepalive": false, + "nicehash": false, + "variant": -1 + } + ], + "print-time": 60, + "retries": 5, + "retry-pause": 5, + "safe": false, + "threads": [ + { + "low_power_mode": 1, + "affine_to_cpu": 0 + }, + { + "low_power_mode": 1, + "affine_to_cpu": 1 + }, + { + "low_power_mode": 1, + "affine_to_cpu": 2 + }, + { + "low_power_mode": 1, + "affine_to_cpu": 3 + } + ], + "user-agent": null, + "syslog": false, + "watch": false +} \ No newline at end of file diff --git a/doc/api/1/summary.json b/doc/api/1/summary.json new file mode 100644 index 000000000..ed3cd1284 --- /dev/null +++ b/doc/api/1/summary.json @@ -0,0 +1,73 @@ +{ + "id": "92f3104f9a2ee78c", + "worker_id": "Ubuntu-1604-xenial-64-minimal", + "version": "2.6.0-beta3", + "kind": "cpu", + "ua": "XMRig/2.6.0-beta3 (Linux x86_64) libuv/1.8.0 gcc/5.4.0", + "cpu": { + "brand": "Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz", + "aes": true, + "x64": true, + "sockets": 1 + }, + "algo": "cryptonight", + "hugepages": true, + "donate_level": 5, + "hashrate": { + "total": [ + 296.24, + 296.23, + 295.97 + ], + "highest": 296.5, + "threads": [ + [ + 73.39, + 73.39, + 73.28 + ], + [ + 74.72, + 74.72, + 74.71 + ], + [ + 74.72, + 74.72, + 74.71 + ], + [ + 73.39, + 73.39, + 73.27 + ] + ] + }, + "results": { + "diff_current": 9990, + "shares_good": 30, + "shares_total": 30, + "avg_time": 31, + "hashes_total": 311833, + "best": [ + 278199, + 181923, + 103717, + 96632, + 56154, + 51580, + 45667, + 33159, + 29581, + 29514 + ], + "error_log": [] + }, + "connection": { + "pool": "pool.monero.hashvault.pro:3333", + "uptime": 953, + "ping": 35, + "failures": 0, + "error_log": [] + } +} \ No newline at end of file diff --git a/doc/api/1/threads.json b/doc/api/1/threads.json new file mode 100644 index 000000000..e536883d1 --- /dev/null +++ b/doc/api/1/threads.json @@ -0,0 +1,65 @@ +{ + "hugepages": [ + 4, + 4 + ], + "memory": 8388608, + "threads": [ + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 0, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 73.39, + 73.4, + 73.28 + ] + }, + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 1, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 74.72, + 74.72, + 74.7 + ] + }, + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 2, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 74.71, + 74.72, + 74.7 + ] + }, + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 3, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 73.39, + 73.4, + 73.28 + ] + } + ] +} \ No newline at end of file diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 2cce845cc..22fd348da 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -205,12 +205,12 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case SyslogKey: /* --syslog */ case KeepAliveKey: /* --keepalive */ case NicehashKey: /* --nicehash */ + case ApiIPv6Key: /* --api-ipv6 */ return parseBoolean(key, true); case ColorKey: /* --no-color */ case WatchKey: /* --no-watch */ case ApiRestrictedKey: /* --api-no-restricted */ - case ApiIPv6Key: /* --api-no-ipv6 */ return parseBoolean(key, false); case DonateLevelKey: /* --donate-level */ diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index 7e1a4baa8..d02a9e8f0 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -85,6 +85,8 @@ Options:\n\ --api-port=N port for the miner API\n\ --api-access-token=T access token for API\n\ --api-worker-id=ID custom worker-id for API\n\ + --api-ipv6 enable IPv6 support for API\n\ + --api-no-restricted enable full remote access (only if API token set)\n\ -h, --help display this help and exit\n\ -V, --version output version information and exit\n\ "; @@ -98,7 +100,7 @@ static struct option const options[] = { { "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, { "api-port", 1, nullptr, xmrig::IConfig::ApiPort }, { "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, - { "api-no-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, + { "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "av", 1, nullptr, xmrig::IConfig::AVKey }, { "background", 0, nullptr, xmrig::IConfig::BackgroundKey }, diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index e1609c0ee..25e1d0685 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -193,8 +193,8 @@ void Workers::submit(const JobResult &result) void Workers::threadsSummary(rapidjson::Document &doc) { uv_mutex_lock(&m_mutex); - const size_t pages[2] = { m_status.hugePages, m_status.pages }; - const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo); + const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; + const uint64_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo); uv_mutex_unlock(&m_mutex); auto &allocator = doc.GetAllocator(); From ad94e9a7d273df6818e1817b4f04a149b6019e5f Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 11:54:11 +0700 Subject: [PATCH 23/25] Simplify ARM implementation. --- src/Cpu_arm.cpp | 20 ++-- src/Summary.cpp | 33 ++++--- src/crypto/CryptoNight.h | 9 -- src/crypto/CryptoNight_arm.h | 172 +++++++++++------------------------ 4 files changed, 86 insertions(+), 148 deletions(-) diff --git a/src/Cpu_arm.cpp b/src/Cpu_arm.cpp index 1b3067894..59ff84217 100644 --- a/src/Cpu_arm.cpp +++ b/src/Cpu_arm.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * 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 @@ -28,16 +28,16 @@ #include "Cpu.h" -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -int Cpu::m_totalThreads = 0; +char Cpu::m_brand[64] = { 0 }; +int Cpu::m_flags = 0; +int Cpu::m_l2_cache = 0; +int Cpu::m_l3_cache = 0; +int Cpu::m_sockets = 1; +int Cpu::m_totalCores = 0; +size_t Cpu::m_totalThreads = 0; -int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) +size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) { return m_totalThreads; } diff --git a/src/Summary.cpp b/src/Summary.cpp index a54214e46..32a0e4bb8 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -93,21 +93,30 @@ static void print_cpu(xmrig::Config *config) static void print_threads(xmrig::Config *config) { - char buf[32]; - if (config->affinity() != -1L) { - snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity()); + if (config->threadsMode() != xmrig::Config::Advanced) { + char buf[32]; + if (config->affinity() != -1L) { + snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity()); + } + else { + buf[0] = '\0'; + } + + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", + config->threadsCount(), + config->algoName(), + config->algoVariant(), + config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", + config->donateLevel(), + buf); } else { - buf[0] = '\0'; + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%", + config->threadsCount(), + config->algoName(), + config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", + config->donateLevel()); } - - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", - config->threadsCount(), - config->algoName(), - config->algoVariant(), - config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", - config->donateLevel(), - buf); } diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 5a4a266d5..e8e86dc42 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -30,15 +30,6 @@ #include -#define AEON_MEMORY 1048576 -#define AEON_MASK 0xFFFF0 -#define AEON_ITER 0x40000 - -#define MONERO_MEMORY 2097152 -#define MONERO_MASK 0x1FFFF0 -#define MONERO_ITER 0x80000 - - struct cryptonight_ctx { alignas(16) uint8_t state[200]; alignas(16) uint8_t* memory; diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index 101a1f58b..fd8c19209 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -73,6 +73,13 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64 } +static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) +{ + alignas(16) const __m128i zero = { 0 }; + return veorq_u8(vaesmcq_u8(vaeseq_u8(v, zero)), rkey ); +} + + /* this one was not implemented yet so here it is */ static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i a) { @@ -155,19 +162,19 @@ static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, _ *k0 = xout0; *k1 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x01>(&xout0, &xout2) : soft_aes_genkey_sub<0x01>(&xout0, &xout2); + soft_aes_genkey_sub<0x01>(&xout0, &xout2); *k2 = xout0; *k3 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x02>(&xout0, &xout2) : soft_aes_genkey_sub<0x02>(&xout0, &xout2); + soft_aes_genkey_sub<0x02>(&xout0, &xout2); *k4 = xout0; *k5 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x04>(&xout0, &xout2) : soft_aes_genkey_sub<0x04>(&xout0, &xout2); + soft_aes_genkey_sub<0x04>(&xout0, &xout2); *k6 = xout0; *k7 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x08>(&xout0, &xout2) : soft_aes_genkey_sub<0x08>(&xout0, &xout2); + soft_aes_genkey_sub<0x08>(&xout0, &xout2); *k8 = xout0; *k9 = xout2; } @@ -186,18 +193,16 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, *x6 = soft_aesenc((uint32_t*)x6, key); *x7 = soft_aesenc((uint32_t*)x7, key); } -# ifndef XMRIG_ARMv7 else { - *x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key)); - *x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key)); - *x2 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x2), key)); - *x3 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x3), key)); - *x4 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x4), key)); - *x5 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x5), key)); - *x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key)); - *x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key)); + *x0 = _mm_aesenc_si128(*x0, key); + *x1 = _mm_aesenc_si128(*x1, key); + *x2 = _mm_aesenc_si128(*x2, key); + *x3 = _mm_aesenc_si128(*x3, key); + *x4 = _mm_aesenc_si128(*x4, key); + *x5 = _mm_aesenc_si128(*x5, key); + *x6 = _mm_aesenc_si128(*x6, key); + *x7 = _mm_aesenc_si128(*x7, key); } -# endif } @@ -234,10 +239,6 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { for (size_t i = 0; i < 16; i++) { - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -247,30 +248,13 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - if (!SOFT_AES) { - xin0 ^= k9; - xin1 ^= k9; - xin2 ^= k9; - xin3 ^= k9; - xin4 ^= k9; - xin5 ^= k9; - xin6 ^= k9; - xin7 ^= k9; - } - else { - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7); } } for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -280,20 +264,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - if (!SOFT_AES) { - xin0 ^= k9; - xin1 ^= k9; - xin2 ^= k9; - xin3 ^= k9; - xin4 ^= k9; - xin5 ^= k9; - xin6 ^= k9; - xin7 ^= k9; - } - else { - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); _mm_store_si128(output + i + 0, xin0); _mm_store_si128(output + i + 1, xin1); @@ -335,10 +306,6 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); @@ -348,20 +315,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - - if (!SOFT_AES) { - xout0 ^= k9; - xout1 ^= k9; - xout2 ^= k9; - xout3 ^= k9; - xout4 ^= k9; - xout5 ^= k9; - xout6 ^= k9; - xout7 ^= k9; - } - else { - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); @@ -379,10 +333,6 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); @@ -392,29 +342,12 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - - if (!SOFT_AES) { - xout0 ^= k9; - xout1 ^= k9; - xout2 ^= k9; - xout3 ^= k9; - xout4 ^= k9; - xout5 ^= k9; - xout6 ^= k9; - xout7 ^= k9; - } - else { - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); } for (size_t i = 0; i < 16; i++) { - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); @@ -424,20 +357,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - - if (!SOFT_AES) { - xout0 ^= k9; - xout1 ^= k9; - xout2 ^= k9; - xout3 ^= k9; - xout4 ^= k9; - xout5 ^= k9; - xout6 ^= k9; - xout7 ^= k9; - } - else { - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); } @@ -454,6 +374,21 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } +static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) +{ + mem_out[0] = EXTRACT64(tmp); + + uint64_t vh = vgetq_lane_u64(tmp, 1); + + uint8_t x = vh >> 24; + static const uint16_t table = 0x7531; + const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1; + vh ^= ((table >> index) & 0x3) << 28; + + mem_out[1] = vh; +} + + template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { @@ -489,13 +424,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } else { cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); -# ifndef XMRIG_ARMv7 - cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0); -# endif + cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); + } + + if (VARIANT > 0) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + } else { + _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); - VARIANT1_1(&l0[idx0 & MASK]); idx0 = EXTRACT64(cx); bx0 = cx; @@ -580,16 +517,17 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si else { cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); -# ifndef XMRIG_ARMv7 - cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0); - cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1); -# endif + cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); + cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); } - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); - VARIANT1_1(&l0[idx0 & MASK]); - VARIANT1_1(&l1[idx1 & MASK]); + if (VARIANT > 0) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + } else { + _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + }; idx0 = EXTRACT64(cx0); idx1 = EXTRACT64(cx1); From e119f7f40217bc7ef2da412bf1dbd5977b0c95c7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 13:50:06 +0700 Subject: [PATCH 24/25] Rearrange test vectors, for catch cn-heavy bug. --- src/crypto/CryptoNight_test.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 52dd2965b..93cbf23de 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -27,16 +27,16 @@ const static uint8_t test_input[380] = { - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, + 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, + 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, + 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, + 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, + 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, 0x07, 0x07, 0xB4, 0x87, 0xD0, 0xD6, 0x05, 0x26, 0xE0, 0xC6, 0xDD, 0x9B, 0xC7, 0x18, 0xC3, 0xCF, 0x52, 0x04, 0xBD, 0x4F, 0x9B, 0x27, 0xF6, 0x73, 0xB9, 0x3F, 0xEF, 0x7B, 0xB2, 0xF7, 0x2B, 0xBB, 0x3F, 0x3E, 0x9C, 0x3E, 0x9D, 0x33, 0x1E, 0xDE, 0xAD, 0xBE, 0xEF, 0x4E, 0x00, 0x91, 0x81, 0x29, @@ -56,10 +56,10 @@ const static uint8_t test_input[380] = { const static uint8_t test_output_v0[160] = { - 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, - 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00, + 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, + 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, 0xA1, 0xB4, 0xFA, 0xE3, 0xE5, 0x76, 0xCE, 0xCF, 0xB7, 0x9C, 0xAF, 0x3E, 0x29, 0x92, 0xE4, 0xE0, 0x31, 0x24, 0x05, 0x48, 0xBF, 0x8D, 0x5F, 0x7B, 0x11, 0x03, 0x60, 0xAA, 0xD7, 0x50, 0x3F, 0x0C, 0x2D, 0x30, 0xF3, 0x87, 0x4F, 0x86, 0xA1, 0x4A, 0xB5, 0xA2, 0x1A, 0x08, 0xD0, 0x44, 0x2C, 0x9D, @@ -71,10 +71,10 @@ const static uint8_t test_output_v0[160] = { // Monero v7 const static uint8_t test_output_v1[160] = { - 0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D, - 0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22, 0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9, - 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, + 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, + 0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D, + 0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22, 0xE7, 0x8C, 0x5A, 0x6E, 0x38, 0x30, 0x68, 0x4A, 0x73, 0xFC, 0x1B, 0xC6, 0x6D, 0xFC, 0x8D, 0x98, 0xB4, 0xC2, 0x23, 0x39, 0xAD, 0xE0, 0x9D, 0xF6, 0x6D, 0x8C, 0x6A, 0xAA, 0xF9, 0xB2, 0xE3, 0x4C, 0xB6, 0x90, 0x6C, 0xE6, 0x15, 0x5E, 0x46, 0x07, 0x9C, 0xB2, 0x6B, 0xAC, 0x3B, 0xAC, 0x1A, 0xDE, @@ -86,10 +86,10 @@ const static uint8_t test_output_v1[160] = { #ifndef XMRIG_NO_AEON const static uint8_t test_output_v0_lite[160] = { - 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, - 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, + 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, + 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, 0x38, 0x08, 0xE1, 0x17, 0x0B, 0x99, 0x8D, 0x1A, 0x3C, 0xCE, 0x35, 0xC5, 0xC7, 0x3A, 0x00, 0x2E, 0xCB, 0x54, 0xF0, 0x78, 0x2E, 0x9E, 0xDB, 0xC7, 0xDF, 0x2E, 0x71, 0x9A, 0x16, 0x97, 0xC4, 0x18, 0x4B, 0x97, 0x07, 0xFE, 0x5D, 0x98, 0x9A, 0xD6, 0xD8, 0xE5, 0x92, 0x66, 0x87, 0x7F, 0x19, 0x37, @@ -101,10 +101,10 @@ const static uint8_t test_output_v0_lite[160] = { // AEON v7 const static uint8_t test_output_v1_lite[160] = { - 0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45, - 0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F, 0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22, 0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41, + 0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45, + 0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F, 0x16, 0x08, 0x74, 0xC7, 0xA2, 0xD2, 0xA3, 0x97, 0x95, 0x76, 0xCA, 0x4D, 0x06, 0x39, 0x7A, 0xAB, 0x6C, 0x87, 0x58, 0x33, 0x4D, 0xC8, 0x5A, 0xAB, 0x04, 0x27, 0xFE, 0x8B, 0x1C, 0x23, 0x2F, 0x32, 0xC0, 0x44, 0xFF, 0x0D, 0xB5, 0x3B, 0x27, 0x96, 0x06, 0x89, 0x7B, 0xA3, 0x0B, 0xD0, 0xCE, 0x9E, @@ -117,10 +117,10 @@ const static uint8_t test_output_v1_lite[160] = { #ifndef XMRIG_NO_SUMO const static uint8_t test_output_heavy[160] = { - 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, - 0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D, 0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64, 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2, + 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, + 0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D, 0x3E, 0xE1, 0x23, 0x03, 0x5A, 0x63, 0x7B, 0x66, 0xF6, 0xD7, 0xC2, 0x2A, 0x34, 0x5E, 0x88, 0xE7, 0xFA, 0xC4, 0x25, 0x36, 0x54, 0xCB, 0xD2, 0x5C, 0x2F, 0x80, 0x2A, 0xF9, 0xCC, 0x43, 0xF7, 0xCD, 0xE5, 0x18, 0xA8, 0x05, 0x60, 0x18, 0xA5, 0x73, 0x72, 0x9B, 0x32, 0xDC, 0x69, 0x83, 0xC1, 0xE1, From 14576f599c3e4113704e1457d97badcbbb8bb89e Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 19:44:17 +0700 Subject: [PATCH 25/25] Fix ARMv7 build. --- src/crypto/CryptoNight_arm.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index fd8c19209..746de79cc 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -73,11 +73,17 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64 } +#ifdef XMRIG_ARMv8 static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) { alignas(16) const __m128i zero = { 0 }; return veorq_u8(vaesmcq_u8(vaeseq_u8(v, zero)), rkey ); } +#else +static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) +{ +} +#endif /* this one was not implemented yet so here it is */