Merged branch dev into master
This commit is contained in:
commit
de0183c284
34 changed files with 2516 additions and 264 deletions
|
@ -1,3 +1,7 @@
|
|||
# v1.2.0
|
||||
- Added configurability for thread based doublehash mode which helps you to use more of your l3 cache
|
||||
- Memory optimizations
|
||||
- Updated to latest XMRig (2.4.3) with ARM support
|
||||
# v1.1.1
|
||||
- Fixed table sorting for client id column on Dashboard
|
||||
- Fixed Windows compilation with msys2 (gcc)
|
||||
|
|
|
@ -10,6 +10,7 @@ option(WITH_CC_CLIENT "CC Client" ON)
|
|||
option(WITH_CC_SERVER "CC Server" ON)
|
||||
|
||||
include (CheckIncludeFile)
|
||||
include (cmake/cpu.cmake)
|
||||
|
||||
|
||||
set(HEADERS
|
||||
|
@ -49,7 +50,6 @@ set(HEADERS_CRYPTO
|
|||
src/crypto/c_keccak.h
|
||||
src/crypto/c_skein.h
|
||||
src/crypto/CryptoNight.h
|
||||
src/crypto/CryptoNight_p.h
|
||||
src/crypto/CryptoNight_test.h
|
||||
src/crypto/groestl_tables.h
|
||||
src/crypto/hash.h
|
||||
|
@ -57,6 +57,12 @@ set(HEADERS_CRYPTO
|
|||
src/crypto/soft_aes.h
|
||||
)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_arm.h)
|
||||
else()
|
||||
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_x86.h)
|
||||
endif()
|
||||
|
||||
set(SOURCES
|
||||
src/api/Api.cpp
|
||||
src/api/ApiState.cpp
|
||||
|
@ -146,65 +152,22 @@ if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
|
|||
set(EXTRA_LIBS ${EXTRA_LIBS} kvm)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
EXECUTE_PROCESS(COMMAND uname -o COMMAND tr -d '\n' OUTPUT_VARIABLE OPERATING_SYSTEM)
|
||||
if (OPERATING_SYSTEM MATCHES "Android")
|
||||
set(EXTRA_LIBS ${EXTRA_LIBS} log)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_definitions(/D__STDC_FORMAT_MACROS)
|
||||
add_definitions(/DUNICODE)
|
||||
add_definitions(/DRAPIDJSON_SSE2)
|
||||
#add_definitions(/DAPP_DEBUG)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
find_package(UV REQUIRED)
|
||||
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
|
||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -Wno-strict-aliasing")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
|
||||
add_definitions(/D_GNU_SOURCE)
|
||||
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
|
||||
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")
|
||||
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
|
||||
add_definitions(/DNOMINMAX)
|
||||
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti -Wno-missing-braces")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
endif()
|
||||
include(cmake/flags.cmake)
|
||||
|
||||
if (WITH_LIBCPUID)
|
||||
add_subdirectory(src/3rdparty/libcpuid)
|
||||
|
@ -214,7 +177,12 @@ if (WITH_LIBCPUID)
|
|||
set(SOURCES_CPUID src/Cpu.cpp)
|
||||
else()
|
||||
add_definitions(/DXMRIG_NO_LIBCPUID)
|
||||
set(SOURCES_CPUID src/Cpu_stub.cpp)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
set(SOURCES_CPUID src/Cpu_arm.cpp)
|
||||
else()
|
||||
set(SOURCES_CPUID src/Cpu_stub.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
|
||||
|
|
25
cmake/cpu.cmake
Normal file
25
cmake/cpu.cmake
Normal file
|
@ -0,0 +1,25 @@
|
|||
if (NOT CMAKE_SYSTEM_PROCESSOR)
|
||||
message(WARNING "CMAKE_SYSTEM_PROCESSOR not defined")
|
||||
endif()
|
||||
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
|
||||
add_definitions(/DRAPIDJSON_SSE2)
|
||||
endif()
|
||||
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64)$")
|
||||
set(XMRIG_ARM ON)
|
||||
set(XMRIG_ARMv8 ON)
|
||||
set(WITH_LIBCPUID OFF)
|
||||
|
||||
add_definitions(/DXMRIG_ARM)
|
||||
add_definitions(/DXMRIG_ARMv8)
|
||||
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7|armv7f|armv7s|armv7k|armv7-a|armv7l)$")
|
||||
set(XMRIG_ARM ON)
|
||||
set(XMRIG_ARMv7 ON)
|
||||
set(WITH_LIBCPUID OFF)
|
||||
|
||||
add_definitions(/DXMRIG_ARM)
|
||||
add_definitions(/DXMRIG_ARMv7)
|
||||
endif()
|
69
cmake/flags.cmake
Normal file
69
cmake/flags.cmake
Normal file
|
@ -0,0 +1,69 @@
|
|||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto -flax-vector-conversions")
|
||||
elseif (XMRIG_ARMv7)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -flax-vector-conversions")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
|
||||
add_definitions(/D_GNU_SOURCE)
|
||||
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
|
||||
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")
|
||||
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
|
||||
add_definitions(/DNOMINMAX)
|
||||
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-missing-braces")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto")
|
||||
elseif (XMRIG_ARMv7)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||
endif()
|
||||
|
||||
endif()
|
|
@ -282,8 +282,8 @@ function isOnline(lastStatus) {
|
|||
<th>Algo</th>
|
||||
|
||||
<th>Hashrate</th>
|
||||
<th>Hashrate 5m</th>
|
||||
<th>Hashrate 60m</th>
|
||||
<th>Hashrate 1m</th>
|
||||
<th>Hashrate 15m</th>
|
||||
|
||||
<th>Hashrate Highest</th>
|
||||
<th>Hashes Total</th>
|
||||
|
@ -334,4 +334,4 @@ function isOnline(lastStatus) {
|
|||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
65
src/3rdparty/aligned_malloc.h
vendored
Normal file
65
src/3rdparty/aligned_malloc.h
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ALIGNED_MALLOC_H__
|
||||
#define __ALIGNED_MALLOC_H__
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
|
||||
#else
|
||||
// Some systems (e.g. those with GNU libc) declare posix_memalign with an
|
||||
// exception specifier. Via an "egregious workaround" in
|
||||
// Sema::CheckEquivalentExceptionSpec, Clang accepts the following as a valid
|
||||
// redeclaration of glibc's declaration.
|
||||
extern "C" int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
|
||||
#endif
|
||||
|
||||
|
||||
static __inline__ void *__attribute__((__always_inline__, __malloc__)) _mm_malloc(size_t __size, size_t __align)
|
||||
{
|
||||
if (__align == 1) {
|
||||
return malloc(__size);
|
||||
}
|
||||
|
||||
if (!(__align & (__align - 1)) && __align < sizeof(void *))
|
||||
__align = sizeof(void *);
|
||||
|
||||
void *__mallocedMemory;
|
||||
if (posix_memalign(&__mallocedMemory, __align, __size)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __mallocedMemory;
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void __attribute__((__always_inline__)) _mm_free(void *__p)
|
||||
{
|
||||
free(__p);
|
||||
}
|
||||
|
||||
#endif /* __ALIGNED_MALLOC_H__ */
|
54
src/Cpu_arm.cpp
Normal file
54
src/Cpu_arm.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "Cpu.h"
|
||||
|
||||
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
int Cpu::m_totalThreads = 0;
|
||||
|
||||
|
||||
int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
|
||||
{
|
||||
return m_totalThreads;
|
||||
}
|
||||
|
||||
|
||||
void Cpu::initCommon()
|
||||
{
|
||||
memcpy(m_brand, "Unknown", 7);
|
||||
|
||||
# if defined(XMRIG_ARMv8)
|
||||
m_flags |= X86_64;
|
||||
m_flags |= AES;
|
||||
# endif
|
||||
}
|
|
@ -70,6 +70,10 @@ void Cpu::setAffinity(int id, uint64_t mask)
|
|||
sched_setaffinity(0, sizeof(&set), &set);
|
||||
# endif
|
||||
} else {
|
||||
# ifndef __ANDROID__
|
||||
pthread_setaffinity_np(pthread_self(), sizeof(&set), &set);
|
||||
# else
|
||||
sched_setaffinity(gettid(), sizeof(&set), &set);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
|
63
src/Mem.cpp
63
src/Mem.cpp
|
@ -30,58 +30,29 @@
|
|||
#include "Options.h"
|
||||
|
||||
|
||||
bool Mem::m_doubleHash = false;
|
||||
int Mem::m_algo = 0;
|
||||
int Mem::m_flags = 0;
|
||||
int Mem::m_threads = 0;
|
||||
size_t Mem::m_offset = 0;
|
||||
uint8_t *Mem::m_memory = nullptr;
|
||||
|
||||
bool Mem::m_doubleHash = false;
|
||||
int Mem::m_algo = 0;
|
||||
int Mem::m_flags = 0;
|
||||
int Mem::m_threads = 0;
|
||||
size_t Mem::m_memorySize = 0;
|
||||
uint8_t *Mem::m_memory = nullptr;
|
||||
int64_t Mem::m_doubleHashThreadMask = -1L;
|
||||
|
||||
cryptonight_ctx *Mem::create(int threadId)
|
||||
{
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_algo == Options::ALGO_CRYPTONIGHT_LITE) {
|
||||
return createLite(threadId);
|
||||
size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
|
||||
|
||||
size_t offset = 0;
|
||||
for (int i=0; i < threadId; i++) {
|
||||
offset += sizeof(cryptonight_ctx);
|
||||
offset += isDoubleHash(i) ? scratchPadSize*2 : scratchPadSize;
|
||||
}
|
||||
# endif
|
||||
|
||||
cryptonight_ctx *ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
|
||||
auto* ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset]);
|
||||
|
||||
const int ratio = m_doubleHash ? 2 : 1;
|
||||
ctx->memory = &m_memory[MEMORY * (threadId * ratio + 1)];
|
||||
size_t memOffset = offset+sizeof(cryptonight_ctx);
|
||||
|
||||
ctx->memory = &m_memory[memOffset];
|
||||
|
||||
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,10 +45,9 @@ public:
|
|||
|
||||
static bool allocate(const Options* options);
|
||||
static cryptonight_ctx *create(int threadId);
|
||||
static void *calloc(size_t num, size_t size);
|
||||
static void release();
|
||||
|
||||
static inline bool isDoubleHash() { return m_doubleHash; }
|
||||
static inline bool isDoubleHash(int threadId) { return m_doubleHash && (m_doubleHashThreadMask == -1L || ((m_doubleHashThreadMask >> threadId) & 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; }
|
||||
|
@ -59,12 +58,9 @@ private:
|
|||
static int m_algo;
|
||||
static int m_flags;
|
||||
static int m_threads;
|
||||
static size_t m_offset;
|
||||
static int64_t m_doubleHashThreadMask;
|
||||
static size_t m_memorySize;
|
||||
VAR_ALIGN(16, static uint8_t *m_memory);
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
static cryptonight_ctx *createLite(int threadId);
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,10 +23,16 @@
|
|||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <mm_malloc.h>
|
||||
#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"
|
||||
|
@ -38,12 +44,22 @@ bool Mem::allocate(const Options* options)
|
|||
m_algo = options->algo();
|
||||
m_threads = options->threads();
|
||||
m_doubleHash = options->doubleHash();
|
||||
m_doubleHashThreadMask = options->doubleHashThreadMask();
|
||||
m_memorySize = 0;
|
||||
|
||||
const int ratio = (m_doubleHash && m_algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
|
||||
const size_t size = MEMORY * (m_threads * ratio + 1);
|
||||
size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
|
||||
for (int i=0; i < m_threads; i++) {
|
||||
m_memorySize += sizeof(cryptonight_ctx);
|
||||
|
||||
if (isDoubleHash(i)) {
|
||||
m_memorySize += scratchPadSize*2;
|
||||
} else {
|
||||
m_memorySize += scratchPadSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (!options->hugePages()) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -54,20 +70,20 @@ bool Mem::allocate(const Options* options)
|
|||
# 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));
|
||||
# else
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_memorySize, 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(size, 16));
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
m_flags |= HugepagesEnabled;
|
||||
|
||||
if (madvise(m_memory, size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
if (madvise(m_memory, m_memorySize, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
LOG_ERR("madvise failed");
|
||||
}
|
||||
|
||||
if (mlock(m_memory, size) == 0) {
|
||||
if (mlock(m_memory, m_memorySize) == 0) {
|
||||
m_flags |= Lock;
|
||||
}
|
||||
|
||||
|
@ -77,14 +93,12 @@ bool Mem::allocate(const Options* options)
|
|||
|
||||
void Mem::release()
|
||||
{
|
||||
const int size = MEMORY * (m_threads + 1);
|
||||
|
||||
if (m_flags & HugepagesEnabled) {
|
||||
if (m_flags & Lock) {
|
||||
munlock(m_memory, size);
|
||||
munlock(m_memory, m_memorySize);
|
||||
}
|
||||
|
||||
munmap(m_memory, size);
|
||||
munmap(m_memory, m_memorySize);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_memory);
|
||||
|
|
|
@ -149,12 +149,24 @@ bool Mem::allocate(const Options* options)
|
|||
m_algo = options->algo();
|
||||
m_threads = options->threads();
|
||||
m_doubleHash = options->doubleHash();
|
||||
m_doubleHashThreadMask = options->doubleHashThreadMask();
|
||||
m_memorySize = 0;
|
||||
|
||||
const int ratio = (m_doubleHash && m_algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
|
||||
const size_t size = MEMORY * (m_threads * ratio + 1);
|
||||
size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
|
||||
for (int i=0; i < m_threads; i++) {
|
||||
m_memorySize += sizeof(cryptonight_ctx);
|
||||
|
||||
if (isDoubleHash(i)) {
|
||||
m_memorySize += scratchPadSize*2;
|
||||
} else {
|
||||
m_memorySize += scratchPadSize;
|
||||
}
|
||||
}
|
||||
|
||||
m_memorySize = m_memorySize - (m_memorySize % MEMORY) + MEMORY;
|
||||
|
||||
if (!options->hugePages()) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(size, 16));
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -162,9 +174,9 @@ bool Mem::allocate(const Options* options)
|
|||
m_flags |= HugepagesAvailable;
|
||||
}
|
||||
|
||||
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||
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(size, 16));
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_memorySize, 16));
|
||||
}
|
||||
else {
|
||||
m_flags |= HugepagesEnabled;
|
||||
|
|
|
@ -70,6 +70,7 @@ Options:\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, --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-priority set process priority (0 idle, 2 normal to 5 highest)\n\
|
||||
--no-huge-pages disable huge pages support\n\
|
||||
|
@ -158,6 +159,7 @@ static struct option const options[] = {
|
|||
{ "cc-client-config-folder", 1, nullptr, 4009 },
|
||||
{ "cc-custom-dashboard", 1, nullptr, 4010 },
|
||||
{ "daemonized", 0, nullptr, 4011 },
|
||||
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -180,6 +182,7 @@ static struct option const config_options[] = {
|
|||
{ "syslog", 0, nullptr, 'S' },
|
||||
{ "threads", 1, nullptr, 't' },
|
||||
{ "user-agent", 1, nullptr, 1008 },
|
||||
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -281,7 +284,8 @@ Options::Options(int argc, char **argv) :
|
|||
m_threads(0),
|
||||
m_ccUpdateInterval(10),
|
||||
m_ccPort(0),
|
||||
m_affinity(-1L)
|
||||
m_affinity(-1L),
|
||||
m_doubleHashThreadMask(-1L)
|
||||
{
|
||||
m_pools.push_back(new Url());
|
||||
|
||||
|
@ -528,9 +532,14 @@ bool Options::parseArg(int key, const char *arg)
|
|||
break;
|
||||
|
||||
case 1020: { /* --cpu-affinity */
|
||||
const char *p = strstr(arg, "0x");
|
||||
return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
|
||||
}
|
||||
const char *p = strstr(arg, "0x");
|
||||
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 */
|
||||
free(m_userAgent);
|
||||
|
@ -634,6 +643,7 @@ bool Options::parseArg(int key, uint64_t arg)
|
|||
m_ccPort = (int) arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4012: /* --cc-update-interval-s */
|
||||
if (arg < 1) {
|
||||
showUsage(1);
|
||||
|
@ -642,6 +652,12 @@ bool Options::parseArg(int key, uint64_t arg)
|
|||
|
||||
m_ccUpdateInterval = (int) arg;
|
||||
break;
|
||||
|
||||
case 4013: /* --doublehash-thread-mask */
|
||||
if (arg) {
|
||||
m_doubleHashThreadMask = arg;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,8 @@ public:
|
|||
inline int ccUpdateInterval() const { return m_ccUpdateInterval; }
|
||||
inline int ccPort() const { return m_ccPort; }
|
||||
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; }
|
||||
|
||||
|
@ -155,6 +157,7 @@ private:
|
|||
int m_ccUpdateInterval;
|
||||
int m_ccPort;
|
||||
int64_t m_affinity;
|
||||
int64_t m_doubleHashThreadMask;
|
||||
std::vector<Url*> m_pools;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
|
@ -91,21 +92,51 @@ static void print_cpu()
|
|||
|
||||
static void print_threads()
|
||||
{
|
||||
char buf[32];
|
||||
if (Options::i()->affinity() != -1L) {
|
||||
snprintf(buf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
|
||||
char dhtMaskBuf[256];
|
||||
if (Options::i()->doubleHash() && Options::i()->doubleHashThreadMask() != -1L) {
|
||||
|
||||
std::string singleThreads;
|
||||
std::string doubleThreads;
|
||||
|
||||
for (int i=0; i < Options::i()->threads(); i++) {
|
||||
if (Mem::isDoubleHash(i)) {
|
||||
if (!doubleThreads.empty()) {
|
||||
doubleThreads.append(", ");
|
||||
}
|
||||
|
||||
doubleThreads.append(std::to_string(i));
|
||||
} else {
|
||||
if (!singleThreads.empty()) {
|
||||
singleThreads.append(" ");
|
||||
}
|
||||
|
||||
singleThreads.append(std::to_string(i));
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(dhtMaskBuf, 256, ", doubleHashThreadMask=0x%" PRIX64 " [single threads: %s; double threads: %s]",
|
||||
Options::i()->doubleHashThreadMask(), singleThreads.c_str(), doubleThreads.c_str());
|
||||
}
|
||||
else {
|
||||
buf[0] = '\0';
|
||||
dhtMaskBuf[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" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
|
||||
char affBuf[32];
|
||||
if (Options::i()->affinity() != -1L) {
|
||||
snprintf(affBuf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
|
||||
}
|
||||
else {
|
||||
affBuf[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",
|
||||
Options::i()->threads(),
|
||||
Options::i()->algoName(),
|
||||
Options::i()->algoVariant(),
|
||||
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||
Options::i()->donateLevel(),
|
||||
buf);
|
||||
affBuf,
|
||||
dhtMaskBuf);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
@ -53,11 +53,11 @@ extern "C"
|
|||
|
||||
static inline double normalize(double d)
|
||||
{
|
||||
if (!std::isnormal(d)) {
|
||||
if (!isnormal(d)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return std::floor(d * 100.0) / 100.0;
|
||||
return floor(d * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ CCClient::CCClient(Options* options, uv_async_t* async)
|
|||
|
||||
m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled());
|
||||
m_clientStatus.setHugepages(Mem::isHugepagesAvailable());
|
||||
m_clientStatus.setDoubleHashMode(Mem::isDoubleHash());
|
||||
m_clientStatus.setDoubleHashMode(m_options->doubleHash());
|
||||
|
||||
m_clientStatus.setVersion(Version::string());
|
||||
m_clientStatus.setCpuBrand(Cpu::brand());
|
||||
|
|
|
@ -1,37 +1,38 @@
|
|||
{
|
||||
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
|
||||
"av": 0, // algorithm variation, 0 auto select
|
||||
"background": false, // true to run the miner in the background
|
||||
"colors": true, // false to disable colored output
|
||||
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
|
||||
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
|
||||
"donate-level": 5, // donate level, mininum 1%
|
||||
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
|
||||
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
|
||||
"print-time": 60, // print hashrate report every N seconds
|
||||
"retries": 5, // number of times to retry before switch to backup server
|
||||
"retry-pause": 5, // time to pause between retries
|
||||
"safe": false, // true to safe adjust threads and av settings for current CPU
|
||||
"syslog": false, // use system log for output messages
|
||||
"threads": null, // number of miner threads
|
||||
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
|
||||
"av": 0, // algorithm variation, 0 auto select
|
||||
"doublehash-thread-mask" : null, // for av=2/4 only, limits doublehash to given threads (mask), mask "0x3" means run doublehash on thread 0 and 1 only (default: all threads)
|
||||
"background": false, // true to run the miner in the background
|
||||
"colors": true, // false to disable colored output
|
||||
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
|
||||
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
|
||||
"donate-level": 5, // donate level, mininum 1%
|
||||
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
|
||||
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
|
||||
"print-time": 60, // print hashrate report every N seconds
|
||||
"retries": 5, // number of times to retry before switch to backup server
|
||||
"retry-pause": 5, // time to pause between retries
|
||||
"safe": false, // true to safe adjust threads and av settings for current CPU
|
||||
"syslog": false, // use system log for output messages
|
||||
"threads": null, // number of miner threads
|
||||
"pools": [
|
||||
{
|
||||
"url": "", // URL of mining server
|
||||
"user": "", // username for mining server
|
||||
"pass": "x", // password for mining server
|
||||
"keepalive": true, // send keepalived for prevent timeout (need pool support)
|
||||
"nicehash": false // enable nicehash/xmrig-proxy support
|
||||
"url": "", // URL of mining server
|
||||
"user": "", // username for mining server
|
||||
"pass": "x", // password for mining server
|
||||
"keepalive": true, // send keepalived for prevent timeout (need pool support)
|
||||
"nicehash": false // enable nicehash/xmrig-proxy support
|
||||
}
|
||||
],
|
||||
"api": {
|
||||
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
|
||||
"access-token": null, // access token for API
|
||||
"worker-id": null // custom worker-id for API
|
||||
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
|
||||
"access-token": null, // access token for API
|
||||
"worker-id": null // custom worker-id for API
|
||||
},
|
||||
"cc-client": {
|
||||
"url": "localhost:3344", // url of the CC Server (ip:port)
|
||||
"access-token": "mySecret", // access token for CC Server (has to be the same in config_cc.json)
|
||||
"worker-id": null, // custom worker-id for CC Server (otherwise hostname is used)
|
||||
"update-interval-s": 10 // status update interval in seconds (default: 10 min: 1)
|
||||
"url": "localhost:3344", // url of the CC Server (ip:port)
|
||||
"access-token": "mySecret", // access token for CC Server (has to be the same in config_cc.json)
|
||||
"worker-id": null, // custom worker-id for CC Server (otherwise hostname is used)
|
||||
"update-interval-s": 10 // status update interval in seconds (default: 10 min: 1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,23 +23,34 @@
|
|||
|
||||
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_p.h"
|
||||
|
||||
#if defined(XMRIG_ARM)
|
||||
# include "crypto/CryptoNight_arm.h"
|
||||
#else
|
||||
# include "crypto/CryptoNight_x86.h"
|
||||
#endif
|
||||
|
||||
#include "crypto/CryptoNight_test.h"
|
||||
#include "net/Job.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "Options.h"
|
||||
|
||||
|
||||
void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
|
||||
void (*cryptonight_hash_ctx_s)(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) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,12 +66,16 @@ static void cryptonight_av4_softaes_double(const void *input, size_t size, void
|
|||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
|
||||
# if !defined(XMRIG_ARMv7)
|
||||
cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -93,40 +108,43 @@ void (*cryptonight_variations[4])(const void *input, size_t size, void *output,
|
|||
#endif
|
||||
|
||||
|
||||
bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx)
|
||||
void CryptoNight::hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
|
||||
{
|
||||
cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx);
|
||||
|
||||
return *reinterpret_cast<uint64_t*>(result.result + 24) < job.target();
|
||||
cryptonight_hash_ctx_s(input, size, output, ctx);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (variant < 1 || variant > 4) {
|
||||
if (variant < 1 || variant > 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
const int index = algo == Options::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1);
|
||||
# else
|
||||
const int index = variant - 1;
|
||||
# endif
|
||||
int index = 0;
|
||||
|
||||
cryptonight_hash_ctx = cryptonight_variations[index];
|
||||
if (variant == 3 || variant == 4)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx)
|
||||
bool CryptoNight::selfTest(int algo)
|
||||
{
|
||||
cryptonight_hash_ctx(input, size, output, ctx);
|
||||
}
|
||||
|
||||
|
||||
bool CryptoNight::selfTest(int algo) {
|
||||
if (cryptonight_hash_ctx == nullptr) {
|
||||
if (cryptonight_hash_ctx_s == nullptr || cryptonight_hash_ctx_d == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -135,14 +153,16 @@ bool CryptoNight::selfTest(int algo) {
|
|||
struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
|
||||
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16);
|
||||
|
||||
cryptonight_hash_ctx(test_input, 76, output, ctx);
|
||||
cryptonight_hash_ctx_s(test_input, 76, output, ctx);
|
||||
|
||||
bool resultSingle = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, 32) == 0;
|
||||
|
||||
cryptonight_hash_ctx_d(test_input, 76, output, ctx);
|
||||
|
||||
_mm_free(ctx->memory);
|
||||
_mm_free(ctx);
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
return memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
|
||||
# else
|
||||
return memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
|
||||
# endif
|
||||
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
|
||||
{
|
||||
public:
|
||||
static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx);
|
||||
static void hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
|
||||
static bool init(int algo, int variant);
|
||||
static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx);
|
||||
static void hashDouble(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
|
||||
|
||||
private:
|
||||
static bool selfTest(int algo);
|
||||
|
|
491
src/crypto/CryptoNight_arm.h
Normal file
491
src/crypto/CryptoNight_arm.h
Normal file
|
@ -0,0 +1,491 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016 Imran Yusuff <https://github.com/imranyusuff>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CRYPTONIGHT_ARM_H__
|
||||
#define __CRYPTONIGHT_ARM_H__
|
||||
|
||||
|
||||
#if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
#else
|
||||
# include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/soft_aes.h"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "crypto/c_keccak.h"
|
||||
#include "crypto/c_groestl.h"
|
||||
#include "crypto/c_blake256.h"
|
||||
#include "crypto/c_jh.h"
|
||||
#include "crypto/c_skein.h"
|
||||
}
|
||||
|
||||
|
||||
static inline void do_blake_hash(const void* input, size_t len, char* output) {
|
||||
blake256_hash(reinterpret_cast<uint8_t*>(output), static_cast<const uint8_t*>(input), len);
|
||||
}
|
||||
|
||||
|
||||
static inline void do_groestl_hash(const void* input, size_t len, char* output) {
|
||||
groestl(static_cast<const uint8_t*>(input), len * 8, reinterpret_cast<uint8_t*>(output));
|
||||
}
|
||||
|
||||
|
||||
static inline void do_jh_hash(const void* input, size_t len, char* output) {
|
||||
jh_hash(32 * 8, static_cast<const uint8_t*>(input), 8 * len, reinterpret_cast<uint8_t*>(output));
|
||||
}
|
||||
|
||||
|
||||
static inline void do_skein_hash(const void* input, size_t len, char* output) {
|
||||
xmr_skein(static_cast<const uint8_t*>(input), reinterpret_cast<uint8_t*>(output));
|
||||
}
|
||||
|
||||
|
||||
void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
|
||||
|
||||
|
||||
static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64_t a, const uint64_t b)
|
||||
{
|
||||
return vcombine_u64(vcreate_u64(b), vcreate_u64(a));
|
||||
}
|
||||
|
||||
|
||||
/* this one was not implemented yet so here it is */
|
||||
static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i a)
|
||||
{
|
||||
return vgetq_lane_u64(a, 0);
|
||||
}
|
||||
|
||||
|
||||
#define EXTRACT64(X) _mm_cvtsi128_si64(X)
|
||||
|
||||
|
||||
#if defined(XMRIG_ARMv8)
|
||||
static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
|
||||
{
|
||||
unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b;
|
||||
*hi = r >> 64;
|
||||
return (uint64_t) r;
|
||||
}
|
||||
#else
|
||||
static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) {
|
||||
// multiplier = ab = a * 2^32 + b
|
||||
// multiplicand = cd = c * 2^32 + d
|
||||
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
|
||||
uint64_t a = multiplier >> 32;
|
||||
uint64_t b = multiplier & 0xFFFFFFFF;
|
||||
uint64_t c = multiplicand >> 32;
|
||||
uint64_t d = multiplicand & 0xFFFFFFFF;
|
||||
|
||||
//uint64_t ac = a * c;
|
||||
uint64_t ad = a * d;
|
||||
//uint64_t bc = b * c;
|
||||
uint64_t bd = b * d;
|
||||
|
||||
uint64_t adbc = ad + (b * c);
|
||||
uint64_t adbc_carry = adbc < ad ? 1 : 0;
|
||||
|
||||
// multiplier * multiplicand = product_hi * 2^64 + product_lo
|
||||
uint64_t product_lo = bd + (adbc << 32);
|
||||
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
|
||||
*product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
|
||||
|
||||
return product_lo;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// This will shift and xor tmp1 into itself as 4 32-bit vals such as
|
||||
// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1)
|
||||
static inline __m128i sl_xor(__m128i tmp1)
|
||||
{
|
||||
__m128i tmp4;
|
||||
tmp4 = _mm_slli_si128(tmp1, 0x04);
|
||||
tmp1 = _mm_xor_si128(tmp1, tmp4);
|
||||
tmp4 = _mm_slli_si128(tmp4, 0x04);
|
||||
tmp1 = _mm_xor_si128(tmp1, tmp4);
|
||||
tmp4 = _mm_slli_si128(tmp4, 0x04);
|
||||
tmp1 = _mm_xor_si128(tmp1, tmp4);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
template<uint8_t rcon>
|
||||
static inline void aes_genkey_sub(__m128i* xout0, __m128i* xout2)
|
||||
{
|
||||
// __m128i xout1 = _mm_aeskeygenassist_si128(*xout2, rcon);
|
||||
// xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem
|
||||
// *xout0 = sl_xor(*xout0);
|
||||
// *xout0 = _mm_xor_si128(*xout0, xout1);
|
||||
// xout1 = _mm_aeskeygenassist_si128(*xout0, 0x00);
|
||||
// xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem
|
||||
// *xout2 = sl_xor(*xout2);
|
||||
// *xout2 = _mm_xor_si128(*xout2, xout1);
|
||||
}
|
||||
|
||||
|
||||
template<uint8_t rcon>
|
||||
static inline void soft_aes_genkey_sub(__m128i* xout0, __m128i* xout2)
|
||||
{
|
||||
__m128i xout1 = soft_aeskeygenassist<rcon>(*xout2);
|
||||
xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem
|
||||
*xout0 = sl_xor(*xout0);
|
||||
*xout0 = _mm_xor_si128(*xout0, xout1);
|
||||
xout1 = soft_aeskeygenassist<0x00>(*xout0);
|
||||
xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem
|
||||
*xout2 = sl_xor(*xout2);
|
||||
*xout2 = _mm_xor_si128(*xout2, xout1);
|
||||
}
|
||||
|
||||
|
||||
template<bool SOFT_AES>
|
||||
static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9)
|
||||
{
|
||||
__m128i xout0 = _mm_load_si128(memory);
|
||||
__m128i xout2 = _mm_load_si128(memory + 1);
|
||||
*k0 = xout0;
|
||||
*k1 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x01>(&xout0, &xout2) : soft_aes_genkey_sub<0x01>(&xout0, &xout2);
|
||||
*k2 = xout0;
|
||||
*k3 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x02>(&xout0, &xout2) : soft_aes_genkey_sub<0x02>(&xout0, &xout2);
|
||||
*k4 = xout0;
|
||||
*k5 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x04>(&xout0, &xout2) : soft_aes_genkey_sub<0x04>(&xout0, &xout2);
|
||||
*k6 = xout0;
|
||||
*k7 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x08>(&xout0, &xout2) : soft_aes_genkey_sub<0x08>(&xout0, &xout2);
|
||||
*k8 = xout0;
|
||||
*k9 = xout2;
|
||||
}
|
||||
|
||||
|
||||
template<bool SOFT_AES>
|
||||
static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7)
|
||||
{
|
||||
if (SOFT_AES) {
|
||||
*x0 = soft_aesenc(*x0, key);
|
||||
*x1 = soft_aesenc(*x1, key);
|
||||
*x2 = soft_aesenc(*x2, key);
|
||||
*x3 = soft_aesenc(*x3, key);
|
||||
*x4 = soft_aesenc(*x4, key);
|
||||
*x5 = soft_aesenc(*x5, key);
|
||||
*x6 = soft_aesenc(*x6, key);
|
||||
*x7 = soft_aesenc(*x7, key);
|
||||
}
|
||||
# ifndef XMRIG_ARMv7
|
||||
else {
|
||||
*x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key));
|
||||
*x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key));
|
||||
*x2 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x2), key));
|
||||
*x3 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x3), key));
|
||||
*x4 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x4), key));
|
||||
*x5 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x5), key));
|
||||
*x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key));
|
||||
*x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key));
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
template<size_t MEM, bool SOFT_AES>
|
||||
static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
||||
{
|
||||
__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
|
||||
__m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
|
||||
|
||||
aes_genkey<SOFT_AES>(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
|
||||
|
||||
xin0 = _mm_load_si128(input + 4);
|
||||
xin1 = _mm_load_si128(input + 5);
|
||||
xin2 = _mm_load_si128(input + 6);
|
||||
xin3 = _mm_load_si128(input + 7);
|
||||
xin4 = _mm_load_si128(input + 8);
|
||||
xin5 = _mm_load_si128(input + 9);
|
||||
xin6 = _mm_load_si128(input + 10);
|
||||
xin7 = _mm_load_si128(input + 11);
|
||||
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xin0 ^= k9;
|
||||
xin1 ^= k9;
|
||||
xin2 ^= k9;
|
||||
xin3 ^= k9;
|
||||
xin4 ^= k9;
|
||||
xin5 ^= k9;
|
||||
xin6 ^= k9;
|
||||
xin7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
|
||||
_mm_store_si128(output + i + 0, xin0);
|
||||
_mm_store_si128(output + i + 1, xin1);
|
||||
_mm_store_si128(output + i + 2, xin2);
|
||||
_mm_store_si128(output + i + 3, xin3);
|
||||
_mm_store_si128(output + i + 4, xin4);
|
||||
_mm_store_si128(output + i + 5, xin5);
|
||||
_mm_store_si128(output + i + 6, xin6);
|
||||
_mm_store_si128(output + i + 7, xin7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<size_t MEM, bool SOFT_AES>
|
||||
static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
||||
{
|
||||
__m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7;
|
||||
__m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
|
||||
|
||||
aes_genkey<SOFT_AES>(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
|
||||
|
||||
xout0 = _mm_load_si128(output + 4);
|
||||
xout1 = _mm_load_si128(output + 5);
|
||||
xout2 = _mm_load_si128(output + 6);
|
||||
xout3 = _mm_load_si128(output + 7);
|
||||
xout4 = _mm_load_si128(output + 8);
|
||||
xout5 = _mm_load_si128(output + 9);
|
||||
xout6 = _mm_load_si128(output + 10);
|
||||
xout7 = _mm_load_si128(output + 11);
|
||||
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8)
|
||||
{
|
||||
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
|
||||
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
|
||||
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
|
||||
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
|
||||
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
|
||||
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
|
||||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xout0 ^= k9;
|
||||
xout1 ^= k9;
|
||||
xout2 ^= k9;
|
||||
xout3 ^= k9;
|
||||
xout4 ^= k9;
|
||||
xout5 ^= k9;
|
||||
xout6 ^= k9;
|
||||
xout7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
}
|
||||
|
||||
_mm_store_si128(output + 4, xout0);
|
||||
_mm_store_si128(output + 5, xout1);
|
||||
_mm_store_si128(output + 6, xout2);
|
||||
_mm_store_si128(output + 7, xout3);
|
||||
_mm_store_si128(output + 8, xout4);
|
||||
_mm_store_si128(output + 9, xout5);
|
||||
_mm_store_si128(output + 10, xout6);
|
||||
_mm_store_si128(output + 11, xout7);
|
||||
}
|
||||
|
||||
|
||||
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES>
|
||||
inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
|
||||
{
|
||||
keccak(static_cast<const uint8_t*>(input), (int) size, ctx->state0, 200);
|
||||
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t ah0 = h0[1] ^ h0[5];
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
|
||||
uint64_t idx0 = h0[0] ^ h0[4];
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS; i++) {
|
||||
__m128i cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
|
||||
|
||||
if (SOFT_AES) {
|
||||
cx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0));
|
||||
}
|
||||
else {
|
||||
# ifndef XMRIG_ARMv7
|
||||
cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
|
||||
# endif
|
||||
}
|
||||
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
idx0 = EXTRACT64(cx);
|
||||
bx0 = cx;
|
||||
|
||||
uint64_t hi, lo, cl, ch;
|
||||
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
|
||||
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
|
||||
lo = __umul128(idx0, cl, &hi);
|
||||
|
||||
al0 += hi;
|
||||
ah0 += lo;
|
||||
|
||||
((uint64_t*)&l0[idx0 & MASK])[0] = al0;
|
||||
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
|
||||
|
||||
ah0 ^= ch;
|
||||
al0 ^= cl;
|
||||
idx0 = al0;
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
|
||||
|
||||
keccakf(h0, 24);
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast<char*>(output));
|
||||
}
|
||||
|
||||
|
||||
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES>
|
||||
inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
{
|
||||
keccak((const uint8_t *) input, (int) size, ctx->state0, 200);
|
||||
keccak((const uint8_t *) input + size, (int) size, ctx->state1, 200);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
const uint8_t* l1 = ctx->memory + MEM;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state1);
|
||||
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
|
||||
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t al1 = h1[0] ^ h1[4];
|
||||
uint64_t ah0 = h0[1] ^ h0[5];
|
||||
uint64_t ah1 = h1[1] ^ h1[5];
|
||||
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
|
||||
uint64_t idx0 = h0[0] ^ h0[4];
|
||||
uint64_t idx1 = h1[0] ^ h1[4];
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS; i++) {
|
||||
__m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
|
||||
__m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
|
||||
|
||||
if (SOFT_AES) {
|
||||
cx0 = soft_aesenc(cx0, _mm_set_epi64x(ah0, al0));
|
||||
cx1 = soft_aesenc(cx1, _mm_set_epi64x(ah1, al1));
|
||||
}
|
||||
else {
|
||||
# ifndef XMRIG_ARMv7
|
||||
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
|
||||
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
|
||||
# endif
|
||||
}
|
||||
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
|
||||
idx0 = EXTRACT64(cx0);
|
||||
idx1 = EXTRACT64(cx1);
|
||||
|
||||
bx0 = cx0;
|
||||
bx1 = cx1;
|
||||
|
||||
uint64_t hi, lo, cl, ch;
|
||||
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
|
||||
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
|
||||
lo = __umul128(idx0, cl, &hi);
|
||||
|
||||
al0 += hi;
|
||||
ah0 += lo;
|
||||
|
||||
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
|
||||
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
|
||||
|
||||
ah0 ^= ch;
|
||||
al0 ^= cl;
|
||||
idx0 = al0;
|
||||
|
||||
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
|
||||
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
|
||||
lo = __umul128(idx1, cl, &hi);
|
||||
|
||||
al1 += hi;
|
||||
ah1 += lo;
|
||||
|
||||
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
|
||||
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
|
||||
|
||||
ah1 ^= ch;
|
||||
al1 ^= cl;
|
||||
idx1 = al1;
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
|
||||
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
|
||||
|
||||
keccakf(h0, 24);
|
||||
keccakf(h1, 24);
|
||||
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast<char*>(output));
|
||||
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast<char*>(output) + 32);
|
||||
}
|
||||
|
||||
#endif /* __CRYPTONIGHT_ARM_H__ */
|
|
@ -47,14 +47,12 @@ const static uint8_t test_output0[64] = {
|
|||
};
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
const static uint8_t test_output1[64] = {
|
||||
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
|
||||
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
|
||||
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
|
||||
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CRYPTONIGHT_TEST_H__ */
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CRYPTONIGHT_P_H__
|
||||
#define __CRYPTONIGHT_P_H__
|
||||
#ifndef __CRYPTONIGHT_X86_H__
|
||||
#define __CRYPTONIGHT_X86_H__
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -448,4 +448,4 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size,
|
|||
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast<char*>(output) + 32);
|
||||
}
|
||||
|
||||
#endif /* __CRYPTONIGHT_P_H__ */
|
||||
#endif /* __CRYPTONIGHT_X86_H__ */
|
1497
src/crypto/SSE2NEON.h
Normal file
1497
src/crypto/SSE2NEON.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -26,14 +26,18 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <x86intrin.h>
|
||||
|
||||
#if defined(XMRIG_ARM)
|
||||
# include "crypto/SSE2NEON.h"
|
||||
#elif defined(__GNUC__)
|
||||
# include <x86intrin.h>
|
||||
#else
|
||||
#include <intrin.h>
|
||||
#endif // __GNUC__
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#define saes_data(w) {\
|
||||
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||
|
@ -109,7 +113,7 @@ static inline uint32_t sub_word(uint32_t key)
|
|||
saes_sbox[key & 0xff];
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#if defined(__clang__) || defined(XMRIG_ARM)
|
||||
static inline uint32_t _rotr(uint32_t value, uint32_t amount)
|
||||
{
|
||||
return (value >> amount) | (value << ((32 - amount) & 31));
|
||||
|
|
|
@ -1,37 +1,38 @@
|
|||
{
|
||||
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
|
||||
"av": 0, // algorithm variation, 0 auto select
|
||||
"background": false, // true to run the miner in the background
|
||||
"colors": true, // false to disable colored output
|
||||
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
|
||||
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
|
||||
"donate-level": 5, // donate level, mininum 1%
|
||||
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
|
||||
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
|
||||
"print-time": 60, // print hashrate report every N seconds
|
||||
"retries": 5, // number of times to retry before switch to backup server
|
||||
"retry-pause": 5, // time to pause between retries
|
||||
"safe": false, // true to safe adjust threads and av settings for current CPU
|
||||
"syslog": false, // use system log for output messages
|
||||
"threads": null, // number of miner threads
|
||||
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
|
||||
"av": 0, // algorithm variation, 0 auto select
|
||||
"doublehash-thread-mask" : null, // for av=2/4 only, limits doublehash to given threads (mask), mask "0x3" means run doublehash on thread 0 and 1 only (default: all threads)
|
||||
"background": false, // true to run the miner in the background
|
||||
"colors": true, // false to disable colored output
|
||||
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
|
||||
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
|
||||
"donate-level": 5, // donate level, mininum 1%
|
||||
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
|
||||
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
|
||||
"print-time": 60, // print hashrate report every N seconds
|
||||
"retries": 5, // number of times to retry before switch to backup server
|
||||
"retry-pause": 5, // time to pause between retries
|
||||
"safe": false, // true to safe adjust threads and av settings for current CPU
|
||||
"syslog": false, // use system log for output messages
|
||||
"threads": null, // number of miner threads
|
||||
"pools": [
|
||||
{
|
||||
"url": "", // URL of mining server
|
||||
"user": "", // username for mining server
|
||||
"pass": "x", // password for mining server
|
||||
"keepalive": true, // send keepalived for prevent timeout (need pool support)
|
||||
"nicehash": false // enable nicehash/xmrig-proxy support
|
||||
"url": "", // URL of mining server
|
||||
"user": "", // username for mining server
|
||||
"pass": "x", // password for mining server
|
||||
"keepalive": true, // send keepalived for prevent timeout (need pool support)
|
||||
"nicehash": false // enable nicehash/xmrig-proxy support
|
||||
}
|
||||
],
|
||||
"api": {
|
||||
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
|
||||
"access-token": null, // access token for API
|
||||
"worker-id": null // custom worker-id for API
|
||||
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
|
||||
"access-token": null, // access token for API
|
||||
"worker-id": null // custom worker-id for API
|
||||
},
|
||||
"cc-client": {
|
||||
"url": "localhost:3344", // url of the CC Server (ip:port)
|
||||
"access-token": "mySecret", // access token for CC Server (has to be the same in config_cc.json)
|
||||
"worker-id": null, // custom worker-id for CC Server (otherwise hostname is used)
|
||||
"update-interval-s": 10 // status update interval in seconds (default: 10 min: 1)
|
||||
"url": "localhost:3344", // url of the CC Server (ip:port)
|
||||
"access-token": "mySecret", // access token for CC Server (has to be the same in config_cc.json)
|
||||
"worker-id": null, // custom worker-id for CC Server (otherwise hostname is used)
|
||||
"update-interval-s": 10 // status update interval in seconds (default: 10 min: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "Options.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
|
@ -36,19 +38,22 @@
|
|||
|
||||
#include "log/ConsoleLog.h"
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
|
||||
|
||||
ConsoleLog::ConsoleLog(bool colors) :
|
||||
m_colors(colors),
|
||||
m_stream(nullptr)
|
||||
m_colors(colors),
|
||||
m_stream(nullptr)
|
||||
{
|
||||
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
|
||||
Options::i()->setColors(false);
|
||||
m_colors = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
|
||||
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
|
||||
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
@ -65,10 +70,6 @@ ConsoleLog::ConsoleLog(bool colors) :
|
|||
|
||||
void ConsoleLog::message(int level, const char* fmt, va_list args)
|
||||
{
|
||||
if (!isWritable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
time_t now = time(nullptr);
|
||||
tm stime;
|
||||
|
||||
|
@ -113,7 +114,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
|
|||
m_colors ? color : "",
|
||||
fmt,
|
||||
m_colors ? Log::kCL_N : ""
|
||||
);
|
||||
);
|
||||
|
||||
print(args);
|
||||
}
|
||||
|
@ -121,10 +122,6 @@ void ConsoleLog::message(int level, 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 : "");
|
||||
|
||||
print(args);
|
||||
|
@ -149,5 +146,11 @@ void ConsoleLog::print(va_list args)
|
|||
return;
|
||||
}
|
||||
|
||||
uv_try_write(m_stream, &m_uvBuf, 1);
|
||||
if (!isWritable()) {
|
||||
fputs(m_buf, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
else {
|
||||
uv_try_write(m_stream, &m_uvBuf, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,14 +36,14 @@
|
|||
#define APP_DESC "XMRigCC CPU miner"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
|
||||
#endif
|
||||
#define APP_VERSION "1.1.1 (based on XMRig 2.4.2)"
|
||||
#define APP_VERSION "1.2.0 (based on XMRig 2.4.3)"
|
||||
#define APP_DOMAIN ""
|
||||
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
|
||||
#define APP_KIND "cpu"
|
||||
|
||||
#define APP_VER_MAJOR 1
|
||||
#define APP_VER_MINOR 1
|
||||
#define APP_VER_BUILD 1
|
||||
#define APP_VER_MINOR 2
|
||||
#define APP_VER_BUILD 0
|
||||
#define APP_VER_REV 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -82,17 +82,18 @@ void DoubleWorker::start()
|
|||
}
|
||||
|
||||
m_count += 2;
|
||||
|
||||
*Job::nonce(m_state->blob) = ++m_state->nonce1;
|
||||
*Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2;
|
||||
|
||||
CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
||||
CryptoNight::hashDouble(m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
||||
|
||||
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()));
|
||||
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff()), m_id);
|
||||
}
|
||||
|
||||
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()));
|
||||
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff()), m_id);
|
||||
}
|
||||
|
||||
std::this_thread::yield();
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "Options.h"
|
||||
|
@ -33,7 +34,7 @@
|
|||
|
||||
inline const char *format(double h, char* buf, size_t size)
|
||||
{
|
||||
if (std::isnormal(h)) {
|
||||
if (isnormal(h)) {
|
||||
snprintf(buf, size, "%03.1f", h);
|
||||
return buf;
|
||||
}
|
||||
|
@ -77,7 +78,7 @@ double Hashrate::calc(size_t ms) const
|
|||
|
||||
for (int i = 0; i < m_threads; ++i) {
|
||||
data = calc(i, ms);
|
||||
if (std::isnormal(data)) {
|
||||
if (isnormal(data)) {
|
||||
result += data;
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +171,7 @@ void Hashrate::stop()
|
|||
void Hashrate::updateHighest()
|
||||
{
|
||||
double highest = calc(ShortInterval);
|
||||
if (std::isnormal(highest) && highest > m_highest) {
|
||||
if (isnormal(highest) && highest > m_highest) {
|
||||
m_highest = highest;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,8 +60,10 @@ void SingleWorker::start()
|
|||
m_count++;
|
||||
*m_job.nonce() = ++m_result.nonce;
|
||||
|
||||
if (CryptoNight::hash(m_job, m_result, m_ctx)) {
|
||||
Workers::submit(m_result);
|
||||
CryptoNight::hash(m_job.blob(), m_job.size(), m_result.result, m_ctx);
|
||||
|
||||
if (*reinterpret_cast<uint64_t*>(m_result.result + 24) < m_job.target()) {
|
||||
Workers::submit(m_result, m_id);
|
||||
}
|
||||
|
||||
std::this_thread::yield();
|
||||
|
@ -103,10 +105,10 @@ void SingleWorker::consumeJob()
|
|||
m_result = m_job;
|
||||
|
||||
if (m_job.isNicehash()) {
|
||||
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id);
|
||||
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id);
|
||||
}
|
||||
else {
|
||||
m_result.nonce = 0xffffffffU / m_threads * m_id;
|
||||
m_result.nonce = 0xffffffffU / (m_threads * 2) * m_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ void Workers::stop()
|
|||
}
|
||||
|
||||
|
||||
void Workers::submit(const JobResult &result)
|
||||
void Workers::submit(const JobResult &result, int threadId)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
m_queue.push_back(result);
|
||||
|
@ -153,7 +153,7 @@ void Workers::submit(const JobResult &result)
|
|||
void Workers::onReady(void *arg)
|
||||
{
|
||||
auto handle = static_cast<Handle*>(arg);
|
||||
if (Mem::isDoubleHash()) {
|
||||
if (Mem::isDoubleHash(handle->threadId())) {
|
||||
handle->setWorker(new DoubleWorker(handle));
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
static void setJob(const Job &job);
|
||||
static void start(int64_t affinity, int priority);
|
||||
static void stop();
|
||||
static void submit(const JobResult &result);
|
||||
static void submit(const JobResult &result, int threadId);
|
||||
|
||||
static inline bool isEnabled() { return m_enabled; }
|
||||
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