Features of 1.6.5 (#140)
* Hashrate improve -> add autodetection mode for cpu-affinity * Hashrate improve, more stable hashrates -> refactor memory allocation * Add TubeV4 support (cn-heavy + ipbc mod + soft-aes mod) * Update ccp-httpd lib to fix stop/freeze of cc communication on some miners * Fix cn-heavy on arm processors
This commit is contained in:
parent
7897f8f645
commit
90699d58ec
38 changed files with 5525 additions and 3114 deletions
3164
src/3rdparty/cpp-httplib/httplib.h
vendored
3164
src/3rdparty/cpp-httplib/httplib.h
vendored
File diff suppressed because it is too large
Load diff
25
src/App.cpp
25
src/App.cpp
|
@ -113,7 +113,6 @@ App::~App()
|
|||
delete m_network;
|
||||
|
||||
Options::release();
|
||||
Mem::release();
|
||||
Platform::release();
|
||||
|
||||
uv_tty_reset_mode();
|
||||
|
@ -142,12 +141,26 @@ int App::start()
|
|||
|
||||
background();
|
||||
|
||||
if (!CryptoNight::init(m_options->algo(), m_options->aesni())) {
|
||||
LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName());
|
||||
return EINVAL;
|
||||
if (Options::i()->colors()) {
|
||||
LOG_INFO(WHITE_BOLD("%s hash self-test"), m_options->algoName());
|
||||
}
|
||||
else {
|
||||
LOG_INFO("%s hash self-test", m_options->algoName());
|
||||
}
|
||||
|
||||
Mem::allocate(m_options);
|
||||
if (!CryptoNight::init(m_options->algo(), m_options->aesni())) {
|
||||
LOG_ERR("%s hash self-test... failed.", m_options->algoName());
|
||||
return EINVAL;
|
||||
} else {
|
||||
if (Options::i()->colors()) {
|
||||
LOG_INFO(WHITE_BOLD("%s hash self-test... ") GREEN_BOLD("successful") ".", m_options->algoName());
|
||||
}
|
||||
else {
|
||||
LOG_INFO("%s hash self-test... successful.", m_options->algoName());
|
||||
}
|
||||
}
|
||||
|
||||
Mem::init(m_options);
|
||||
|
||||
Summary::print();
|
||||
|
||||
|
@ -174,7 +187,7 @@ int App::start()
|
|||
}
|
||||
# endif
|
||||
|
||||
Workers::start(m_options->affinity(), m_options->priority());
|
||||
Workers::start(m_options->threads(), m_options->affinity(), m_options->priority());
|
||||
|
||||
if (m_options->pools().front()->isValid()) {
|
||||
m_network->connect();
|
||||
|
|
|
@ -31,10 +31,6 @@
|
|||
|
||||
void App::background()
|
||||
{
|
||||
if (m_options->affinity() != -1L) {
|
||||
Cpu::setAffinity(-1, m_options->affinity());
|
||||
}
|
||||
|
||||
if (m_options->background()) {
|
||||
Log::i()->text(Options::i()->colors()
|
||||
? "\x1B[01;31m\nBackground mode is not supported by %s on *nix Systems. Please use screen/tmux or systemd service instead.\n"
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
|
||||
void App::background()
|
||||
{
|
||||
if (m_options->affinity() != -1L) {
|
||||
Cpu::setAffinity(-1, m_options->affinity());
|
||||
}
|
||||
|
||||
if (!m_options->background()) {
|
||||
return;
|
||||
}
|
||||
|
|
25
src/Cpu.cpp
25
src/Cpu.cpp
|
@ -145,9 +145,9 @@ void Cpu::optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::
|
|||
CpuImpl::instance().optimizeParameters(threadsCount, hashFactor, algo, maxCpuUsage, safeMode);
|
||||
}
|
||||
|
||||
void Cpu::setAffinity(int id, uint64_t mask)
|
||||
int Cpu::setThreadAffinity(size_t threadId, int64_t affinityMask)
|
||||
{
|
||||
CpuImpl::instance().setAffinity(id, mask);
|
||||
return CpuImpl::instance().setThreadAffinity(threadId, affinityMask);
|
||||
}
|
||||
|
||||
bool Cpu::hasAES()
|
||||
|
@ -194,3 +194,24 @@ size_t Cpu::availableCache()
|
|||
{
|
||||
return CpuImpl::instance().availableCache();
|
||||
}
|
||||
|
||||
int Cpu::getAssignedCpuId(size_t threadId, int64_t affinityMask)
|
||||
{
|
||||
int cpuId = -1;
|
||||
|
||||
Mem::ThreadBitSet threadAffinityMask = Mem::ThreadBitSet(affinityMask);
|
||||
size_t threadCount = 0;
|
||||
|
||||
for (size_t i = 0; i < CpuImpl::instance().threads(); i++) {
|
||||
if (threadAffinityMask.test(i)) {
|
||||
if (threadCount == threadId) {
|
||||
cpuId = i;
|
||||
break;
|
||||
}
|
||||
|
||||
threadCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return cpuId;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
static void optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo,
|
||||
size_t maxCpuUsage, bool safeMode);
|
||||
|
||||
static void setAffinity(int id, uint64_t mask);
|
||||
static int setThreadAffinity(size_t threadId, int64_t affinityMask);
|
||||
|
||||
static bool hasAES();
|
||||
static bool isX64();
|
||||
|
@ -53,6 +53,7 @@ public:
|
|||
static size_t sockets();
|
||||
static size_t threads();
|
||||
static size_t availableCache();
|
||||
static int getAssignedCpuId(size_t threadId, int64_t affinityMask);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "Options.h"
|
||||
#include "Mem.h"
|
||||
|
||||
class CpuImpl
|
||||
{
|
||||
|
@ -39,7 +40,7 @@ public:
|
|||
|
||||
void optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo,
|
||||
size_t maxCpuUsage, bool safeMode);
|
||||
void setAffinity(int id, uint64_t mask);
|
||||
int setThreadAffinity(size_t threadId, int64_t affinityMask);
|
||||
|
||||
bool hasAES();
|
||||
bool isX64();
|
||||
|
|
|
@ -22,13 +22,15 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include "Cpu.h"
|
||||
#include "CpuImpl.h"
|
||||
#include "Cpu.h"
|
||||
|
||||
void CpuImpl::init()
|
||||
{
|
||||
|
@ -39,7 +41,23 @@ void CpuImpl::init()
|
|||
initCommon();
|
||||
}
|
||||
|
||||
|
||||
void CpuImpl::setAffinity(int id, uint64_t mask)
|
||||
int CpuImpl::setThreadAffinity(size_t threadId, int64_t affinityMask)
|
||||
{
|
||||
int cpuId = -1;
|
||||
|
||||
if (affinityMask != -1L) {
|
||||
cpuId = Cpu::getAssignedCpuId(threadId, affinityMask);
|
||||
} else {
|
||||
cpuId = static_cast<int>(threadId);
|
||||
}
|
||||
|
||||
if (cpuId > -1) {
|
||||
thread_port_t mach_thread;
|
||||
thread_affinity_policy_data_t policy = {static_cast<integer_t>(cpuId)};
|
||||
mach_thread = pthread_mach_thread_np(pthread_self());
|
||||
|
||||
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t) & policy, 1);
|
||||
}
|
||||
|
||||
return cpuId;
|
||||
}
|
||||
|
|
|
@ -35,9 +35,8 @@
|
|||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "CpuImpl.h"
|
||||
|
||||
#include "Cpu.h"
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
typedef cpuset_t cpu_set_t;
|
||||
|
@ -54,26 +53,31 @@ void CpuImpl::init()
|
|||
}
|
||||
|
||||
|
||||
void CpuImpl::setAffinity(int id, uint64_t mask)
|
||||
int CpuImpl::setThreadAffinity(size_t threadId, int64_t affinityMask)
|
||||
{
|
||||
cpu_set_t set;
|
||||
CPU_ZERO(&set);
|
||||
int cpuId = -1;
|
||||
|
||||
for (size_t i = 0; i < threads(); i++) {
|
||||
if (mask & (1UL << i)) {
|
||||
CPU_SET(i, &set);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == -1) {
|
||||
# ifndef __FreeBSD__
|
||||
sched_setaffinity(0, sizeof(&set), &set);
|
||||
# endif
|
||||
if (affinityMask != -1L) {
|
||||
cpuId = Cpu::getAssignedCpuId(threadId, affinityMask);
|
||||
} else {
|
||||
# ifndef __ANDROID__
|
||||
pthread_setaffinity_np(pthread_self(), sizeof(&set), &set);
|
||||
# else
|
||||
sched_setaffinity(gettid(), sizeof(&set), &set);
|
||||
# endif
|
||||
cpuId = static_cast<int>(threadId);
|
||||
}
|
||||
|
||||
if (cpuId > -1) {
|
||||
cpu_set_t mn;
|
||||
CPU_ZERO(&mn);
|
||||
CPU_SET(cpuId, &mn);
|
||||
|
||||
# ifndef __ANDROID__
|
||||
if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mn) != 0) {
|
||||
cpuId = -1;
|
||||
}
|
||||
# else
|
||||
if (sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == -1) {
|
||||
cpuId = -1;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
return cpuId;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "CpuImpl.h"
|
||||
#include "Mem.h"
|
||||
#include "Cpu.h"
|
||||
|
||||
void CpuImpl::init()
|
||||
{
|
||||
|
@ -42,24 +43,29 @@ void CpuImpl::init()
|
|||
}
|
||||
|
||||
|
||||
void CpuImpl::setAffinity(int id, uint64_t mask)
|
||||
int CpuImpl::setThreadAffinity(size_t threadId, int64_t affinityMask)
|
||||
{
|
||||
if (id == -1) {
|
||||
SetProcessAffinityMask(GetCurrentProcess(), mask);
|
||||
int cpuId = -1;
|
||||
|
||||
if (affinityMask != -1L) {
|
||||
cpuId = Cpu::getAssignedCpuId(threadId, affinityMask);
|
||||
} else {
|
||||
Mem::ThreadBitSet threadAffinityMask = Mem::ThreadBitSet(mask);
|
||||
|
||||
int threadCount = 0;
|
||||
|
||||
for (size_t i = 0; i < m_totalThreads; i++) {
|
||||
if (threadAffinityMask.test(i)) {
|
||||
if (threadCount == id) {
|
||||
SetThreadAffinityMask(GetCurrentThread(), 1ULL << i);
|
||||
break;
|
||||
}
|
||||
|
||||
threadCount++;
|
||||
}
|
||||
if (threadId+1 > Cpu::threads()/2) {
|
||||
cpuId = (threadId - Cpu::threads()/2) + (threadId+1 - Cpu::threads()/2);
|
||||
} else {
|
||||
cpuId = threadId * 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (cpuId >= 64) {
|
||||
cpuId = -1;
|
||||
}
|
||||
|
||||
if (cpuId > -1) {
|
||||
if (SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpuId) == 0) {
|
||||
cpuId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return cpuId;
|
||||
}
|
||||
|
|
49
src/Mem.cpp
49
src/Mem.cpp
|
@ -24,25 +24,20 @@
|
|||
|
||||
#include <memory.h>
|
||||
|
||||
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "Mem.h"
|
||||
|
||||
|
||||
int Mem::m_algo = 0;
|
||||
int Mem::m_flags = 0;
|
||||
bool Mem::m_useHugePages = true;
|
||||
size_t Mem::m_hashFactor = 1;
|
||||
size_t Mem::m_threads = 0;
|
||||
size_t Mem::m_memorySize = 0;
|
||||
alignas(16) uint8_t *Mem::m_memory = nullptr;
|
||||
int Mem::m_flags = 0;
|
||||
Options::Algo Mem::m_algo = Options::ALGO_CRYPTONIGHT;
|
||||
Mem::ThreadBitSet Mem::m_multiHashThreadMask = Mem::ThreadBitSet(-1L);
|
||||
|
||||
cryptonight_ctx *Mem::create(int threadId)
|
||||
ScratchPadMem Mem::create(ScratchPad** scratchPads, int threadId)
|
||||
{
|
||||
size_t scratchPadSize;
|
||||
|
||||
switch (m_algo)
|
||||
{
|
||||
switch (m_algo) {
|
||||
case Options::ALGO_CRYPTONIGHT_LITE:
|
||||
scratchPadSize = MEMORY_LITE;
|
||||
break;
|
||||
|
@ -55,17 +50,29 @@ cryptonight_ctx *Mem::create(int threadId)
|
|||
break;
|
||||
}
|
||||
|
||||
size_t offset = 0;
|
||||
for (int i=0; i < threadId; i++) {
|
||||
offset += sizeof(cryptonight_ctx);
|
||||
offset += scratchPadSize * getThreadHashFactor(i);
|
||||
ScratchPadMem scratchPadMem;
|
||||
scratchPadMem.realSize = scratchPadSize * getThreadHashFactor(threadId);
|
||||
scratchPadMem.size = scratchPadSize * getThreadHashFactor(threadId);
|
||||
scratchPadMem.size += scratchPadMem.size % MEMORY;
|
||||
scratchPadMem.pages = scratchPadMem.size / MEMORY;
|
||||
|
||||
allocate(scratchPadMem, m_useHugePages);
|
||||
|
||||
for (size_t i = 0; i < getThreadHashFactor(threadId); ++i) {
|
||||
ScratchPad* scratchPad = static_cast<ScratchPad *>(_mm_malloc(sizeof(ScratchPad), 4096));
|
||||
scratchPad->memory = scratchPadMem.memory + (i * scratchPadSize);
|
||||
|
||||
scratchPads[i] = scratchPad;
|
||||
}
|
||||
|
||||
auto* ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset]);
|
||||
|
||||
size_t memOffset = offset+sizeof(cryptonight_ctx);
|
||||
|
||||
ctx->memory = &m_memory[memOffset];
|
||||
|
||||
return ctx;
|
||||
return scratchPadMem;
|
||||
}
|
||||
|
||||
void Mem::release(ScratchPad** scratchPads, ScratchPadMem& scratchPadMem, int threadId)
|
||||
{
|
||||
release(scratchPadMem);
|
||||
|
||||
for (size_t i = 0; i < getThreadHashFactor(threadId); ++i) {
|
||||
_mm_free(scratchPads[i]);
|
||||
}
|
||||
}
|
47
src/Mem.h
47
src/Mem.h
|
@ -33,22 +33,47 @@
|
|||
|
||||
#include "Options.h"
|
||||
|
||||
struct cryptonight_ctx;
|
||||
#ifdef _WIN32
|
||||
# ifdef __GNUC__
|
||||
# include <mm_malloc.h>
|
||||
# else
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#else
|
||||
# if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
# else
|
||||
# include <mm_malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
struct ScratchPad;
|
||||
|
||||
struct ScratchPadMem
|
||||
{
|
||||
alignas(16) uint8_t *memory;
|
||||
|
||||
size_t hugePages;
|
||||
size_t pages;
|
||||
size_t size;
|
||||
size_t realSize;
|
||||
};
|
||||
|
||||
|
||||
class Mem
|
||||
{
|
||||
public:
|
||||
typedef std::bitset<128> ThreadBitSet;
|
||||
|
||||
enum Flags {
|
||||
HugepagesAvailable = 1,
|
||||
HugepagesEnabled = 2,
|
||||
Lock = 4
|
||||
};
|
||||
|
||||
static bool allocate(const Options* options);
|
||||
static cryptonight_ctx *create(int threadId);
|
||||
static void release();
|
||||
static void init(const Options* option);
|
||||
static ScratchPadMem create(ScratchPad** scratchPads, int threadId);
|
||||
static void release(ScratchPad** scratchPads, ScratchPadMem& scratchPadMem, int threadId);
|
||||
|
||||
static inline size_t hashFactor() { return m_hashFactor; }
|
||||
static inline size_t getThreadHashFactor(int threadId)
|
||||
|
@ -56,19 +81,19 @@ public:
|
|||
return (m_multiHashThreadMask.all() ||
|
||||
m_multiHashThreadMask.test(threadId)) ? m_hashFactor : 1;
|
||||
}
|
||||
|
||||
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 size_t threads() { return m_threads; }
|
||||
|
||||
private:
|
||||
static void allocate(ScratchPadMem& scratchPadMem, bool useHugePages);
|
||||
static void release(ScratchPadMem& scratchPadMem);
|
||||
|
||||
private:
|
||||
static bool m_useHugePages;
|
||||
static size_t m_hashFactor;
|
||||
static size_t m_threads;
|
||||
static int m_algo;
|
||||
static int m_flags;
|
||||
static Options::Algo m_algo;
|
||||
static ThreadBitSet m_multiHashThreadMask;
|
||||
static size_t m_memorySize;
|
||||
alignas(16) static uint8_t *m_memory;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -25,92 +25,61 @@
|
|||
#include <cstdlib>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
||||
#if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
#else
|
||||
# include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
|
||||
|
||||
bool Mem::allocate(const Options* options)
|
||||
void Mem::init(const Options* options)
|
||||
{
|
||||
m_algo = options->algo();
|
||||
m_threads = options->threads();
|
||||
m_hashFactor = options->hashFactor();
|
||||
m_multiHashThreadMask = Mem::ThreadBitSet(options->multiHashThreadMask());
|
||||
m_memorySize = 0;
|
||||
m_useHugePages = options->hugePages();
|
||||
m_algo = options->algo();
|
||||
m_multiHashThreadMask = Mem::ThreadBitSet(static_cast<unsigned long long int>(options->multiHashThreadMask()));
|
||||
}
|
||||
|
||||
size_t scratchPadSize;
|
||||
switch (m_algo)
|
||||
{
|
||||
case Options::ALGO_CRYPTONIGHT_LITE:
|
||||
scratchPadSize = MEMORY_LITE;
|
||||
break;
|
||||
case Options::ALGO_CRYPTONIGHT_HEAVY:
|
||||
scratchPadSize = MEMORY_HEAVY;
|
||||
break;
|
||||
case Options::ALGO_CRYPTONIGHT:
|
||||
default:
|
||||
scratchPadSize = MEMORY;
|
||||
break;
|
||||
void Mem::allocate(ScratchPadMem& scratchPadMem, bool useHugePages)
|
||||
{
|
||||
scratchPadMem.hugePages = 0;
|
||||
|
||||
if (!useHugePages) {
|
||||
scratchPadMem.memory = static_cast<uint8_t*>(_mm_malloc(scratchPadMem.size, 4096));
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i=0; i < m_threads; i++) {
|
||||
m_memorySize += sizeof(cryptonight_ctx);
|
||||
m_memorySize += scratchPadSize * getThreadHashFactor(i);
|
||||
}
|
||||
|
||||
m_memorySize = m_memorySize - (m_memorySize % MEMORY) + MEMORY;
|
||||
|
||||
if (!options->hugePages()) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
m_flags |= HugepagesAvailable;
|
||||
|
||||
# if defined(__APPLE__)
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
|
||||
scratchPadMem.memory = static_cast<uint8_t*>(mmap(0, scratchPadMem.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
|
||||
# elif defined(__FreeBSD__)
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||
scratchPadMem.memory = static_cast<uint8_t*>(mmap(0, scratchPadMem.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||
# else
|
||||
m_memory = static_cast<uint8_t*>(mmap(nullptr, m_memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||
scratchPadMem.memory = static_cast<uint8_t*>(mmap(0, scratchPadMem.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<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
return true;
|
||||
|
||||
if (scratchPadMem.memory == MAP_FAILED) {
|
||||
return allocate(scratchPadMem, false);
|
||||
}
|
||||
|
||||
m_flags |= HugepagesEnabled;
|
||||
scratchPadMem.hugePages = scratchPadMem.pages;
|
||||
|
||||
if (madvise(m_memory, m_memorySize, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
if (madvise(scratchPadMem.memory, scratchPadMem.size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
LOG_ERR("madvise failed");
|
||||
}
|
||||
|
||||
if (mlock(m_memory, m_memorySize) == 0) {
|
||||
if (mlock(scratchPadMem.memory, scratchPadMem.size) == 0) {
|
||||
m_flags |= Lock;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Mem::release()
|
||||
void Mem::release(ScratchPadMem &scratchPadMem)
|
||||
{
|
||||
if (m_flags & HugepagesEnabled) {
|
||||
if (scratchPadMem.hugePages) {
|
||||
if (m_flags & Lock) {
|
||||
munlock(m_memory, m_memorySize);
|
||||
munlock(scratchPadMem.memory, scratchPadMem.size);
|
||||
}
|
||||
|
||||
munmap(m_memory, m_memorySize);
|
||||
munmap(scratchPadMem.memory, scratchPadMem.size);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_memory);
|
||||
_mm_free(scratchPadMem.memory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,6 @@
|
|||
#include <ntsecapi.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# include <mm_malloc.h>
|
||||
#else
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "Mem.h"
|
||||
|
@ -144,63 +138,44 @@ static BOOL TrySetLockPagesPrivilege() {
|
|||
}
|
||||
|
||||
|
||||
bool Mem::allocate(const Options* options)
|
||||
void Mem::init(const Options* options)
|
||||
{
|
||||
m_algo = options->algo();
|
||||
m_threads = options->threads();
|
||||
m_hashFactor = options->hashFactor();
|
||||
m_multiHashThreadMask = Mem::ThreadBitSet(options->multiHashThreadMask());
|
||||
m_memorySize = 0;
|
||||
m_useHugePages = options->hugePages();
|
||||
m_algo = options->algo();
|
||||
m_multiHashThreadMask = Mem::ThreadBitSet(static_cast<unsigned long long int>(options->multiHashThreadMask()));
|
||||
|
||||
size_t scratchPadSize;
|
||||
switch (m_algo)
|
||||
{
|
||||
case Options::ALGO_CRYPTONIGHT_LITE:
|
||||
scratchPadSize = MEMORY_LITE;
|
||||
break;
|
||||
case Options::ALGO_CRYPTONIGHT_HEAVY:
|
||||
scratchPadSize = MEMORY_HEAVY;
|
||||
break;
|
||||
case Options::ALGO_CRYPTONIGHT:
|
||||
default:
|
||||
scratchPadSize = MEMORY;
|
||||
break;
|
||||
if (m_useHugePages && TrySetLockPagesPrivilege()) {
|
||||
m_flags |= HugepagesAvailable;
|
||||
}
|
||||
|
||||
for (size_t i=0; i < m_threads; i++) {
|
||||
m_memorySize += sizeof(cryptonight_ctx);
|
||||
m_memorySize += scratchPadSize * getThreadHashFactor(i);
|
||||
}
|
||||
|
||||
m_memorySize = m_memorySize - (m_memorySize % MEMORY) + MEMORY;
|
||||
|
||||
if (!options->hugePages()) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TrySetLockPagesPrivilege()) {
|
||||
m_flags |= HugepagesAvailable;
|
||||
}
|
||||
|
||||
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, m_memorySize, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||
if (!m_memory) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
}
|
||||
else {
|
||||
m_flags |= HugepagesEnabled;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Mem::release()
|
||||
void Mem::allocate(ScratchPadMem& scratchPadMem, bool useHugePages)
|
||||
{
|
||||
if (m_flags & HugepagesEnabled) {
|
||||
VirtualFree(m_memory, 0, MEM_RELEASE);
|
||||
scratchPadMem.hugePages = 0;
|
||||
|
||||
if (!useHugePages) {
|
||||
scratchPadMem.memory = static_cast<uint8_t*>(_mm_malloc(scratchPadMem.size, 4096));
|
||||
return;
|
||||
}
|
||||
|
||||
scratchPadMem.memory = static_cast<uint8_t*>(VirtualAlloc(nullptr, scratchPadMem.size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||
if (scratchPadMem.memory) {
|
||||
scratchPadMem.hugePages = scratchPadMem.pages;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
allocate(scratchPadMem, false);
|
||||
}
|
||||
|
||||
|
||||
void Mem::release(ScratchPadMem &scratchPadMem)
|
||||
{
|
||||
if (scratchPadMem.hugePages) {
|
||||
VirtualFree(scratchPadMem.memory, 0, MEM_RELEASE);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_memory);
|
||||
_mm_free(scratchPadMem.memory);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -279,7 +279,7 @@ constexpr static const char *pow_variant_names[] = {
|
|||
"auto",
|
||||
"0",
|
||||
"1",
|
||||
"ipbc",
|
||||
"tube",
|
||||
"alloy",
|
||||
"xtl",
|
||||
"msr",
|
||||
|
@ -984,7 +984,7 @@ bool Options::setAlgo(const char *algo)
|
|||
if (i == ARRAY_SIZE(algo_names) - 1 && (!strcmp(algo, "cryptonight-lite-ipbc") || !strcmp(algo, "cryptonight-light-ipbc") || !strcmp(algo, "cn-lite-ipbc"))) {
|
||||
showDeprecateWarning("cryptonight-light-ipbc", "cryptonight-light (with variant \"ipbc\")");
|
||||
m_algo = ALGO_CRYPTONIGHT_LITE;
|
||||
m_powVariant = POW_IPBC;
|
||||
m_powVariant = POW_TUBE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1025,8 +1025,8 @@ bool Options::parsePowVariant(const char *powVariant)
|
|||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(pow_variant_names) - 1 && !strcmp(powVariant, "tube")) {
|
||||
m_powVariant = POW_IPBC;
|
||||
if (i == ARRAY_SIZE(pow_variant_names) - 1 && (!strcmp(powVariant, "ipbc") || !strcmp(powVariant, "bittube"))) {
|
||||
m_powVariant = POW_TUBE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ enum PowVariant
|
|||
POW_AUTODETECT,
|
||||
POW_V0,
|
||||
POW_V1,
|
||||
POW_IPBC,
|
||||
POW_TUBE,
|
||||
POW_ALLOY,
|
||||
POW_XTL,
|
||||
POW_MSR,
|
||||
|
@ -44,8 +44,8 @@ inline std::string getPowVariantName(PowVariant powVariant)
|
|||
return "0";
|
||||
case POW_V1:
|
||||
return "1";
|
||||
case POW_IPBC:
|
||||
return "ipbc";
|
||||
case POW_TUBE:
|
||||
return "tube";
|
||||
case POW_ALLOY:
|
||||
return "alloy";
|
||||
case POW_XTL:
|
||||
|
@ -104,8 +104,8 @@ inline PowVariant parseVariant(const std::string variant)
|
|||
powVariant = PowVariant::POW_V0;
|
||||
} else if (variant == "1") {
|
||||
powVariant = PowVariant::POW_V1;
|
||||
} else if (variant == "ipbc" || variant == "tube") {
|
||||
powVariant = PowVariant::POW_IPBC;
|
||||
} else if (variant == "ipbc" || variant == "tube" || variant == "bittube") {
|
||||
powVariant = PowVariant::POW_TUBE;
|
||||
} else if (variant == "xao" || variant == "alloy") {
|
||||
powVariant = PowVariant::POW_ALLOY;
|
||||
} else if (variant == "xtl" || variant == "stellite") {
|
||||
|
|
|
@ -56,18 +56,6 @@ static void print_versions()
|
|||
}
|
||||
|
||||
|
||||
static void print_memory() {
|
||||
if (Options::i()->colors()) {
|
||||
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");
|
||||
}
|
||||
else {
|
||||
Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void print_cpu()
|
||||
{
|
||||
if (Options::i()->colors()) {
|
||||
|
@ -125,14 +113,15 @@ static void print_threads()
|
|||
snprintf(affBuf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
|
||||
}
|
||||
else {
|
||||
affBuf[0] = '\0';
|
||||
snprintf(affBuf, 32, ", affinity=auto");
|
||||
}
|
||||
|
||||
Log::i()->text(Options::i()->colors() ?
|
||||
"\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, aes=%d, hf=%zu, %sdonate=%d%%\x1B[01;37m%s%s" :
|
||||
" * THREADS: %d, %s, aes=%d, hf=%zu, %sdonate=%d%%\x1B[01;37m%s%s",
|
||||
"\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %saes=%d\x1B[01;37m, hf=%zu, %sdonate=%d%%\x1B[01;37m%s%s" :
|
||||
" * THREADS: %d, %s, %saes=%d, hf=%zu, %sdonate=%d%%%s%s",
|
||||
Options::i()->threads(),
|
||||
Options::i()->algoName(),
|
||||
Options::i()->colors() && Options::i()->aesni() == 0 ? "\x1B[01;31m" : "",
|
||||
Options::i()->aesni(),
|
||||
Options::i()->hashFactor(),
|
||||
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||
|
@ -201,7 +190,6 @@ static void print_commands()
|
|||
void Summary::print()
|
||||
{
|
||||
print_versions();
|
||||
print_memory();
|
||||
print_cpu();
|
||||
print_threads();
|
||||
print_pools();
|
||||
|
|
|
@ -231,7 +231,7 @@ void ApiState::getMiner(rapidjson::Document &doc) const
|
|||
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
|
||||
doc.AddMember("cpu", cpu, allocator);
|
||||
doc.AddMember("algo", rapidjson::StringRef(Options::i()->algoName()), allocator);
|
||||
doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator);
|
||||
doc.AddMember("hugepages", Mem::isHugepagesAvailable(), allocator);
|
||||
doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,6 @@ CCClient::CCClient(Options* options, uv_async_t* async)
|
|||
m_clientStatus.setCurrentAlgoName(m_options->algoName());
|
||||
}
|
||||
|
||||
m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled());
|
||||
m_clientStatus.setHugepages(Mem::isHugepagesAvailable());
|
||||
m_clientStatus.setHashFactor(Mem::hashFactor());
|
||||
|
||||
|
@ -265,10 +264,10 @@ std::shared_ptr<httplib::Response> CCClient::performRequest(const std::string& r
|
|||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
if (m_self->m_options->ccUseTls()) {
|
||||
cli = std::make_shared<httplib::SSLClient>(m_self->m_options->ccHost(), m_self->m_options->ccPort());
|
||||
cli = std::make_shared<httplib::SSLClient>(m_self->m_options->ccHost(), m_self->m_options->ccPort(), 10);
|
||||
} else {
|
||||
# endif
|
||||
cli = std::make_shared<httplib::Client>(m_self->m_options->ccHost(), m_self->m_options->ccPort());
|
||||
cli = std::make_shared<httplib::Client>(m_self->m_options->ccHost(), m_self->m_options->ccPort(), 10);
|
||||
# ifndef XMRIG_NO_TLS
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -34,88 +34,94 @@
|
|||
#include "crypto/CryptoNight_test.h"
|
||||
|
||||
template <size_t NUM_HASH_BLOCKS>
|
||||
static void cryptonight_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||
static void cryptonight_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
if (powVersion == PowVariant::POW_V1) {
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_ALLOY) {
|
||||
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_XTL) {
|
||||
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_MSR) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_RTO) {
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
|
||||
}else {
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
template <size_t NUM_HASH_BLOCKS>
|
||||
static void cryptonight_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||
static void cryptonight_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
|
||||
if (powVersion == PowVariant::POW_V1) {
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_ALLOY) {
|
||||
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x100000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_XTL) {
|
||||
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_XLT_V4_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_MSR) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_RTO) {
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
|
||||
} else {
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x80000, POW_DEFAULT_INDEX_SHIFT, MEMORY, 0x1FFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t NUM_HASH_BLOCKS>
|
||||
static void cryptonight_lite_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||
static void cryptonight_lite_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
if (powVersion == PowVariant::POW_V1) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
} else if (powVersion == PowVariant::POW_IPBC) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_TUBE) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
|
||||
} else {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
template <size_t NUM_HASH_BLOCKS>
|
||||
static void cryptonight_lite_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||
static void cryptonight_lite_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
|
||||
if (powVersion == PowVariant::POW_V1) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, ctx);
|
||||
} else if (powVersion == PowVariant::POW_IPBC) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashPowV2(input, size, output, scratchPad);
|
||||
} else if (powVersion == PowVariant::POW_TUBE) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashLiteTube(input, size, output, scratchPad);
|
||||
} else {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hash(input, size, output, scratchPad);
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t NUM_HASH_BLOCKS>
|
||||
static void cryptonight_heavy_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||
static void cryptonight_heavy_aesni(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
if (powVersion == PowVariant::POW_XHV) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, scratchPad);
|
||||
}
|
||||
else if (powVersion == PowVariant::POW_TUBE) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavyTube(input, size, output, scratchPad);
|
||||
}
|
||||
else {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, false, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, scratchPad);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
template <size_t NUM_HASH_BLOCKS>
|
||||
static void cryptonight_heavy_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
|
||||
static void cryptonight_heavy_softaes(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad) {
|
||||
if (powVersion == PowVariant::POW_XHV) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavyHaven(input, size, output, scratchPad);
|
||||
}
|
||||
else if (powVersion == PowVariant::POW_TUBE) {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavyTube(input, size, output, scratchPad);
|
||||
}
|
||||
else {
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, ctx);
|
||||
CryptoNightMultiHash<0x40000, POW_DEFAULT_INDEX_SHIFT, MEMORY_HEAVY, 0x3FFFF0, true, NUM_HASH_BLOCKS>::hashHeavy(input, size, output, scratchPad);
|
||||
}
|
||||
}
|
||||
|
||||
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx);
|
||||
void (*cryptonight_hash_ctx[MAX_NUM_HASH_BLOCKS])(PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad);
|
||||
|
||||
template <size_t HASH_FACTOR>
|
||||
void setCryptoNightHashMethods(Options::Algo algo, bool aesni)
|
||||
|
@ -161,9 +167,9 @@ bool CryptoNight::init(int algo, bool aesni)
|
|||
return selfTest(algo);
|
||||
}
|
||||
|
||||
void CryptoNight::hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
|
||||
void CryptoNight::hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPad)
|
||||
{
|
||||
cryptonight_hash_ctx[factor-1](powVersion, input, size, output, ctx);
|
||||
cryptonight_hash_ctx[factor-1](powVersion, input, size, output, scratchPad);
|
||||
}
|
||||
|
||||
bool CryptoNight::selfTest(int algo)
|
||||
|
@ -187,8 +193,14 @@ bool CryptoNight::selfTest(int algo)
|
|||
|
||||
uint8_t output[160];
|
||||
|
||||
auto ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
|
||||
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 6, 16);
|
||||
ScratchPad* scratchPads [MAX_NUM_HASH_BLOCKS];
|
||||
|
||||
for (size_t i = 0; i < MAX_NUM_HASH_BLOCKS; ++i) {
|
||||
ScratchPad* scratchPad = static_cast<ScratchPad *>(_mm_malloc(sizeof(ScratchPad), 4096));
|
||||
scratchPad->memory = (uint8_t *) _mm_malloc(MEMORY * 6, 16);
|
||||
|
||||
scratchPads[i] = scratchPad;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
bool resultLite = true;
|
||||
|
@ -197,188 +209,206 @@ bool CryptoNight::selfTest(int algo)
|
|||
if (algo == Options::ALGO_CRYPTONIGHT_HEAVY) {
|
||||
// cn-heavy
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 96) == 0;
|
||||
#endif
|
||||
|
||||
// cn-heavy haven
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_XHV, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_XHV, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_haven, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_XHV, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_XHV, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_haven, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_XHV, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_XHV, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_haven, 96) == 0;
|
||||
#endif
|
||||
|
||||
// cn-heavy bittube
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_tube, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_tube, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultHeavy = resultHeavy && memcmp(output, test_output_heavy_tube, 96) == 0;
|
||||
#endif
|
||||
} else if (algo == Options::ALGO_CRYPTONIGHT_LITE) {
|
||||
// cn-lite v0
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v0_lite, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v0_lite, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v0_lite, 96) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 3
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v0_lite, 128) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 4
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v0_lite, 160) == 0;
|
||||
#endif
|
||||
|
||||
// cn-lite v7 tests
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v1_lite, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v1_lite, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v1_lite, 96) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 3
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v1_lite, 128) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 4
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_v1_lite, 160) == 0;
|
||||
#endif
|
||||
|
||||
|
||||
// cn-lite ibpc tests
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_IPBC, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_IPBC, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_IPBC, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 96) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 3
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_IPBC, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 128) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 4
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_IPBC, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_TUBE, test_input, 76, output, scratchPads);
|
||||
resultLite = resultLite && memcmp(output, test_output_ipbc_lite, 160) == 0;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
// cn v0
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V0,test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V0,test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v0, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v0, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v0, 96) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 3
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v0, 128) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 4
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V0, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v0, 160) == 0;
|
||||
#endif
|
||||
|
||||
// cn v7
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v1, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v1, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v1, 96) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 3
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v1, 128) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 4
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_V1, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_v1, 160) == 0;
|
||||
#endif
|
||||
|
||||
// cn xtl
|
||||
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_XTL,test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[0](PowVariant::POW_XTL,test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_xtl, 32) == 0;
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 1
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_XTL, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[1](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_xtl, 64) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 2
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_XTL, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[2](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_xtl, 96) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 3
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_XTL, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[3](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_xtl, 128) == 0;
|
||||
#endif
|
||||
|
||||
#if MAX_NUM_HASH_BLOCKS > 4
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_XTL, test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx[4](PowVariant::POW_XTL, test_input, 76, output, scratchPads);
|
||||
result = result && memcmp(output, test_output_xtl, 160) == 0;
|
||||
#endif
|
||||
}
|
||||
_mm_free(ctx->memory);
|
||||
_mm_free(ctx);
|
||||
|
||||
for (size_t i = 0; i < MAX_NUM_HASH_BLOCKS; ++i) {
|
||||
_mm_free(scratchPads[i]->memory);
|
||||
_mm_free(scratchPads[i]);
|
||||
}
|
||||
|
||||
return result && resultLite & resultHeavy;
|
||||
}
|
|
@ -37,8 +37,8 @@
|
|||
#define POW_DEFAULT_INDEX_SHIFT 3
|
||||
#define POW_XLT_V4_INDEX_SHIFT 4
|
||||
|
||||
struct cryptonight_ctx {
|
||||
alignas(16) uint8_t state[MAX_NUM_HASH_BLOCKS][208]; // 208 instead of 200 to maintain aligned to 16 byte boundaries
|
||||
struct ScratchPad {
|
||||
alignas(16) uint8_t state[208]; // 208 instead of 200 to maintain aligned to 16 byte boundaries
|
||||
alignas(16) uint8_t* memory;
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,7 @@ class CryptoNight
|
|||
public:
|
||||
static bool init(int algo, bool aesni);
|
||||
|
||||
static void hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
|
||||
static void hash(size_t factor, PowVariant powVersion, const uint8_t* input, size_t size, uint8_t* output, ScratchPad** scratchPads);
|
||||
|
||||
private:
|
||||
static bool selfTest(int algo);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -158,7 +158,7 @@ const static uint8_t test_output_heavy[160] = {
|
|||
};
|
||||
|
||||
// CN-Heavy Haven
|
||||
const static uint8_t test_output_heavy_haven[160] = {
|
||||
const static uint8_t test_output_heavy_haven[96] = {
|
||||
0x5A, 0xC3, 0xF7, 0x85, 0xC4, 0x90, 0xC5, 0x85, 0x50, 0xEC, 0x95, 0xD2, 0x72, 0x65, 0x63, 0x57,
|
||||
0x7E, 0x7C, 0x1C, 0x21, 0x2D, 0x0C, 0xDE, 0x59, 0x12, 0x73, 0x20, 0x1E, 0x44, 0xFD, 0xD5, 0xB6,
|
||||
0x1F, 0x4E, 0xB2, 0x0A, 0x36, 0x51, 0x4B, 0xF5, 0x4D, 0xC9, 0xE0, 0x90, 0x2C, 0x16, 0x47, 0x3F,
|
||||
|
@ -167,4 +167,14 @@ const static uint8_t test_output_heavy_haven[160] = {
|
|||
0x8F, 0x28, 0x0B, 0xCE, 0x2C, 0xEE, 0xDD, 0x88, 0x94, 0x35, 0x48, 0x51, 0xAE, 0xC8, 0x9C, 0x0B
|
||||
};
|
||||
|
||||
// CN-Heavy Tube
|
||||
const static uint8_t test_output_heavy_tube[96] = {
|
||||
0xfe, 0x53, 0x35, 0x20, 0x76, 0xea, 0xe6, 0x89, 0xfa, 0x3b, 0x4f, 0xda, 0x61, 0x46, 0x34, 0xcf,
|
||||
0xc3, 0x12, 0xee, 0x0c, 0x38, 0x7d, 0xf2, 0xb8, 0xb7, 0x4d, 0xa2, 0xa1, 0x59, 0x74, 0x12, 0x35,
|
||||
0xcd, 0x3f, 0x29, 0xdf, 0x07, 0x4a, 0x14, 0xad, 0x0b, 0x98, 0x99, 0x37, 0xca, 0x14, 0x68, 0xa3,
|
||||
0x8d, 0xae, 0x86, 0xc1, 0xa3, 0x54, 0x05, 0xbe, 0xea, 0x6d, 0x29, 0x24, 0x0c, 0x82, 0x97, 0x74,
|
||||
0xa0, 0x64, 0x77, 0xcd, 0x8d, 0x8a, 0xc3, 0x10, 0xb4, 0x89, 0x0e, 0xbb, 0x7d, 0xe6, 0x32, 0x8f,
|
||||
0xf4, 0x2d, 0xb6, 0x9e, 0x8a, 0xf9, 0xf8, 0xee, 0x2c, 0xd0, 0x74, 0xed, 0xa9, 0xaa, 0xa1, 0xfb
|
||||
};
|
||||
|
||||
#endif /* __CRYPTONIGHT_TEST_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1189,6 +1189,12 @@ FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b)
|
|||
return vreinterpretq_m128i_u32(vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
|
||||
}
|
||||
|
||||
// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers in b for greater than. https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx
|
||||
FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b)
|
||||
{
|
||||
return vreinterpretq_m128i_u32(vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
|
||||
}
|
||||
|
||||
// Compares the four 32-bit floats in a and b to check if any values are NaN. Ordered compare between each value returns true for "orderable" and false for "not orderable" (NaN). https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx
|
||||
// see also:
|
||||
// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean
|
||||
|
|
|
@ -105,12 +105,29 @@ 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) |
|
||||
(saes_sbox[(key >> 16) & 0xff] << 16 ) |
|
||||
(saes_sbox[(key >> 8) & 0xff] << 8 ) |
|
||||
saes_sbox[key & 0xff];
|
||||
return (saes_sbox[key >> 24 ] << 24) |
|
||||
(saes_sbox[(key >> 16) & 0xff] << 16 ) |
|
||||
(saes_sbox[(key >> 8) & 0xff] << 8 ) |
|
||||
saes_sbox[key & 0xff];
|
||||
}
|
||||
|
||||
#if defined(__clang__) || defined(XMRIG_ARM)
|
||||
|
|
|
@ -73,6 +73,19 @@ private:
|
|||
};
|
||||
|
||||
|
||||
#define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m"
|
||||
#define RED(x) "\x1B[0;31m" x "\x1B[0m"
|
||||
#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m"
|
||||
#define GREEN(x) "\x1B[0;32m" x "\x1B[0m"
|
||||
#define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m"
|
||||
#define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m"
|
||||
#define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m"
|
||||
#define CYAN(x) "\x1B[0;36m" x "\x1B[0m"
|
||||
#define WHITE_BOLD(x) "\x1B[1;37m" x "\x1B[0m"
|
||||
#define WHITE(x) "\x1B[0;37m" x "\x1B[0m"
|
||||
#define YELLOW_BOLD(x) "\x1B[1;33m" x "\x1B[0m"
|
||||
#define YELLOW(x) "\x1B[0;33m" x "\x1B[0m"
|
||||
|
||||
#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
|
||||
#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
|
||||
#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__)
|
||||
|
|
|
@ -36,14 +36,14 @@
|
|||
#define APP_DESC "XMRigCC CPU miner"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
|
||||
#endif
|
||||
#define APP_VERSION "1.6.4 (based on XMRig)"
|
||||
#define APP_VERSION "1.6.5_beta1 (based on XMRig)"
|
||||
#define APP_DOMAIN ""
|
||||
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
|
||||
#define APP_KIND "cpu"
|
||||
|
||||
#define APP_VER_MAJOR 1
|
||||
#define APP_VER_MINOR 6
|
||||
#define APP_VER_BUILD 4
|
||||
#define APP_VER_BUILD 5
|
||||
#define APP_VER_REV 0
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "workers/Handle.h"
|
||||
|
||||
|
||||
Handle::Handle(int threadId, int threads, int64_t affinity, int priority) :
|
||||
Handle::Handle(size_t threadId, size_t threads, int64_t affinity, int priority) :
|
||||
m_priority(priority),
|
||||
m_threadId(threadId),
|
||||
m_threads(threads),
|
||||
|
|
|
@ -35,21 +35,21 @@ class IWorker;
|
|||
class Handle
|
||||
{
|
||||
public:
|
||||
Handle(int threadId, int threads, int64_t affinity, int priority);
|
||||
Handle(size_t threadId, size_t threads, int64_t affinity, int priority);
|
||||
void join();
|
||||
void start(void (*callback) (void *));
|
||||
|
||||
inline int priority() const { return m_priority; }
|
||||
inline int threadId() const { return m_threadId; }
|
||||
inline int threads() const { return m_threads; }
|
||||
inline size_t threadId() const { return m_threadId; }
|
||||
inline size_t threads() const { return m_threads; }
|
||||
inline int64_t affinity() const { return m_affinity; }
|
||||
inline IWorker *worker() const { return m_worker; }
|
||||
inline void setWorker(IWorker *worker) { m_worker = worker; }
|
||||
|
||||
private:
|
||||
int m_priority;
|
||||
int m_threadId;
|
||||
int m_threads;
|
||||
size_t m_threadId;
|
||||
size_t m_threads;
|
||||
int64_t m_affinity;
|
||||
IWorker *m_worker;
|
||||
uv_thread_t m_thread;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
|
||||
#include <thread>
|
||||
#include <log/Log.h>
|
||||
|
||||
|
||||
#include "crypto/CryptoNight.h"
|
||||
|
@ -35,7 +36,7 @@
|
|||
class MultiWorker : public Worker
|
||||
{
|
||||
public:
|
||||
explicit MultiWorker(Handle *handle, size_t hashMultiplier);
|
||||
explicit MultiWorker(Handle *handle, size_t hashFactor);
|
||||
~MultiWorker();
|
||||
|
||||
void start() override;
|
||||
|
@ -50,7 +51,10 @@ private:
|
|||
uint8_t* m_hash;
|
||||
State *m_state;
|
||||
State *m_pausedState;
|
||||
size_t m_hashMultiplier;
|
||||
size_t m_hashFactor;
|
||||
|
||||
ScratchPadMem scratchPadMem;
|
||||
ScratchPad* scratchPads[MAX_NUM_HASH_BLOCKS];
|
||||
};
|
||||
|
||||
class MultiWorker::State
|
||||
|
@ -77,13 +81,14 @@ public:
|
|||
};
|
||||
|
||||
|
||||
MultiWorker::MultiWorker(Handle *handle, size_t hashMultiplier)
|
||||
MultiWorker::MultiWorker(Handle *handle, size_t hashFactor)
|
||||
: Worker(handle),
|
||||
m_hash(new uint8_t[32 * hashMultiplier]),
|
||||
m_state(new MultiWorker::State(hashMultiplier)),
|
||||
m_pausedState(new MultiWorker::State(hashMultiplier)),
|
||||
m_hashMultiplier(hashMultiplier)
|
||||
m_hash(new uint8_t[32 * hashFactor]),
|
||||
m_state(new MultiWorker::State(hashFactor)),
|
||||
m_pausedState(new MultiWorker::State(hashFactor)),
|
||||
m_hashFactor(hashFactor)
|
||||
{
|
||||
scratchPadMem = Mem::create(scratchPads, m_id);
|
||||
}
|
||||
|
||||
MultiWorker::~MultiWorker()
|
||||
|
@ -91,10 +96,25 @@ MultiWorker::~MultiWorker()
|
|||
delete[] m_hash;
|
||||
delete m_state;
|
||||
delete m_pausedState;
|
||||
|
||||
Mem::release(scratchPads, scratchPadMem, m_id);
|
||||
}
|
||||
|
||||
void MultiWorker::start()
|
||||
{
|
||||
const size_t memory = scratchPadMem.realSize / 1048576;
|
||||
|
||||
if (Options::i()->colors()) {
|
||||
LOG_INFO(WHITE_BOLD("Starting thread ") GREEN_BOLD("%zu/%zu") " affined to core: " GREEN_BOLD("#%d") " -> huge pages:" GREEN_BOLD(" %s%zu/%zu") " scratchpad: " CYAN_BOLD("%zu.0 MB"),
|
||||
m_id+1, Options::i()->threads(), m_affinedCpu,
|
||||
(scratchPadMem.hugePages == scratchPadMem.pages ? "\x1B[1;32m" : (scratchPadMem.hugePages == 0 ? "\x1B[1;31m" : "\x1B[1;33m")),
|
||||
scratchPadMem.hugePages, scratchPadMem.pages, memory);
|
||||
}
|
||||
else {
|
||||
LOG_INFO("Starting thread %zu/%zu affined to core: #%d -> huge pages: %zu/%zu scratchpad: %zu.0 MB",
|
||||
m_id+1, Options::i()->threads(), m_affinedCpu, scratchPadMem.hugePages, scratchPadMem.pages, memory);
|
||||
}
|
||||
|
||||
while (Workers::sequence() > 0) {
|
||||
if (Workers::isPaused()) {
|
||||
do {
|
||||
|
@ -114,15 +134,15 @@ void MultiWorker::start()
|
|||
storeStats();
|
||||
}
|
||||
|
||||
m_count += m_hashMultiplier;
|
||||
m_count += m_hashFactor;
|
||||
|
||||
for (size_t i=0; i < m_hashMultiplier; ++i) {
|
||||
for (size_t i=0; i < m_hashFactor; ++i) {
|
||||
*Job::nonce(m_state->blob + i * m_state->job.size()) = ++m_state->nonces[i];
|
||||
}
|
||||
|
||||
CryptoNight::hash(m_hashMultiplier, m_state->job.powVariant(), m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
||||
CryptoNight::hash(m_hashFactor, m_state->job.powVariant(), m_state->blob, m_state->job.size(), m_hash, scratchPads);
|
||||
|
||||
for (size_t i=0; i < m_hashMultiplier; ++i) {
|
||||
for (size_t i=0; i < m_hashFactor; ++i) {
|
||||
if (*reinterpret_cast<uint64_t *>(m_hash + 24 + i * 32) < m_state->job.target()) {
|
||||
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonces[i], m_hash + i * 32,
|
||||
m_state->job.diff()), m_id);
|
||||
|
@ -162,7 +182,7 @@ void MultiWorker::consumeJob()
|
|||
|
||||
m_state->job = std::move(job);
|
||||
|
||||
for (size_t i=0; i < m_hashMultiplier; ++i) {
|
||||
for (size_t i=0; i < m_hashFactor; ++i) {
|
||||
memcpy(m_state->blob + i * m_state->job.size(), m_state->job.blob(), m_state->job.size());
|
||||
if (m_state->job.isNicehash()) {
|
||||
m_state->nonces[i] = (*Job::nonce(m_state->blob + i * m_state->job.size()) & 0xff000000U) +
|
||||
|
@ -183,6 +203,6 @@ void MultiWorker::save(const Job &job)
|
|||
}
|
||||
}
|
||||
|
||||
Worker* createMultiWorker(size_t numHashes, Handle *handle) {
|
||||
return new MultiWorker(handle, numHashes);
|
||||
Worker* createMultiWorker(Handle *handle, size_t hashFactor) {
|
||||
return new MultiWorker(handle, hashFactor);
|
||||
}
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
class Handle;
|
||||
|
||||
Worker* createMultiWorker(size_t numHashes, Handle *handle);
|
||||
Worker* createMultiWorker(Handle *handle, size_t hashFactor);
|
||||
|
||||
|
||||
#endif /* __SINGLEWORKER_H__ */
|
||||
|
|
|
@ -39,12 +39,11 @@ Worker::Worker(Handle *handle) :
|
|||
m_count(0),
|
||||
m_sequence(0)
|
||||
{
|
||||
if (Cpu::threads() > 1 && handle->affinity() != -1L) {
|
||||
Cpu::setAffinity(m_id, handle->affinity());
|
||||
if (m_threads > 1 && m_threads <= Cpu::threads()) {
|
||||
m_affinedCpu = Cpu::setThreadAffinity(m_id, handle->affinity());
|
||||
}
|
||||
|
||||
Platform::setThreadPriority(handle->priority());
|
||||
m_ctx = Mem::create(m_id);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "interfaces/IWorker.h"
|
||||
|
||||
|
||||
struct cryptonight_ctx;
|
||||
struct ScratchPad;
|
||||
class Handle;
|
||||
|
||||
|
||||
|
@ -48,9 +48,9 @@ public:
|
|||
protected:
|
||||
void storeStats();
|
||||
|
||||
cryptonight_ctx *m_ctx;
|
||||
int m_id;
|
||||
int m_threads;
|
||||
int m_affinedCpu;
|
||||
size_t m_threads;
|
||||
std::atomic<uint64_t> m_hashCount;
|
||||
std::atomic<uint64_t> m_timestamp;
|
||||
uint64_t m_count;
|
||||
|
|
|
@ -100,9 +100,8 @@ void Workers::setJob(const Job &job)
|
|||
}
|
||||
|
||||
|
||||
void Workers::start(int64_t affinity, int priority)
|
||||
void Workers::start(size_t threads, int64_t affinityMask, int priority)
|
||||
{
|
||||
const int threads = Mem::threads();
|
||||
m_hashrate = new Hashrate(threads);
|
||||
|
||||
uv_mutex_init(&m_mutex);
|
||||
|
@ -115,8 +114,8 @@ void Workers::start(int64_t affinity, int priority)
|
|||
uv_timer_init(uv_default_loop(), &m_timer);
|
||||
uv_timer_start(&m_timer, Workers::onTick, 500, 500);
|
||||
|
||||
for (int i = 0; i < threads; ++i) {
|
||||
auto handle = new Handle(i, threads, affinity, priority);
|
||||
for (size_t i = 0; i < threads; ++i) {
|
||||
auto handle = new Handle(i, threads, affinityMask, priority);
|
||||
m_workers.push_back(handle);
|
||||
handle->start(Workers::onReady);
|
||||
}
|
||||
|
@ -151,7 +150,7 @@ void Workers::submit(const JobResult &result, int threadId)
|
|||
void Workers::onReady(void *arg)
|
||||
{
|
||||
auto handle = static_cast<Handle*>(arg);
|
||||
handle->setWorker(createMultiWorker(Mem::getThreadHashFactor(handle->threadId()), handle));
|
||||
handle->setWorker(createMultiWorker(handle, Mem::getThreadHashFactor(handle->threadId())));
|
||||
handle->worker()->start();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
static void printHashrate(bool detail);
|
||||
static void setEnabled(bool enabled);
|
||||
static void setJob(const Job &job);
|
||||
static void start(int64_t affinity, int priority);
|
||||
static void start(size_t threads, int64_t affinityMask, int priority);
|
||||
static void stop();
|
||||
static void submit(const JobResult &result, int threadId);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue