Merge of xmrig v6.5.0

This commit is contained in:
MoneroOcean 2020-11-02 15:08:16 +00:00
commit a57d1bbbda
86 changed files with 15293 additions and 490 deletions

View file

@ -92,24 +92,15 @@ namespace randomx {
argon2_ctx_mem(&context, Argon2_d, cache->memory, RandomX_CurrentConfig.ArgonMemory * 1024);
cache->reciprocalCache.clear();
randomx::Blake2Generator gen(key, keySize);
for (uint32_t i = 0; i < RandomX_CurrentConfig.CacheAccesses; ++i) {
randomx::generateSuperscalar(cache->programs[i], gen);
for (unsigned j = 0; j < cache->programs[i].getSize(); ++j) {
auto& instr = cache->programs[i](j);
if ((SuperscalarInstructionType)instr.opcode == SuperscalarInstructionType::IMUL_RCP) {
auto rcp = randomx_reciprocal(instr.getImm32());
instr.setImm32(cache->reciprocalCache.size());
cache->reciprocalCache.push_back(rcp);
}
}
}
}
void initCacheCompile(randomx_cache* cache, const void* key, size_t keySize) {
initCache(cache, key, keySize);
cache->jit->generateSuperscalarHash(cache->programs, cache->reciprocalCache);
cache->jit->generateSuperscalarHash(cache->programs);
cache->jit->generateDatasetInitCode();
}
@ -144,7 +135,7 @@ namespace randomx {
rx_prefetch_nta(mixBlock);
SuperscalarProgram& prog = cache->programs[i];
executeSuperscalar(rl, prog, &cache->reciprocalCache);
executeSuperscalar(rl, prog);
for (unsigned q = 0; q < 8; ++q)
rl[q] ^= load64_native(mixBlock + 8 * q);

View file

@ -47,7 +47,6 @@ struct randomx_cache {
randomx::CacheInitializeFunc* initialize;
randomx::DatasetInitFunc* datasetInit;
randomx::SuperscalarProgram programs[RANDOMX_CACHE_MAX_ACCESSES];
std::vector<uint64_t> reciprocalCache;
bool isInitialized() {
return programs[0].getSize() != 0;

View file

@ -230,7 +230,7 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
}
template<size_t N>
void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N], std::vector<uint64_t> &reciprocalCache)
void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
{
uint32_t codePos = CodeSize;
@ -263,7 +263,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N], s
{
const Instruction& instr = prog(j);
if (static_cast<SuperscalarInstructionType>(instr.opcode) == randomx::SuperscalarInstructionType::IMUL_RCP)
emit64(reciprocalCache[instr.getImm32()], code, codePos);
emit64(randomx_reciprocal(instr.getImm32()), code, codePos);
}
// Jump over literal pool
@ -345,7 +345,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N], s
clear_code_cache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos));
}
template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES], std::vector<uint64_t> &reciprocalCache);
template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]);
DatasetInitFunc* JitCompilerA64::getDatasetInitFunc()
{

View file

@ -38,7 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace randomx {
class Program;
class ProgramConfiguration;
struct ProgramConfiguration;
class SuperscalarProgram;
class Instruction;
@ -54,7 +54,7 @@ namespace randomx {
void generateProgramLight(Program&, ProgramConfiguration&, uint32_t);
template<size_t N>
void generateSuperscalarHash(SuperscalarProgram(&programs)[N], std::vector<uint64_t> &);
void generateSuperscalarHash(SuperscalarProgram(&programs)[N]);
void generateDatasetInitCode() {}

View file

@ -52,7 +52,7 @@ namespace randomx {
}
template<size_t N>
void generateSuperscalarHash(SuperscalarProgram(&programs)[N], std::vector<uint64_t> &) {
void generateSuperscalarHash(SuperscalarProgram(&programs)[N]) {
}
void generateDatasetInitCode() {

View file

@ -96,24 +96,30 @@ namespace randomx {
*/
#define codePrefetchScratchpad ((uint8_t*)&randomx_prefetch_scratchpad)
#define codePrefetchScratchpadEnd ((uint8_t*)&randomx_prefetch_scratchpad_end)
#define codePrologue ((uint8_t*)&randomx_program_prologue)
#define codeLoopBegin ((uint8_t*)&randomx_program_loop_begin)
#define codeLoopLoad ((uint8_t*)&randomx_program_loop_load)
#define codeLoopLoadXOP ((uint8_t*)&randomx_program_loop_load_xop)
#define codeProgamStart ((uint8_t*)&randomx_program_start)
#define codeReadDatasetLightSshInit ((uint8_t*)&randomx_program_read_dataset_sshash_init)
#define codeReadDatasetLightSshFin ((uint8_t*)&randomx_program_read_dataset_sshash_fin)
#define codeDatasetInit ((uint8_t*)&randomx_dataset_init)
#define codeLoopStore ((uint8_t*)&randomx_program_loop_store)
#define codeLoopEnd ((uint8_t*)&randomx_program_loop_end)
#define codeEpilogue ((uint8_t*)&randomx_program_epilogue)
#define codeProgramEnd ((uint8_t*)&randomx_program_end)
#define codeShhLoad ((uint8_t*)&randomx_sshash_load)
#define codeShhPrefetch ((uint8_t*)&randomx_sshash_prefetch)
#define codeShhEnd ((uint8_t*)&randomx_sshash_end)
#define codeShhInit ((uint8_t*)&randomx_sshash_init)
# if defined(_MSC_VER) && (defined(_DEBUG) || defined (RELWITHDEBINFO))
#define ADDR(x) ((((uint8_t*)&x)[0] == 0xE9) ? (((uint8_t*)&x) + *(const int32_t*)(((uint8_t*)&x) + 1) + 5) : ((uint8_t*)&x))
# else
#define ADDR(x) ((uint8_t*)&x)
# endif
#define codePrefetchScratchpad ADDR(randomx_prefetch_scratchpad)
#define codePrefetchScratchpadEnd ADDR(randomx_prefetch_scratchpad_end)
#define codePrologue ADDR(randomx_program_prologue)
#define codeLoopBegin ADDR(randomx_program_loop_begin)
#define codeLoopLoad ADDR(randomx_program_loop_load)
#define codeLoopLoadXOP ADDR(randomx_program_loop_load_xop)
#define codeProgamStart ADDR(randomx_program_start)
#define codeReadDatasetLightSshInit ADDR(randomx_program_read_dataset_sshash_init)
#define codeReadDatasetLightSshFin ADDR(randomx_program_read_dataset_sshash_fin)
#define codeDatasetInit ADDR(randomx_dataset_init)
#define codeLoopStore ADDR(randomx_program_loop_store)
#define codeLoopEnd ADDR(randomx_program_loop_end)
#define codeEpilogue ADDR(randomx_program_epilogue)
#define codeProgramEnd ADDR(randomx_program_end)
#define codeShhLoad ADDR(randomx_sshash_load)
#define codeShhPrefetch ADDR(randomx_sshash_prefetch)
#define codeShhEnd ADDR(randomx_sshash_end)
#define codeShhInit ADDR(randomx_sshash_init)
#define prefetchScratchpadSize (codePrefetchScratchpadEnd - codePrefetchScratchpad)
#define prologueSize (codeLoopBegin - codePrologue)
@ -264,14 +270,14 @@ namespace randomx {
}
template<size_t N>
void JitCompilerX86::generateSuperscalarHash(SuperscalarProgram(&programs)[N], std::vector<uint64_t> &reciprocalCache) {
void JitCompilerX86::generateSuperscalarHash(SuperscalarProgram(&programs)[N]) {
memcpy(code + superScalarHashOffset, codeShhInit, codeSshInitSize);
codePos = superScalarHashOffset + codeSshInitSize;
for (unsigned j = 0; j < RandomX_CurrentConfig.CacheAccesses; ++j) {
SuperscalarProgram& prog = programs[j];
for (unsigned i = 0; i < prog.getSize(); ++i) {
Instruction& instr = prog(i);
generateSuperscalarCode(instr, reciprocalCache);
generateSuperscalarCode(instr);
}
emit(codeShhLoad, codeSshLoadSize, code, codePos);
if (j < RandomX_CurrentConfig.CacheAccesses - 1) {
@ -284,7 +290,7 @@ namespace randomx {
}
template
void JitCompilerX86::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES], std::vector<uint64_t> &reciprocalCache);
void JitCompilerX86::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]);
void JitCompilerX86::generateDatasetInitCode() {
memcpy(code, codeDatasetInit, datasetInitSize);
@ -366,7 +372,7 @@ namespace randomx {
emit32(epilogueOffset - codePos - 4, code, codePos);
}
void JitCompilerX86::generateSuperscalarCode(Instruction& instr, std::vector<uint64_t> &reciprocalCache) {
void JitCompilerX86::generateSuperscalarCode(Instruction& instr) {
static constexpr uint8_t REX_SUB_RR[] = { 0x4d, 0x2b };
static constexpr uint8_t REX_MOV_RR64[] = { 0x49, 0x8b };
static constexpr uint8_t REX_MOV_R64R[] = { 0x4c, 0x8b };
@ -452,7 +458,7 @@ namespace randomx {
break;
case randomx::SuperscalarInstructionType::IMUL_RCP:
emit(MOV_RAX_I, code, codePos);
emit64(reciprocalCache[instr.getImm32()], code, codePos);
emit64(randomx_reciprocal_fast(instr.getImm32()), code, codePos);
emit(REX_IMUL_RM, code, codePos);
emitByte(0xc0 + 8 * instr.dst, code, codePos);
break;

View file

@ -53,7 +53,7 @@ namespace randomx {
void generateProgram(Program&, ProgramConfiguration&, uint32_t);
void generateProgramLight(Program&, ProgramConfiguration&, uint32_t);
template<size_t N>
void generateSuperscalarHash(SuperscalarProgram (&programs)[N], std::vector<uint64_t> &);
void generateSuperscalarHash(SuperscalarProgram (&programs)[N]);
void generateDatasetInitCode();
ProgramFunc* getProgramFunc() {
return (ProgramFunc*)code;
@ -92,7 +92,7 @@ namespace randomx {
static void genAddressImm(const Instruction&, uint8_t* code, uint32_t& codePos);
static void genSIB(int scale, int index, int base, uint8_t* code, uint32_t& codePos);
void generateSuperscalarCode(Instruction &, std::vector<uint64_t> &);
void generateSuperscalarCode(Instruction &);
static void emitByte(uint8_t val, uint8_t* code, uint32_t& codePos) {
code[codePos] = val;

View file

@ -847,7 +847,7 @@ namespace randomx {
}*/
}
void executeSuperscalar(int_reg_t(&r)[8], SuperscalarProgram& prog, std::vector<uint64_t> *reciprocals) {
void executeSuperscalar(int_reg_t(&r)[8], SuperscalarProgram& prog) {
for (unsigned j = 0; j < prog.getSize(); ++j) {
Instruction& instr = prog(j);
switch ((SuperscalarInstructionType)instr.opcode)
@ -884,10 +884,7 @@ namespace randomx {
r[instr.dst] = smulh(r[instr.dst], r[instr.src]);
break;
case SuperscalarInstructionType::IMUL_RCP:
if (reciprocals != nullptr)
r[instr.dst] *= (*reciprocals)[instr.getImm32()];
else
r[instr.dst] *= randomx_reciprocal(instr.getImm32());
r[instr.dst] *= randomx_reciprocal(instr.getImm32());
break;
default:
UNREACHABLE;

View file

@ -56,5 +56,5 @@ namespace randomx {
};
void generateSuperscalar(SuperscalarProgram& prog, Blake2Generator& gen);
void executeSuperscalar(uint64_t(&r)[8], SuperscalarProgram& prog, std::vector<uint64_t> *reciprocals = nullptr);
void executeSuperscalar(uint64_t(&r)[8], SuperscalarProgram& prog);
}

View file

@ -36,7 +36,7 @@ namespace randomx {
void CompiledLightVm<softAes>::setCache(randomx_cache* cache) {
cachePtr = cache;
mem.memory = cache->memory;
compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
compiler.generateSuperscalarHash(cache->programs);
}
template<int softAes>

View file

@ -42,6 +42,7 @@ class RxPrivate;
static bool osInitialized = false;
static bool msrInitialized = false;
static bool msrEnabled = false;
static RxPrivate *d_ptr = nullptr;
@ -93,7 +94,8 @@ bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu
if (seed.algorithm().family() != Algorithm::RANDOM_X) {
if (msrInitialized) {
msrDestroy();
msrInitialized = false;
msrInitialized = false;
msrEnabled = false;
}
return true;
@ -107,8 +109,8 @@ bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu
}
if (!msrInitialized) {
msrInit(config, cpu.threads().get(seed.algorithm()).data());
msrInitialized = true;
msrEnabled = msrInit(config, cpu.threads().get(seed.algorithm()).data());
msrInitialized = true;
}
if (!osInitialized) {
@ -132,9 +134,15 @@ bool xmrig::Rx::isReady(const T &seed)
}
#ifndef XMRIG_FEATURE_MSR
void xmrig::Rx::msrInit(const RxConfig &, const std::vector<CpuThread> &)
#ifdef XMRIG_FEATURE_MSR
bool xmrig::Rx::isMSR()
{
return msrEnabled;
}
#else
bool xmrig::Rx::msrInit(const RxConfig &, const std::vector<CpuThread> &)
{
return false;
}

View file

@ -63,8 +63,14 @@ public:
static void setMainLoopBounds(const std::pair<const void*, const void*>& bounds);
# endif
# ifdef XMRIG_FEATURE_MSR
static bool isMSR();
# else
static constexpr bool isMSR() { return false; }
# endif
private:
static void msrInit(const RxConfig &config, const std::vector<CpuThread>& threads);
static bool msrInit(const RxConfig &config, const std::vector<CpuThread>& threads);
static void msrDestroy();
static void setupMainLoopExceptionFrame();
};

View file

@ -27,9 +27,9 @@
#include "crypto/rx/RxQueue.h"
#include "backend/common/interfaces/IRxListener.h"
#include "base/io/Async.h"
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/tools/Handle.h"
#include "crypto/rx/RxBasicStorage.h"
@ -41,11 +41,7 @@
xmrig::RxQueue::RxQueue(IRxListener *listener) :
m_listener(listener)
{
m_async = new uv_async_t;
m_async->data = this;
uv_async_init(uv_default_loop(), m_async, [](uv_async_t *handle) { static_cast<RxQueue *>(handle->data)->onReady(); });
m_async = std::make_shared<Async>(this);
m_thread = std::thread(&RxQueue::backgroundInit, this);
}
@ -61,8 +57,6 @@ xmrig::RxQueue::~RxQueue()
m_thread.join();
delete m_storage;
Handle::close(m_async);
}
@ -167,7 +161,7 @@ void xmrig::RxQueue::backgroundInit()
}
m_state = STATE_IDLE;
uv_async_send(m_async);
m_async->send();
}
}

View file

@ -28,7 +28,7 @@
#define XMRIG_RX_QUEUE_H
#include "base/io/Async.h"
#include "base/kernel/interfaces/IAsyncListener.h"
#include "base/tools/Object.h"
#include "crypto/common/HugePagesInfo.h"
#include "crypto/rx/RxConfig.h"
@ -40,9 +40,6 @@
#include <thread>
using uv_async_t = struct uv_async_s;
namespace xmrig
{
@ -75,19 +72,22 @@ public:
};
class RxQueue
class RxQueue : public IAsyncListener
{
public:
XMRIG_DISABLE_COPY_MOVE(RxQueue);
RxQueue(IRxListener *listener);
~RxQueue();
~RxQueue() override;
HugePagesInfo hugePages();
RxDataset *dataset(const Job &job, uint32_t nodeId);
template<typename T> bool isReady(const T &seed);
void enqueue(const RxSeed &seed, const std::vector<uint32_t> &nodeset, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority);
protected:
inline void onAsync() override { onReady(); }
private:
enum State {
STATE_IDLE,
@ -105,9 +105,9 @@ private:
State m_state = STATE_IDLE;
std::condition_variable m_cv;
std::mutex m_mutex;
std::shared_ptr<Async> m_async;
std::thread m_thread;
std::vector<RxQueueItem> m_queue;
uv_async_t *m_async = nullptr;
};

View file

@ -151,7 +151,7 @@ static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value, uint64_t mask, T&& c
static bool wrmsr_modprobe()
{
if (system("/sbin/modprobe msr > /dev/null 2>&1") != 0) {
if (system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") != 0) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "msr kernel module is not available", tag);
return false;
@ -272,21 +272,25 @@ void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
} // namespace xmrig
void xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread>& threads)
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread> &threads)
{
const auto &preset = config.msrPreset();
if (preset.empty()) {
return;
return false;
}
const uint64_t ts = Chrono::steadyMSecs();
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
return true;
}
else {
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
}
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
return false;
}

View file

@ -117,7 +117,7 @@ static HANDLE wrmsr_install_driver()
return nullptr;
}
for (auto it = dir.end(); it != dir.begin(); --it) {
for (auto it = dir.end() - 1; it != dir.begin(); --it) {
if ((*it == L'\\') || (*it == L'/')) {
++it;
*it = L'\0';
@ -395,21 +395,24 @@ void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
} // namespace xmrig
void xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread>& threads)
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread>& threads)
{
const auto &preset = config.msrPreset();
if (preset.empty()) {
return;
return false;
}
const uint64_t ts = Chrono::steadyMSecs();
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
return true;
}
else {
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
}
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
return false;
}