Revert "Integrated thread based double hash mode"
This reverts commit e264c5f8b5
.
This commit is contained in:
parent
9e3b2e857b
commit
19f0940b92
17 changed files with 133 additions and 160 deletions
|
@ -282,7 +282,7 @@ function isOnline(lastStatus) {
|
||||||
<th>Algo</th>
|
<th>Algo</th>
|
||||||
|
|
||||||
<th>Hashrate</th>
|
<th>Hashrate</th>
|
||||||
<th>Hashrate 1m</th>
|
<th>Hashrate 5m</th>
|
||||||
<th>Hashrate 60m</th>
|
<th>Hashrate 60m</th>
|
||||||
|
|
||||||
<th>Hashrate Highest</th>
|
<th>Hashrate Highest</th>
|
||||||
|
|
63
src/Mem.cpp
63
src/Mem.cpp
|
@ -30,29 +30,58 @@
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
bool Mem::m_doubleHash = false;
|
bool Mem::m_doubleHash = false;
|
||||||
int Mem::m_algo = 0;
|
int Mem::m_algo = 0;
|
||||||
int Mem::m_flags = 0;
|
int Mem::m_flags = 0;
|
||||||
int Mem::m_threads = 0;
|
int Mem::m_threads = 0;
|
||||||
size_t Mem::m_memorySize = 0;
|
size_t Mem::m_offset = 0;
|
||||||
uint8_t *Mem::m_memory = nullptr;
|
uint8_t *Mem::m_memory = nullptr;
|
||||||
int64_t Mem::m_doubleHashThreadMask = -1L;
|
|
||||||
|
|
||||||
cryptonight_ctx *Mem::create(int threadId)
|
cryptonight_ctx *Mem::create(int threadId)
|
||||||
{
|
{
|
||||||
size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
|
# ifndef XMRIG_NO_AEON
|
||||||
|
if (m_algo == Options::ALGO_CRYPTONIGHT_LITE) {
|
||||||
size_t offset = 0;
|
return createLite(threadId);
|
||||||
for (int i=0; i < threadId; i++) {
|
|
||||||
offset += sizeof(cryptonight_ctx);
|
|
||||||
offset += isDoubleHash(i) ? scratchPadSize*2 : scratchPadSize;
|
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
auto* ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset]);
|
cryptonight_ctx *ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
|
||||||
|
|
||||||
size_t memOffset = offset+sizeof(cryptonight_ctx);
|
const int ratio = m_doubleHash ? 2 : 1;
|
||||||
|
ctx->memory = &m_memory[MEMORY * (threadId * ratio + 1)];
|
||||||
ctx->memory = &m_memory[memOffset];
|
|
||||||
|
|
||||||
return ctx;
|
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 = MEMORY * (threadId + 1);
|
||||||
|
|
||||||
|
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset + MEMORY_LITE]);
|
||||||
|
ctx->memory = &m_memory[offset];
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
|
||||||
|
ctx->memory = &m_memory[MEMORY * (threadId + 1)];
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
10
src/Mem.h
10
src/Mem.h
|
@ -45,9 +45,10 @@ public:
|
||||||
|
|
||||||
static bool allocate(const Options* options);
|
static bool allocate(const Options* options);
|
||||||
static cryptonight_ctx *create(int threadId);
|
static cryptonight_ctx *create(int threadId);
|
||||||
|
static void *calloc(size_t num, size_t size);
|
||||||
static void release();
|
static void release();
|
||||||
|
|
||||||
static inline bool isDoubleHash(int threadId) { return m_doubleHash && (m_doubleHashThreadMask == -1L || ((m_doubleHashThreadMask >> threadId) & 1)); }
|
static inline bool isDoubleHash() { return m_doubleHash; }
|
||||||
static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; }
|
static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; }
|
||||||
static inline bool isHugepagesEnabled() { return (m_flags & HugepagesEnabled) != 0; }
|
static inline bool isHugepagesEnabled() { return (m_flags & HugepagesEnabled) != 0; }
|
||||||
static inline int flags() { return m_flags; }
|
static inline int flags() { return m_flags; }
|
||||||
|
@ -58,9 +59,12 @@ private:
|
||||||
static int m_algo;
|
static int m_algo;
|
||||||
static int m_flags;
|
static int m_flags;
|
||||||
static int m_threads;
|
static int m_threads;
|
||||||
static int64_t m_doubleHashThreadMask;
|
static size_t m_offset;
|
||||||
static size_t m_memorySize;
|
|
||||||
VAR_ALIGN(16, static uint8_t *m_memory);
|
VAR_ALIGN(16, static uint8_t *m_memory);
|
||||||
|
|
||||||
|
# ifndef XMRIG_NO_AEON
|
||||||
|
static cryptonight_ctx *createLite(int threadId);
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,22 +38,12 @@ bool Mem::allocate(const Options* options)
|
||||||
m_algo = options->algo();
|
m_algo = options->algo();
|
||||||
m_threads = options->threads();
|
m_threads = options->threads();
|
||||||
m_doubleHash = options->doubleHash();
|
m_doubleHash = options->doubleHash();
|
||||||
m_doubleHashThreadMask = options->doubleHashThreadMask();
|
|
||||||
m_memorySize = 0;
|
|
||||||
|
|
||||||
size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
|
const int ratio = (m_doubleHash && m_algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
|
||||||
for (int i=0; i < m_threads; i++) {
|
const size_t size = MEMORY * (m_threads * ratio + 1);
|
||||||
m_memorySize += sizeof(cryptonight_ctx);
|
|
||||||
|
|
||||||
if (isDoubleHash(i)) {
|
|
||||||
m_memorySize += scratchPadSize*2;
|
|
||||||
} else {
|
|
||||||
m_memorySize += scratchPadSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options->hugePages()) {
|
if (!options->hugePages()) {
|
||||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,20 +54,20 @@ bool Mem::allocate(const Options* options)
|
||||||
# elif defined(__FreeBSD__)
|
# elif defined(__FreeBSD__)
|
||||||
m_memory = static_cast<uint8_t*>(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
m_memory = static_cast<uint8_t*>(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||||
# else
|
# else
|
||||||
m_memory = static_cast<uint8_t*>(mmap(0, m_memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
m_memory = static_cast<uint8_t*>(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||||
# endif
|
# endif
|
||||||
if (m_memory == MAP_FAILED) {
|
if (m_memory == MAP_FAILED) {
|
||||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_flags |= HugepagesEnabled;
|
m_flags |= HugepagesEnabled;
|
||||||
|
|
||||||
if (madvise(m_memory, m_memorySize, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
if (madvise(m_memory, size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||||
LOG_ERR("madvise failed");
|
LOG_ERR("madvise failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mlock(m_memory, m_memorySize) == 0) {
|
if (mlock(m_memory, size) == 0) {
|
||||||
m_flags |= Lock;
|
m_flags |= Lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,12 +77,14 @@ bool Mem::allocate(const Options* options)
|
||||||
|
|
||||||
void Mem::release()
|
void Mem::release()
|
||||||
{
|
{
|
||||||
|
const int size = MEMORY * (m_threads + 1);
|
||||||
|
|
||||||
if (m_flags & HugepagesEnabled) {
|
if (m_flags & HugepagesEnabled) {
|
||||||
if (m_flags & Lock) {
|
if (m_flags & Lock) {
|
||||||
munlock(m_memory, m_memorySize);
|
munlock(m_memory, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
munmap(m_memory, m_memorySize);
|
munmap(m_memory, size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_mm_free(m_memory);
|
_mm_free(m_memory);
|
||||||
|
|
|
@ -149,22 +149,12 @@ bool Mem::allocate(const Options* options)
|
||||||
m_algo = options->algo();
|
m_algo = options->algo();
|
||||||
m_threads = options->threads();
|
m_threads = options->threads();
|
||||||
m_doubleHash = options->doubleHash();
|
m_doubleHash = options->doubleHash();
|
||||||
m_doubleHashThreadMask = options->doubleHashThreadMask();
|
|
||||||
m_memorySize = 0;
|
|
||||||
|
|
||||||
size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
|
const int ratio = (m_doubleHash && m_algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
|
||||||
for (int i=0; i < m_threads; i++) {
|
const size_t size = MEMORY * (m_threads * ratio + 1);
|
||||||
m_memorySize += sizeof(cryptonight_ctx);
|
|
||||||
|
|
||||||
if (isDoubleHash(i)) {
|
|
||||||
m_memorySize += scratchPadSize*2;
|
|
||||||
} else {
|
|
||||||
m_memorySize += scratchPadSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options->hugePages()) {
|
if (!options->hugePages()) {
|
||||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,9 +162,9 @@ bool Mem::allocate(const Options* options)
|
||||||
m_flags |= HugepagesAvailable;
|
m_flags |= HugepagesAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, m_memorySize, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||||
if (!m_memory) {
|
if (!m_memory) {
|
||||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_flags |= HugepagesEnabled;
|
m_flags |= HugepagesEnabled;
|
||||||
|
|
|
@ -70,7 +70,6 @@ Options:\n"
|
||||||
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\
|
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\
|
||||||
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
|
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
|
||||||
-R, --retry-pause=N time to pause between retries (default: 5)\n\
|
-R, --retry-pause=N time to pause between retries (default: 5)\n\
|
||||||
--doublehash-thread-mask for av=2/4 only, limits doublehash to given threads (mask), (default: all threads)\n\
|
|
||||||
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
|
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
|
||||||
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
|
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
|
||||||
--no-huge-pages disable huge pages support\n\
|
--no-huge-pages disable huge pages support\n\
|
||||||
|
@ -159,7 +158,6 @@ static struct option const options[] = {
|
||||||
{ "cc-client-config-folder", 1, nullptr, 4009 },
|
{ "cc-client-config-folder", 1, nullptr, 4009 },
|
||||||
{ "cc-custom-dashboard", 1, nullptr, 4010 },
|
{ "cc-custom-dashboard", 1, nullptr, 4010 },
|
||||||
{ "daemonized", 0, nullptr, 4011 },
|
{ "daemonized", 0, nullptr, 4011 },
|
||||||
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -182,7 +180,6 @@ static struct option const config_options[] = {
|
||||||
{ "syslog", 0, nullptr, 'S' },
|
{ "syslog", 0, nullptr, 'S' },
|
||||||
{ "threads", 1, nullptr, 't' },
|
{ "threads", 1, nullptr, 't' },
|
||||||
{ "user-agent", 1, nullptr, 1008 },
|
{ "user-agent", 1, nullptr, 1008 },
|
||||||
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -284,8 +281,7 @@ Options::Options(int argc, char **argv) :
|
||||||
m_threads(0),
|
m_threads(0),
|
||||||
m_ccUpdateInterval(10),
|
m_ccUpdateInterval(10),
|
||||||
m_ccPort(0),
|
m_ccPort(0),
|
||||||
m_affinity(-1L),
|
m_affinity(-1L)
|
||||||
m_doubleHashThreadMask(-1L)
|
|
||||||
{
|
{
|
||||||
m_pools.push_back(new Url());
|
m_pools.push_back(new Url());
|
||||||
|
|
||||||
|
@ -532,14 +528,9 @@ bool Options::parseArg(int key, const char *arg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1020: { /* --cpu-affinity */
|
case 1020: { /* --cpu-affinity */
|
||||||
const char *p = strstr(arg, "0x");
|
const char *p = strstr(arg, "0x");
|
||||||
return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
|
return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4013: { /* --doublehash-thread-mask */
|
|
||||||
const char *p = strstr(arg, "0x");
|
|
||||||
return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1008: /* --user-agent */
|
case 1008: /* --user-agent */
|
||||||
free(m_userAgent);
|
free(m_userAgent);
|
||||||
|
@ -643,7 +634,6 @@ bool Options::parseArg(int key, uint64_t arg)
|
||||||
m_ccPort = (int) arg;
|
m_ccPort = (int) arg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4012: /* --cc-update-interval-s */
|
case 4012: /* --cc-update-interval-s */
|
||||||
if (arg < 1) {
|
if (arg < 1) {
|
||||||
showUsage(1);
|
showUsage(1);
|
||||||
|
@ -652,12 +642,6 @@ bool Options::parseArg(int key, uint64_t arg)
|
||||||
|
|
||||||
m_ccUpdateInterval = (int) arg;
|
m_ccUpdateInterval = (int) arg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4013: /* --doublehash-thread-mask */
|
|
||||||
if (arg) {
|
|
||||||
m_doubleHashThreadMask = arg;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,8 +88,6 @@ public:
|
||||||
inline int ccUpdateInterval() const { return m_ccUpdateInterval; }
|
inline int ccUpdateInterval() const { return m_ccUpdateInterval; }
|
||||||
inline int ccPort() const { return m_ccPort; }
|
inline int ccPort() const { return m_ccPort; }
|
||||||
inline int64_t affinity() const { return m_affinity; }
|
inline int64_t affinity() const { return m_affinity; }
|
||||||
inline int64_t doubleHashThreadMask() const { return m_doubleHashThreadMask; }
|
|
||||||
inline void setColors(bool colors) { m_colors = colors; }
|
|
||||||
|
|
||||||
inline static void release() { delete m_self; }
|
inline static void release() { delete m_self; }
|
||||||
|
|
||||||
|
@ -157,7 +155,6 @@ private:
|
||||||
int m_ccUpdateInterval;
|
int m_ccUpdateInterval;
|
||||||
int m_ccPort;
|
int m_ccPort;
|
||||||
int64_t m_affinity;
|
int64_t m_affinity;
|
||||||
int64_t m_doubleHashThreadMask;
|
|
||||||
std::vector<Url*> m_pools;
|
std::vector<Url*> m_pools;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -91,30 +91,21 @@ static void print_cpu()
|
||||||
|
|
||||||
static void print_threads()
|
static void print_threads()
|
||||||
{
|
{
|
||||||
char dhtMaskBuf[64];
|
char buf[32];
|
||||||
if (Options::i()->doubleHashThreadMask() != -1L) {
|
|
||||||
snprintf(dhtMaskBuf, 64, ", doubleHashThreadMask=0x%" PRIX64, Options::i()->doubleHashThreadMask());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dhtMaskBuf[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
char affBuf[32];
|
|
||||||
if (Options::i()->affinity() != -1L) {
|
if (Options::i()->affinity() != -1L) {
|
||||||
snprintf(affBuf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
|
snprintf(buf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
affBuf[0] = '\0';
|
buf[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s%s",
|
Log::i()->text(Options::i()->colors() ? "\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",
|
||||||
Options::i()->threads(),
|
Options::i()->threads(),
|
||||||
Options::i()->algoName(),
|
Options::i()->algoName(),
|
||||||
Options::i()->algoVariant(),
|
Options::i()->algoVariant(),
|
||||||
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||||
Options::i()->donateLevel(),
|
Options::i()->donateLevel(),
|
||||||
affBuf,
|
buf);
|
||||||
dhtMaskBuf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ CCClient::CCClient(Options* options, uv_async_t* async)
|
||||||
|
|
||||||
m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled());
|
m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled());
|
||||||
m_clientStatus.setHugepages(Mem::isHugepagesAvailable());
|
m_clientStatus.setHugepages(Mem::isHugepagesAvailable());
|
||||||
m_clientStatus.setDoubleHashMode(m_options->doubleHash());
|
m_clientStatus.setDoubleHashMode(Mem::isDoubleHash());
|
||||||
|
|
||||||
m_clientStatus.setVersion(Version::string());
|
m_clientStatus.setVersion(Version::string());
|
||||||
m_clientStatus.setCpuBrand(Cpu::brand());
|
m_clientStatus.setCpuBrand(Cpu::brand());
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
void (*cryptonight_hash_ctx_s)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
|
void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
|
||||||
void (*cryptonight_hash_ctx_d)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
|
|
||||||
|
|
||||||
|
|
||||||
static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) {
|
static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) {
|
||||||
|
@ -94,43 +93,40 @@ void (*cryptonight_variations[4])(const void *input, size_t size, void *output,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void CryptoNight::hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
|
bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx)
|
||||||
{
|
{
|
||||||
cryptonight_hash_ctx_s(input, size, output, ctx);
|
cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx);
|
||||||
|
|
||||||
|
return *reinterpret_cast<uint64_t*>(result.result + 24) < job.target();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryptoNight::hashDouble(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
|
|
||||||
{
|
|
||||||
cryptonight_hash_ctx_d(input, size, output, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CryptoNight::init(int algo, int variant)
|
bool CryptoNight::init(int algo, int variant)
|
||||||
{
|
{
|
||||||
if (variant < 1 || variant > 4)
|
if (variant < 1 || variant > 4) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
# ifndef XMRIG_NO_AEON
|
||||||
|
const int index = algo == Options::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1);
|
||||||
|
# else
|
||||||
|
const int index = variant - 1;
|
||||||
|
# endif
|
||||||
|
|
||||||
if (variant == 3 || variant == 4)
|
cryptonight_hash_ctx = cryptonight_variations[index];
|
||||||
{
|
|
||||||
index = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (algo == Options::ALGO_CRYPTONIGHT_LITE) {
|
|
||||||
index += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
cryptonight_hash_ctx_s = cryptonight_variations[index];
|
|
||||||
cryptonight_hash_ctx_d = cryptonight_variations[index+1];
|
|
||||||
|
|
||||||
return selfTest(algo);
|
return selfTest(algo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CryptoNight::selfTest(int algo)
|
|
||||||
|
void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx)
|
||||||
{
|
{
|
||||||
if (cryptonight_hash_ctx_d == nullptr) {
|
cryptonight_hash_ctx(input, size, output, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CryptoNight::selfTest(int algo) {
|
||||||
|
if (cryptonight_hash_ctx == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,22 +135,14 @@ bool CryptoNight::selfTest(int algo)
|
||||||
struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
|
struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
|
||||||
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16);
|
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16);
|
||||||
|
|
||||||
cryptonight_hash_ctx_d(test_input, 76, output, ctx);
|
cryptonight_hash_ctx(test_input, 76, output, ctx);
|
||||||
|
|
||||||
_mm_free(ctx->memory);
|
_mm_free(ctx->memory);
|
||||||
_mm_free(ctx);
|
_mm_free(ctx);
|
||||||
|
|
||||||
bool resultSingle = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, 32) == 0;
|
# ifndef XMRIG_NO_AEON
|
||||||
|
return memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
|
||||||
ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
|
# else
|
||||||
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16);
|
return memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
|
||||||
|
# endif
|
||||||
cryptonight_hash_ctx_d(test_input, 76, output, ctx);
|
|
||||||
|
|
||||||
_mm_free(ctx->memory);
|
|
||||||
_mm_free(ctx);
|
|
||||||
|
|
||||||
bool resultDouble = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, 64) == 0;
|
|
||||||
|
|
||||||
return resultSingle && resultDouble;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,9 @@ class JobResult;
|
||||||
class CryptoNight
|
class CryptoNight
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
|
static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx);
|
||||||
static bool init(int algo, int variant);
|
static bool init(int algo, int variant);
|
||||||
static void hashDouble(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
|
static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool selfTest(int algo);
|
static bool selfTest(int algo);
|
||||||
|
|
|
@ -47,12 +47,14 @@ const static uint8_t test_output0[64] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_NO_AEON
|
||||||
const static uint8_t test_output1[64] = {
|
const static uint8_t test_output1[64] = {
|
||||||
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
|
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,
|
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,
|
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,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* __CRYPTONIGHT_TEST_H__ */
|
#endif /* __CRYPTONIGHT_TEST_H__ */
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "Options.h"
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
@ -41,18 +39,16 @@
|
||||||
|
|
||||||
|
|
||||||
ConsoleLog::ConsoleLog(bool colors) :
|
ConsoleLog::ConsoleLog(bool colors) :
|
||||||
m_colors(colors),
|
m_colors(colors),
|
||||||
m_stream(nullptr)
|
m_stream(nullptr)
|
||||||
{
|
{
|
||||||
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
|
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
|
||||||
Options::i()->setColors(false);
|
|
||||||
m_colors = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
|
uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
|
||||||
m_uvBuf.base = m_buf;
|
m_uvBuf.base = m_buf;
|
||||||
m_stream = reinterpret_cast<uv_stream_t*>(&m_tty);
|
m_stream = reinterpret_cast<uv_stream_t*>(&m_tty);
|
||||||
|
|
||||||
# ifdef WIN32
|
# ifdef WIN32
|
||||||
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
@ -69,6 +65,10 @@ ConsoleLog::ConsoleLog(bool colors) :
|
||||||
|
|
||||||
void ConsoleLog::message(int level, const char* fmt, va_list args)
|
void ConsoleLog::message(int level, const char* fmt, va_list args)
|
||||||
{
|
{
|
||||||
|
if (!isWritable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
tm stime;
|
tm stime;
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
|
||||||
m_colors ? color : "",
|
m_colors ? color : "",
|
||||||
fmt,
|
fmt,
|
||||||
m_colors ? Log::kCL_N : ""
|
m_colors ? Log::kCL_N : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
print(args);
|
print(args);
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,10 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
|
||||||
|
|
||||||
void ConsoleLog::text(const char* fmt, va_list args)
|
void ConsoleLog::text(const char* fmt, va_list args)
|
||||||
{
|
{
|
||||||
|
if (!isWritable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
|
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
|
||||||
|
|
||||||
print(args);
|
print(args);
|
||||||
|
@ -145,10 +149,5 @@ void ConsoleLog::print(va_list args)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isWritable()) {
|
uv_try_write(m_stream, &m_uvBuf, 1);
|
||||||
fprintf(stdout, m_buf);
|
|
||||||
fflush(stdout);
|
|
||||||
} else {
|
|
||||||
uv_try_write(m_stream, &m_uvBuf, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,18 +82,17 @@ void DoubleWorker::start()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_count += 2;
|
m_count += 2;
|
||||||
|
|
||||||
*Job::nonce(m_state->blob) = ++m_state->nonce1;
|
*Job::nonce(m_state->blob) = ++m_state->nonce1;
|
||||||
*Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2;
|
*Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2;
|
||||||
|
|
||||||
CryptoNight::hashDouble(m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
||||||
|
|
||||||
if (*reinterpret_cast<uint64_t*>(m_hash + 24) < m_state->job.target()) {
|
if (*reinterpret_cast<uint64_t*>(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()), m_id);
|
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*reinterpret_cast<uint64_t*>(m_hash + 32 + 24) < m_state->job.target()) {
|
if (*reinterpret_cast<uint64_t*>(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()), m_id);
|
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();
|
std::this_thread::yield();
|
||||||
|
|
|
@ -60,10 +60,8 @@ void SingleWorker::start()
|
||||||
m_count++;
|
m_count++;
|
||||||
*m_job.nonce() = ++m_result.nonce;
|
*m_job.nonce() = ++m_result.nonce;
|
||||||
|
|
||||||
CryptoNight::hash(m_job.blob(), m_job.size(), m_result.result, m_ctx);
|
if (CryptoNight::hash(m_job, m_result, m_ctx)) {
|
||||||
|
Workers::submit(m_result);
|
||||||
if (*reinterpret_cast<uint64_t*>(m_result.result + 24) < m_job.target()) {
|
|
||||||
Workers::submit(m_result, m_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
|
@ -105,10 +103,10 @@ void SingleWorker::consumeJob()
|
||||||
m_result = m_job;
|
m_result = m_job;
|
||||||
|
|
||||||
if (m_job.isNicehash()) {
|
if (m_job.isNicehash()) {
|
||||||
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id);
|
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_result.nonce = 0xffffffffU / (m_threads * 2) * m_id;
|
m_result.nonce = 0xffffffffU / m_threads * m_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ void Workers::stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Workers::submit(const JobResult &result, int threadId)
|
void Workers::submit(const JobResult &result)
|
||||||
{
|
{
|
||||||
uv_mutex_lock(&m_mutex);
|
uv_mutex_lock(&m_mutex);
|
||||||
m_queue.push_back(result);
|
m_queue.push_back(result);
|
||||||
|
@ -153,7 +153,7 @@ void Workers::submit(const JobResult &result, int threadId)
|
||||||
void Workers::onReady(void *arg)
|
void Workers::onReady(void *arg)
|
||||||
{
|
{
|
||||||
auto handle = static_cast<Handle*>(arg);
|
auto handle = static_cast<Handle*>(arg);
|
||||||
if (Mem::isDoubleHash(handle->threadId())) {
|
if (Mem::isDoubleHash()) {
|
||||||
handle->setWorker(new DoubleWorker(handle));
|
handle->setWorker(new DoubleWorker(handle));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
static void setJob(const Job &job);
|
static void setJob(const Job &job);
|
||||||
static void start(int64_t affinity, int priority);
|
static void start(int64_t affinity, int priority);
|
||||||
static void stop();
|
static void stop();
|
||||||
static void submit(const JobResult &result, int threadId);
|
static void submit(const JobResult &result);
|
||||||
|
|
||||||
static inline bool isEnabled() { return m_enabled; }
|
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 isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue