Merge branch 'dev'
This commit is contained in:
commit
d78713be48
121 changed files with 1944 additions and 1118 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,3 +1,15 @@
|
||||||
|
# v6.16.1
|
||||||
|
- [#2729](https://github.com/xmrig/xmrig/pull/2729) GhostRider fixes:
|
||||||
|
- Added average hashrate display
|
||||||
|
- Fixed the number of threads shown at startup
|
||||||
|
- Fixed `--threads` or `-t` command line option (but `--cpu-max-threads-hint` is recommended to use)
|
||||||
|
- [#2738](https://github.com/xmrig/xmrig/pull/2738) GhostRider fixes:
|
||||||
|
- Fixed "difficulty is not a number" error when diff is high on some pools
|
||||||
|
- Fixed GhostRider compilation when WITH_KAWPOW=OFF
|
||||||
|
- [#2740](https://github.com/xmrig/xmrig/pull/2740) Added VAES support for Cryptonight variants **+4% speedup on Zen3**
|
||||||
|
- VAES instructions are available on Intel Ice Lake/AMD Zen3 and newer CPUs.
|
||||||
|
- +4% speedup on Ryzen 5 5600X.
|
||||||
|
|
||||||
# v6.16.0
|
# v6.16.0
|
||||||
- [#2712](https://github.com/xmrig/xmrig/pull/2712) **GhostRider algorithm (Raptoreum) support**: read the [RELEASE NOTES](src/crypto/ghostrider/README.md) for quick start guide and performance comparisons.
|
- [#2712](https://github.com/xmrig/xmrig/pull/2712) **GhostRider algorithm (Raptoreum) support**: read the [RELEASE NOTES](src/crypto/ghostrider/README.md) for quick start guide and performance comparisons.
|
||||||
- [#2682](https://github.com/xmrig/xmrig/pull/2682) Fixed: use cn-heavy optimization only for Vermeer CPUs.
|
- [#2682](https://github.com/xmrig/xmrig/pull/2682) Fixed: use cn-heavy optimization only for Vermeer CPUs.
|
||||||
|
|
|
@ -28,6 +28,7 @@ option(WITH_STRICT_CACHE "Enable strict checks for OpenCL cache" ON)
|
||||||
option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF)
|
option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF)
|
||||||
option(WITH_PROFILING "Enable profiling for developers" OFF)
|
option(WITH_PROFILING "Enable profiling for developers" OFF)
|
||||||
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
|
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
|
||||||
|
option(WITH_VAES "Enable VAES instructions for Cryptonight" ON)
|
||||||
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
|
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
|
||||||
option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF)
|
option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF)
|
||||||
option(WITH_DMI "Enable DMI/SMBIOS reader" ON)
|
option(WITH_DMI "Enable DMI/SMBIOS reader" ON)
|
||||||
|
@ -133,6 +134,15 @@ if (CMAKE_C_COMPILER_ID MATCHES GNU)
|
||||||
set_source_files_properties(src/crypto/cn/CnHash.cpp PROPERTIES COMPILE_FLAGS "-Ofast -fno-tree-vectorize")
|
set_source_files_properties(src/crypto/cn/CnHash.cpp PROPERTIES COMPILE_FLAGS "-Ofast -fno-tree-vectorize")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (WITH_VAES)
|
||||||
|
add_definitions(-DXMRIG_VAES)
|
||||||
|
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_x86_vaes.h)
|
||||||
|
set(SOURCES_CRYPTO "${SOURCES_CRYPTO}" src/crypto/cn/CryptoNight_x86_vaes.cpp)
|
||||||
|
if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
|
||||||
|
set_source_files_properties(src/crypto/cn/CryptoNight_x86_vaes.cpp PROPERTIES COMPILE_FLAGS "-Ofast -fno-tree-vectorize -mavx2 -mvaes")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if (WITH_HWLOC)
|
if (WITH_HWLOC)
|
||||||
list(APPEND HEADERS_CRYPTO
|
list(APPEND HEADERS_CRYPTO
|
||||||
src/crypto/common/NUMAMemoryPool.h
|
src/crypto/common/NUMAMemoryPool.h
|
||||||
|
|
|
@ -9,10 +9,23 @@ if (NOT CMAKE_SYSTEM_PROCESSOR)
|
||||||
message(WARNING "CMAKE_SYSTEM_PROCESSOR not defined")
|
message(WARNING "CMAKE_SYSTEM_PROCESSOR not defined")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||||
|
set(VAES_SUPPORTED ON)
|
||||||
|
else()
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-mavx2 -mvaes" VAES_SUPPORTED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT VAES_SUPPORTED)
|
||||||
|
set(WITH_VAES OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (XMRIG_64_BIT AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
|
if (XMRIG_64_BIT AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
|
||||||
add_definitions(-DRAPIDJSON_SSE2)
|
add_definitions(-DRAPIDJSON_SSE2)
|
||||||
else()
|
else()
|
||||||
set(WITH_SSE4_1 OFF)
|
set(WITH_SSE4_1 OFF)
|
||||||
|
set(WITH_VAES OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT ARM_TARGET)
|
if (NOT ARM_TARGET)
|
||||||
|
@ -29,8 +42,6 @@ if (ARM_TARGET AND ARM_TARGET GREATER 6)
|
||||||
|
|
||||||
message(STATUS "Use ARM_TARGET=${ARM_TARGET} (${CMAKE_SYSTEM_PROCESSOR})")
|
message(STATUS "Use ARM_TARGET=${ARM_TARGET} (${CMAKE_SYSTEM_PROCESSOR})")
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
|
|
||||||
if (ARM_TARGET EQUAL 8)
|
if (ARM_TARGET EQUAL 8)
|
||||||
CHECK_CXX_COMPILER_FLAG(-march=armv8-a+crypto XMRIG_ARM_CRYPTO)
|
CHECK_CXX_COMPILER_FLAG(-march=armv8-a+crypto XMRIG_ARM_CRYPTO)
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@ xmrig::Hashrate::Hashrate(size_t threads) :
|
||||||
m_timestamps[i] = new uint64_t[kBucketSize]();
|
m_timestamps[i] = new uint64_t[kBucketSize]();
|
||||||
m_top[i] = 0;
|
m_top[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_earliestTimestamp = std::numeric_limits<uint64_t>::max();
|
||||||
|
m_totalCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,6 +69,14 @@ xmrig::Hashrate::~Hashrate()
|
||||||
delete [] m_counts;
|
delete [] m_counts;
|
||||||
delete [] m_timestamps;
|
delete [] m_timestamps;
|
||||||
delete [] m_top;
|
delete [] m_top;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double xmrig::Hashrate::average() const
|
||||||
|
{
|
||||||
|
const uint64_t ts = Chrono::steadyMSecs();
|
||||||
|
return (ts > m_earliestTimestamp) ? (m_totalCount * 1e3 / (ts - m_earliestTimestamp)) : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,4 +178,11 @@ void xmrig::Hashrate::addData(size_t index, uint64_t count, uint64_t timestamp)
|
||||||
m_timestamps[index][top] = timestamp;
|
m_timestamps[index][top] = timestamp;
|
||||||
|
|
||||||
m_top[index] = (top + 1) & kBucketMask;
|
m_top[index] = (top + 1) & kBucketMask;
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
if (m_earliestTimestamp == std::numeric_limits<uint64_t>::max()) {
|
||||||
|
m_earliestTimestamp = timestamp;
|
||||||
|
}
|
||||||
|
m_totalCount = count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
inline void add(size_t threadId, uint64_t count, uint64_t timestamp) { addData(threadId + 1U, count, timestamp); }
|
inline void add(size_t threadId, uint64_t count, uint64_t timestamp) { addData(threadId + 1U, count, timestamp); }
|
||||||
inline void add(uint64_t count, uint64_t timestamp) { addData(0U, count, timestamp); }
|
inline void add(uint64_t count, uint64_t timestamp) { addData(0U, count, timestamp); }
|
||||||
|
|
||||||
|
double average() const;
|
||||||
|
|
||||||
static const char *format(double h, char *buf, size_t size);
|
static const char *format(double h, char *buf, size_t size);
|
||||||
static rapidjson::Value normalize(double d);
|
static rapidjson::Value normalize(double d);
|
||||||
|
|
||||||
|
@ -72,6 +74,9 @@ private:
|
||||||
uint32_t* m_top;
|
uint32_t* m_top;
|
||||||
uint64_t** m_counts;
|
uint64_t** m_counts;
|
||||||
uint64_t** m_timestamps;
|
uint64_t** m_timestamps;
|
||||||
|
|
||||||
|
uint64_t m_earliestTimestamp;
|
||||||
|
uint64_t m_totalCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ class Worker : public IWorker
|
||||||
public:
|
public:
|
||||||
Worker(size_t id, int64_t affinity, int priority);
|
Worker(size_t id, int64_t affinity, int priority);
|
||||||
|
|
||||||
|
size_t threads() const override { return 1; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline int64_t affinity() const { return m_affinity; }
|
inline int64_t affinity() const { return m_affinity; }
|
||||||
inline size_t id() const override { return m_id; }
|
inline size_t id() const override { return m_id; }
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
virtual const VirtualMemory *memory() const = 0;
|
virtual const VirtualMemory *memory() const = 0;
|
||||||
virtual size_t id() const = 0;
|
virtual size_t id() const = 0;
|
||||||
virtual size_t intensity() const = 0;
|
virtual size_t intensity() const = 0;
|
||||||
|
virtual size_t threads() const = 0;
|
||||||
virtual void hashrateData(uint64_t &hashCount, uint64_t &timeStamp, uint64_t &rawHashes) const = 0;
|
virtual void hashrateData(uint64_t &hashCount, uint64_t &timeStamp, uint64_t &rawHashes) const = 0;
|
||||||
virtual void jobEarlyNotification(const Job &job) = 0;
|
virtual void jobEarlyNotification(const Job &job) = 0;
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
|
|
|
@ -88,6 +88,7 @@ public:
|
||||||
{
|
{
|
||||||
if (ready) {
|
if (ready) {
|
||||||
m_started++;
|
m_started++;
|
||||||
|
m_totalStarted += worker->threads();
|
||||||
|
|
||||||
if (m_workersMemory.insert(worker->memory()).second) {
|
if (m_workersMemory.insert(worker->memory()).second) {
|
||||||
m_hugePages += worker->memory()->hugePages();
|
m_hugePages += worker->memory()->hugePages();
|
||||||
|
@ -112,7 +113,7 @@ public:
|
||||||
LOG_INFO("%s" GREEN_BOLD(" READY") " threads %s%zu/%zu (%zu)" CLEAR " huge pages %s%1.0f%% %zu/%zu" CLEAR " memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"),
|
LOG_INFO("%s" GREEN_BOLD(" READY") " threads %s%zu/%zu (%zu)" CLEAR " huge pages %s%1.0f%% %zu/%zu" CLEAR " memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"),
|
||||||
Tags::cpu(),
|
Tags::cpu(),
|
||||||
m_errors == 0 ? CYAN_BOLD_S : YELLOW_BOLD_S,
|
m_errors == 0 ? CYAN_BOLD_S : YELLOW_BOLD_S,
|
||||||
m_started, m_threads, m_ways,
|
m_totalStarted, std::max(m_totalStarted, m_threads), m_ways,
|
||||||
(m_hugePages.isFullyAllocated() ? GREEN_BOLD_S : (m_hugePages.allocated == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
|
(m_hugePages.isFullyAllocated() ? GREEN_BOLD_S : (m_hugePages.allocated == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
|
||||||
m_hugePages.percent(),
|
m_hugePages.percent(),
|
||||||
m_hugePages.allocated, m_hugePages.total,
|
m_hugePages.allocated, m_hugePages.total,
|
||||||
|
@ -127,6 +128,7 @@ private:
|
||||||
size_t m_errors = 0;
|
size_t m_errors = 0;
|
||||||
size_t m_memory = 0;
|
size_t m_memory = 0;
|
||||||
size_t m_started = 0;
|
size_t m_started = 0;
|
||||||
|
size_t m_totalStarted = 0;
|
||||||
size_t m_threads = 0;
|
size_t m_threads = 0;
|
||||||
size_t m_ways = 0;
|
size_t m_ways = 0;
|
||||||
uint64_t m_ts = 0;
|
uint64_t m_ts = 0;
|
||||||
|
|
|
@ -44,7 +44,7 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit
|
||||||
affinity(thread.affinity()),
|
affinity(thread.affinity()),
|
||||||
miner(miner),
|
miner(miner),
|
||||||
threads(threads),
|
threads(threads),
|
||||||
intensity(std::min<uint32_t>(thread.intensity(), algorithm.maxIntensity())),
|
intensity(std::max<uint32_t>(std::min<uint32_t>(thread.intensity(), algorithm.maxIntensity()), algorithm.minIntensity())),
|
||||||
affinities(affinities)
|
affinities(affinities)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,14 +161,14 @@ bool xmrig::CpuWorker<N>::selfTest()
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
allocateCnCtx();
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_GHOSTRIDER
|
# ifdef XMRIG_ALGO_GHOSTRIDER
|
||||||
if (m_algorithm.family() == Algorithm::GHOSTRIDER) {
|
if (m_algorithm.family() == Algorithm::GHOSTRIDER) {
|
||||||
return N == 8;
|
return (N == 8) && verify(Algorithm::GHOSTRIDER_RTM, test_output_gr);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
allocateCnCtx();
|
|
||||||
|
|
||||||
if (m_algorithm.family() == Algorithm::CN) {
|
if (m_algorithm.family() == Algorithm::CN) {
|
||||||
const bool rc = verify(Algorithm::CN_0, test_output_v0) &&
|
const bool rc = verify(Algorithm::CN_0, test_output_v0) &&
|
||||||
verify(Algorithm::CN_1, test_output_v1) &&
|
verify(Algorithm::CN_1, test_output_v1) &&
|
||||||
|
@ -397,6 +397,37 @@ bool xmrig::CpuWorker<N>::nextRound()
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
|
bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
|
||||||
{
|
{
|
||||||
|
# ifdef XMRIG_ALGO_GHOSTRIDER
|
||||||
|
if (algorithm == Algorithm::GHOSTRIDER_RTM) {
|
||||||
|
uint8_t blob[N * 80] = {};
|
||||||
|
for (size_t i = 0; i < N; ++i) {
|
||||||
|
blob[i * 80 + 0] = static_cast<uint8_t>(i);
|
||||||
|
blob[i * 80 + 4] = 0x10;
|
||||||
|
blob[i * 80 + 5] = 0x02;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t hash1[N * 32] = {};
|
||||||
|
ghostrider::hash_octa(blob, 80, hash1, m_ctx, 0, false);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < N; ++i) {
|
||||||
|
blob[i * 80 + 0] = static_cast<uint8_t>(i);
|
||||||
|
blob[i * 80 + 4] = 0x43;
|
||||||
|
blob[i * 80 + 5] = 0x05;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t hash2[N * 32] = {};
|
||||||
|
ghostrider::hash_octa(blob, 80, hash2, m_ctx, 0, false);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < N * 32; ++i) {
|
||||||
|
if ((hash1[i] ^ hash2[i]) != referenceValue[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
cn_hash_fun func = fn(algorithm);
|
cn_hash_fun func = fn(algorithm);
|
||||||
if (!func) {
|
if (!func) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -52,6 +52,15 @@ public:
|
||||||
CpuWorker(size_t id, const CpuLaunchData &data);
|
CpuWorker(size_t id, const CpuLaunchData &data);
|
||||||
~CpuWorker() override;
|
~CpuWorker() override;
|
||||||
|
|
||||||
|
size_t threads() const override
|
||||||
|
{
|
||||||
|
# ifdef XMRIG_ALGO_GHOSTRIDER
|
||||||
|
return m_ghHelper ? 2 : 1;
|
||||||
|
# else
|
||||||
|
return 1;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool selfTest() override;
|
bool selfTest() override;
|
||||||
void hashrateData(uint64_t &hashCount, uint64_t &timeStamp, uint64_t &rawHashes) const override;
|
void hashrateData(uint64_t &hashCount, uint64_t &timeStamp, uint64_t &rawHashes) const override;
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
|
|
||||||
enum Flag : uint32_t {
|
enum Flag : uint32_t {
|
||||||
FLAG_AES,
|
FLAG_AES,
|
||||||
|
FLAG_VAES,
|
||||||
FLAG_AVX,
|
FLAG_AVX,
|
||||||
FLAG_AVX2,
|
FLAG_AVX2,
|
||||||
FLAG_AVX512F,
|
FLAG_AVX512F,
|
||||||
|
@ -90,6 +91,7 @@ public:
|
||||||
virtual Assembly::Id assembly() const = 0;
|
virtual Assembly::Id assembly() const = 0;
|
||||||
virtual bool has(Flag feature) const = 0;
|
virtual bool has(Flag feature) const = 0;
|
||||||
virtual bool hasAES() const = 0;
|
virtual bool hasAES() const = 0;
|
||||||
|
virtual bool hasVAES() const = 0;
|
||||||
virtual bool hasAVX() const = 0;
|
virtual bool hasAVX() const = 0;
|
||||||
virtual bool hasAVX2() const = 0;
|
virtual bool hasAVX2() const = 0;
|
||||||
virtual bool hasBMI2() const = 0;
|
virtual bool hasBMI2() const = 0;
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
constexpr size_t kCpuFlagsSize = 14;
|
constexpr size_t kCpuFlagsSize = 15;
|
||||||
static const std::array<const char *, kCpuFlagsSize> flagNames = { "aes", "avx", "avx2", "avx512f", "bmi2", "osxsave", "pdpe1gb", "sse2", "ssse3", "sse4.1", "xop", "popcnt", "cat_l3", "vm" };
|
static const std::array<const char *, kCpuFlagsSize> flagNames = { "aes", "vaes", "avx", "avx2", "avx512f", "bmi2", "osxsave", "pdpe1gb", "sse2", "ssse3", "sse4.1", "xop", "popcnt", "cat_l3", "vm" };
|
||||||
static_assert(kCpuFlagsSize == ICpuInfo::FLAG_MAX, "kCpuFlagsSize and FLAG_MAX mismatch");
|
static_assert(kCpuFlagsSize == ICpuInfo::FLAG_MAX, "kCpuFlagsSize and FLAG_MAX mismatch");
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ static inline bool has_osxsave() { return has_feature(PROCESSOR_INFO,
|
||||||
static inline bool has_aes_ni() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 25); }
|
static inline bool has_aes_ni() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 25); }
|
||||||
static inline bool has_avx() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 28) && has_osxsave() && has_xcr_avx(); }
|
static inline bool has_avx() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 28) && has_osxsave() && has_xcr_avx(); }
|
||||||
static inline bool has_avx2() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 5) && has_osxsave() && has_xcr_avx(); }
|
static inline bool has_avx2() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 5) && has_osxsave() && has_xcr_avx(); }
|
||||||
|
static inline bool has_vaes() { return has_feature(EXTENDED_FEATURES, ECX_Reg, 1 << 9); }
|
||||||
static inline bool has_avx512f() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 16) && has_osxsave() && has_xcr_avx512(); }
|
static inline bool has_avx512f() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 16) && has_osxsave() && has_xcr_avx512(); }
|
||||||
static inline bool has_bmi2() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 8); }
|
static inline bool has_bmi2() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 8); }
|
||||||
static inline bool has_pdpe1gb() { return has_feature(PROCESSOR_EXT_INFO, EDX_Reg, 1 << 26); }
|
static inline bool has_pdpe1gb() { return has_feature(PROCESSOR_EXT_INFO, EDX_Reg, 1 << 26); }
|
||||||
|
@ -178,6 +179,7 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||||
m_flags.set(FLAG_AES, has_aes_ni());
|
m_flags.set(FLAG_AES, has_aes_ni());
|
||||||
m_flags.set(FLAG_AVX, has_avx());
|
m_flags.set(FLAG_AVX, has_avx());
|
||||||
m_flags.set(FLAG_AVX2, has_avx2());
|
m_flags.set(FLAG_AVX2, has_avx2());
|
||||||
|
m_flags.set(FLAG_VAES, has_vaes());
|
||||||
m_flags.set(FLAG_AVX512F, has_avx512f());
|
m_flags.set(FLAG_AVX512F, has_avx512f());
|
||||||
m_flags.set(FLAG_BMI2, has_bmi2());
|
m_flags.set(FLAG_BMI2, has_bmi2());
|
||||||
m_flags.set(FLAG_OSXSAVE, has_osxsave());
|
m_flags.set(FLAG_OSXSAVE, has_osxsave());
|
||||||
|
|
|
@ -44,6 +44,7 @@ protected:
|
||||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||||
inline bool has(Flag flag) const override { return m_flags.test(flag); }
|
inline bool has(Flag flag) const override { return m_flags.test(flag); }
|
||||||
inline bool hasAES() const override { return has(FLAG_AES); }
|
inline bool hasAES() const override { return has(FLAG_AES); }
|
||||||
|
inline bool hasVAES() const override { return has(FLAG_VAES); }
|
||||||
inline bool hasAVX() const override { return has(FLAG_AVX); }
|
inline bool hasAVX() const override { return has(FLAG_AVX); }
|
||||||
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
|
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
|
||||||
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
|
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
static const char astrobwt_cl[12493] = {
|
static const char astrobwt_cl[12489] = {
|
||||||
0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,
|
0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,
|
||||||
0x73,0x68,0x6f,0x72,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x20,0x75,0x69,0x6e,
|
0x73,0x68,0x6f,0x72,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x20,0x75,0x69,0x6e,
|
||||||
0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,
|
0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,
|
||||||
|
@ -260,140 +260,140 @@ static const char astrobwt_cl[12493] = {
|
||||||
0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,
|
0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,
|
||||||
0x32,0x5f,0x74,0x29,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x28,0x28,0x34,0x2d,0x28,0x6f,0x75,0x74,0x70,0x75,
|
0x32,0x5f,0x74,0x29,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x28,0x28,0x34,0x2d,0x28,0x6f,0x75,0x74,0x70,0x75,
|
||||||
0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,
|
0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,
|
||||||
0x20,0x32,0x34,0x20,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x36,0x34,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x20,0x28,0x28,0x28,0x61,0x29,0x20,0x3c,0x3c,
|
0x20,0x32,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x36,0x34,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x20,0x28,0x28,0x28,0x61,0x29,0x20,0x3c,0x3c,0x20,
|
||||||
0x20,0x62,0x29,0x20,0x7c,0x20,0x28,0x28,0x61,0x29,0x20,0x3e,0x3e,0x20,0x63,0x29,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,
|
0x62,0x29,0x20,0x7c,0x20,0x28,0x28,0x61,0x29,0x20,0x3e,0x3e,0x20,0x63,0x29,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,
|
||||||
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x63,0x5b,0x32,0x5d,0x5b,0x52,0x4f,0x55,0x4e,0x44,0x53,0x5d,0x3d,0x7b,0x0a,0x7b,0x30,0x78,0x30,
|
0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x63,0x5b,0x32,0x5d,0x5b,0x52,0x4f,0x55,0x4e,0x44,0x53,0x5d,0x3d,0x7b,0x0a,0x7b,0x30,0x78,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
|
||||||
0x38,0x30,0x38,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
0x30,0x38,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
|
||||||
0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
|
||||||
0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,
|
0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,
|
||||||
0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,
|
0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
|
||||||
0x38,0x30,0x30,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,
|
0x30,0x30,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x7d,0x2c,0x0a,0x7b,0x30,
|
0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x7d,0x2c,0x0a,0x7b,0x30,0x55,
|
||||||
|
0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x0a,0x30,
|
||||||
0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x0a,
|
0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x0a,
|
||||||
0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,
|
0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x7d,
|
||||||
0x0a,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,
|
0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x5b,0x32,0x35,0x5d,0x5b,
|
||||||
0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x5b,0x32,0x35,0x5d,
|
0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x36,0x34,0x7d,0x2c,0x7b,0x34,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x34,0x33,0x2c,0x32,0x31,0x7d,0x2c,0x7b,0x32,0x31,
|
||||||
0x5b,0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x36,0x34,0x7d,0x2c,0x7b,0x34,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x34,0x33,0x2c,0x32,0x31,0x7d,0x2c,0x7b,0x32,
|
0x2c,0x34,0x33,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x35,0x30,0x7d,0x2c,0x0a,0x7b,0x20,0x31,0x2c,0x36,0x33,0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x35,0x38,0x7d,0x2c,0x7b,0x32,
|
||||||
0x31,0x2c,0x34,0x33,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x35,0x30,0x7d,0x2c,0x0a,0x7b,0x20,0x31,0x2c,0x36,0x33,0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x35,0x38,0x7d,0x2c,0x7b,
|
0x35,0x2c,0x33,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x35,0x36,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x34,0x36,0x7d,0x2c,0x0a,0x7b,0x36,0x32,0x2c,0x32,0x7d,0x2c,0x7b,0x35,
|
||||||
0x32,0x35,0x2c,0x33,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x35,0x36,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x34,0x36,0x7d,0x2c,0x0a,0x7b,0x36,0x32,0x2c,0x32,0x7d,0x2c,0x7b,
|
0x35,0x2c,0x39,0x7d,0x2c,0x7b,0x33,0x39,0x2c,0x32,0x35,0x7d,0x2c,0x7b,0x34,0x31,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x20,0x32,0x2c,0x36,0x32,0x7d,0x2c,0x0a,0x7b,0x32,
|
||||||
0x35,0x35,0x2c,0x39,0x7d,0x2c,0x7b,0x33,0x39,0x2c,0x32,0x35,0x7d,0x2c,0x7b,0x34,0x31,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x20,0x32,0x2c,0x36,0x32,0x7d,0x2c,0x0a,0x7b,
|
0x38,0x2c,0x33,0x36,0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x34,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x36,0x31,0x7d,0x2c,0x7b,0x34,0x35,0x2c,0x31,0x39,0x7d,0x2c,0x7b,0x36,
|
||||||
0x32,0x38,0x2c,0x33,0x36,0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x34,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x36,0x31,0x7d,0x2c,0x7b,0x34,0x35,0x2c,0x31,0x39,0x7d,0x2c,0x7b,
|
0x31,0x2c,0x33,0x7d,0x2c,0x0a,0x7b,0x32,0x37,0x2c,0x33,0x37,0x7d,0x2c,0x7b,0x33,0x36,0x2c,0x32,0x38,0x7d,0x2c,0x7b,0x31,0x30,0x2c,0x35,0x34,0x7d,0x2c,0x7b,0x31,
|
||||||
0x36,0x31,0x2c,0x33,0x7d,0x2c,0x0a,0x7b,0x32,0x37,0x2c,0x33,0x37,0x7d,0x2c,0x7b,0x33,0x36,0x2c,0x32,0x38,0x7d,0x2c,0x7b,0x31,0x30,0x2c,0x35,0x34,0x7d,0x2c,0x7b,
|
0x35,0x2c,0x34,0x39,0x7d,0x2c,0x7b,0x35,0x36,0x2c,0x38,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,
|
||||||
0x31,0x35,0x2c,0x34,0x39,0x7d,0x2c,0x7b,0x35,0x36,0x2c,0x38,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,
|
0x20,0x69,0x6e,0x74,0x20,0x61,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x36,0x2c,0x31,0x32,0x2c,0x31,0x38,0x2c,0x32,0x34,0x2c,0x0a,0x31,0x2c,0x37,0x2c,0x31,
|
||||||
0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x36,0x2c,0x31,0x32,0x2c,0x31,0x38,0x2c,0x32,0x34,0x2c,0x0a,0x31,0x2c,0x37,0x2c,
|
0x33,0x2c,0x31,0x39,0x2c,0x32,0x30,0x2c,0x0a,0x32,0x2c,0x38,0x2c,0x31,0x34,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x0a,0x33,0x2c,0x39,0x2c,0x31,0x30,0x2c,0x31,0x36,
|
||||||
0x31,0x33,0x2c,0x31,0x39,0x2c,0x32,0x30,0x2c,0x0a,0x32,0x2c,0x38,0x2c,0x31,0x34,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x0a,0x33,0x2c,0x39,0x2c,0x31,0x30,0x2c,0x31,
|
0x2c,0x32,0x32,0x2c,0x0a,0x34,0x2c,0x35,0x2c,0x31,0x31,0x2c,0x31,0x37,0x2c,0x32,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,
|
||||||
0x36,0x2c,0x32,0x32,0x2c,0x0a,0x34,0x2c,0x35,0x2c,0x31,0x31,0x2c,0x31,0x37,0x2c,0x32,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,
|
0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x2c,0x32,
|
||||||
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x2c,
|
0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x0a,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x0a,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x0a,0x34,0x2c,
|
||||||
0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x0a,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x0a,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x0a,0x34,
|
0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,
|
||||||
0x2c,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,
|
0x63,0x5b,0x32,0x35,0x5d,0x5b,0x33,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x31,0x2c,0x32,0x7d,0x2c,0x7b,0x20,0x31,0x2c,0x32,0x2c,0x33,0x7d,0x2c,0x7b,0x20,0x32,
|
||||||
0x20,0x63,0x5b,0x32,0x35,0x5d,0x5b,0x33,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x31,0x2c,0x32,0x7d,0x2c,0x7b,0x20,0x31,0x2c,0x32,0x2c,0x33,0x7d,0x2c,0x7b,0x20,
|
0x2c,0x33,0x2c,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x34,0x2c,0x30,0x7d,0x2c,0x7b,0x20,0x34,0x2c,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x20,0x35,0x2c,0x36,0x2c,0x37,
|
||||||
0x32,0x2c,0x33,0x2c,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x34,0x2c,0x30,0x7d,0x2c,0x7b,0x20,0x34,0x2c,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x20,0x35,0x2c,0x36,0x2c,
|
0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x37,0x2c,0x38,0x7d,0x2c,0x7b,0x20,0x37,0x2c,0x38,0x2c,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x39,0x2c,0x35,0x7d,0x2c,0x7b,0x20,0x39,
|
||||||
0x37,0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x37,0x2c,0x38,0x7d,0x2c,0x7b,0x20,0x37,0x2c,0x38,0x2c,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x39,0x2c,0x35,0x7d,0x2c,0x7b,0x20,
|
0x2c,0x35,0x2c,0x36,0x7d,0x2c,0x0a,0x7b,0x31,0x30,0x2c,0x31,0x31,0x2c,0x31,0x32,0x7d,0x2c,0x7b,0x31,0x31,0x2c,0x31,0x32,0x2c,0x31,0x33,0x7d,0x2c,0x7b,0x31,0x32,
|
||||||
0x39,0x2c,0x35,0x2c,0x36,0x7d,0x2c,0x0a,0x7b,0x31,0x30,0x2c,0x31,0x31,0x2c,0x31,0x32,0x7d,0x2c,0x7b,0x31,0x31,0x2c,0x31,0x32,0x2c,0x31,0x33,0x7d,0x2c,0x7b,0x31,
|
0x2c,0x31,0x33,0x2c,0x31,0x34,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x31,0x34,0x2c,0x31,0x30,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x31,0x30,0x2c,0x31,0x31,0x7d,0x2c,0x0a,0x7b,
|
||||||
0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x31,0x34,0x2c,0x31,0x30,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x31,0x30,0x2c,0x31,0x31,0x7d,0x2c,0x0a,
|
0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x7d,0x2c,0x7b,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x7d,0x2c,
|
||||||
0x7b,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x7d,0x2c,0x7b,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x7d,
|
0x7b,0x31,0x38,0x2c,0x31,0x39,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x31,0x39,0x2c,0x31,0x35,0x2c,0x31,0x36,0x7d,0x2c,0x0a,0x7b,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,0x32,
|
||||||
0x2c,0x7b,0x31,0x38,0x2c,0x31,0x39,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x31,0x39,0x2c,0x31,0x35,0x2c,0x31,0x36,0x7d,0x2c,0x0a,0x7b,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,
|
0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x7d,0x2c,0x7b,0x32,0x33,0x2c,0x32,0x34,0x2c,0x32,
|
||||||
0x32,0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x7d,0x2c,0x7b,0x32,0x33,0x2c,0x32,0x34,0x2c,
|
0x30,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x32,0x30,0x2c,0x32,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,
|
||||||
0x32,0x30,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x32,0x30,0x2c,0x32,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,
|
0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x30,0x2c,0x31,0x31,0x2c,0x31,
|
||||||
0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x30,0x2c,0x31,0x31,0x2c,
|
0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x2c,0x0a,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x2c,0x0a,0x35,0x2c,0x36,0x2c,0x37,0x2c,0x38,
|
||||||
0x31,0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x2c,0x0a,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x2c,0x0a,0x35,0x2c,0x36,0x2c,0x37,0x2c,
|
0x2c,0x39,0x2c,0x0a,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,
|
||||||
0x38,0x2c,0x39,0x2c,0x0a,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,
|
0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,
|
||||||
0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,
|
0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
|
||||||
0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,
|
||||||
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
|
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,
|
||||||
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,
|
0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,
|
||||||
0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,
|
0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,
|
||||||
0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,
|
0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,
|
||||||
0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,0x75,
|
||||||
0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,
|
0x72,0x6e,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
|
||||||
0x75,0x72,0x6e,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,
|
0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
|
||||||
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,
|
0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2a,0x67,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,
|
||||||
0x34,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2a,0x67,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,
|
0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,
|
||||||
0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,
|
0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x73,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
|
||||||
0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x73,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
|
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x5d,
|
||||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,
|
0x2b,0x31,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,
|
||||||
0x5d,0x2b,0x31,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,
|
0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
||||||
0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
|
0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||||
0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,
|
||||||
0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
|
0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,
|
||||||
0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,
|
0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x75,0x69,
|
||||||
0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x75,
|
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,
|
0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x77,0x6f,0x72,0x64,0x73,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x2b,0x2b,0x69,0x6e,0x70,0x75,0x74,0x29,0x0a,0x7b,0x0a,0x41,
|
||||||
0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x77,0x6f,0x72,0x64,0x73,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x2b,0x2b,0x69,0x6e,0x70,0x75,0x74,0x29,0x0a,0x7b,0x0a,
|
0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x2b,0x2b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,
|
||||||
0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x2b,0x2b,0x77,0x6f,0x72,0x64,0x49,0x6e,
|
0x65,0x78,0x3b,0x0a,0x69,0x66,0x28,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x3d,0x31,0x37,0x29,0x0a,0x7b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,
|
||||||
0x64,0x65,0x78,0x3b,0x0a,0x69,0x66,0x28,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x3d,0x31,0x37,0x29,0x0a,0x7b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,
|
0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,
|
||||||
0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,
|
0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,
|
||||||
0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,
|
0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,
|
||||||
0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,
|
0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,
|
||||||
0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,
|
0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,
|
||||||
0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,
|
0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,
|
||||||
0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,
|
0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,
|
||||||
0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,
|
0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,
|
||||||
0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,
|
0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
|
||||||
0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,
|
||||||
0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,
|
0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,
|
||||||
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
0x3d,0x30,0x3b,0x20,0x69,0x3c,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,0x61,0x69,0x6c,0x7c,0x3d,0x28,0x75,
|
||||||
0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,0x61,0x69,0x6c,0x7c,0x3d,
|
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x70,0x5b,0x69,0x5d,0x29,0x3c,0x3c,0x28,0x69,0x2a,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,
|
||||||
0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x70,0x5b,0x69,0x5d,0x29,0x3c,0x3c,0x28,0x69,0x2a,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x41,0x5b,0x77,0x6f,0x72,
|
0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x61,0x69,0x6c,0x5e,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,
|
||||||
0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x61,0x69,0x6c,0x5e,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,
|
0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,
|
||||||
0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,
|
0x38,0x29,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x65,0x2a,0x38,0x29,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,
|
||||||
0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,
|
0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,
|
||||||
0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,
|
0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,
|
||||||
0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,
|
0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,
|
||||||
0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,
|
0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,
|
||||||
0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,
|
0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,
|
||||||
0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,
|
0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,
|
||||||
0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,
|
0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,
|
||||||
0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,
|
0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
|
||||||
0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,
|
0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,
|
||||||
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,
|
0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,
|
||||||
0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,
|
0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x5f,0x69,0x6e,0x69,
|
||||||
0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x5f,
|
0x74,0x69,0x61,0x6c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,
|
||||||
0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,
|
0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,
|
||||||
0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,
|
0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,
|
||||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,
|
0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,
|
||||||
0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,
|
0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,
|
||||||
0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x3d,0x67,0x65,
|
0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x63,0x6f,
|
||||||
0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,
|
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
|
||||||
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
|
||||||
0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
|
||||||
0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,
|
||||||
0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,
|
0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x74,
|
||||||
0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,
|
0x3c,0x31,0x36,0x29,0x3f,0x69,0x6e,0x70,0x75,0x74,0x5b,0x74,0x5d,0x3a,0x30,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x3d,0x28,0x74,0x3c,0x31,0x36,0x29,0x3f,0x69,0x6e,0x70,0x75,0x74,0x5b,0x74,0x5d,0x3a,0x30,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
0x74,0x2a,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,
|
||||||
0x33,0x32,0x5f,0x74,0x2a,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
0x28,0x41,0x29,0x2b,0x39,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x3d,0x67,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,0x3d,0x28,0x6e,
|
||||||
0x74,0x2a,0x29,0x28,0x41,0x29,0x2b,0x39,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x3d,0x67,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,
|
0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x26,0x30,
|
||||||
0x3d,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x6e,0x6f,0x6e,0x63,
|
0x78,0x46,0x46,0x29,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x3d,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,
|
||||||
0x65,0x26,0x30,0x78,0x46,0x46,0x29,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x3d,0x28,0x6e,0x6f,0x6e,0x63,
|
0x6f,0x73,0x5b,0x31,0x5d,0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x29,0x7c,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x3e,0x3e,0x38,0x29,0x3b,0x0a,0x75,
|
||||||
0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x29,0x7c,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x3e,0x3e,0x38,0x29,
|
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,
|
||||||
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,
|
0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,
|
||||||
0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
|
||||||
0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,
|
0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,
|
||||||
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x28,0x75,0x69,0x6e,0x74,0x36,
|
0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,
|
||||||
0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,
|
0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,
|
0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,
|
||||||
0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,
|
0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,
|
||||||
0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,
|
0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,
|
||||||
0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,
|
0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,
|
||||||
0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,
|
0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,
|
||||||
0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,
|
0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,
|
||||||
0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,
|
0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,
|
||||||
0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,
|
0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,
|
||||||
0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,
|
0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,
|
||||||
0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,
|
0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
|
||||||
0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xmrig
|
} // namespace xmrig
|
||||||
|
|
|
@ -244,7 +244,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if (WITH_KAWPOW)
|
if (WITH_KAWPOW OR WITH_GHOSTRIDER)
|
||||||
list(APPEND HEADERS_BASE
|
list(APPEND HEADERS_BASE
|
||||||
src/base/net/stratum/AutoClient.h
|
src/base/net/stratum/AutoClient.h
|
||||||
src/base/net/stratum/EthStratumClient.h
|
src/base/net/stratum/EthStratumClient.h
|
||||||
|
|
|
@ -189,6 +189,7 @@ public:
|
||||||
inline Id id() const { return m_id; }
|
inline Id id() const { return m_id; }
|
||||||
inline size_t l2() const { return l2(m_id); }
|
inline size_t l2() const { return l2(m_id); }
|
||||||
inline uint32_t family() const { return family(m_id); }
|
inline uint32_t family() const { return family(m_id); }
|
||||||
|
inline uint32_t minIntensity() const { return ((m_id == GHOSTRIDER_RTM) ? 8 : 1); };
|
||||||
inline uint32_t maxIntensity() const { return isCN() ? 5 : ((m_id == GHOSTRIDER_RTM) ? 8 : 1); };
|
inline uint32_t maxIntensity() const { return isCN() ? 5 : ((m_id == GHOSTRIDER_RTM) ? 8 : 1); };
|
||||||
|
|
||||||
inline size_t l3() const
|
inline size_t l3() const
|
||||||
|
|
|
@ -213,12 +213,13 @@ void xmrig::EthStratumClient::parseNotification(const char *method, const rapidj
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arr[0].IsDouble()) {
|
if (!arr[0].IsDouble() && !arr[0].IsUint64()) {
|
||||||
LOG_ERR("%s " RED("invalid mining.set_difficulty notification: difficulty is not a number"), tag());
|
LOG_ERR("%s " RED("invalid mining.set_difficulty notification: difficulty is not a number"), tag());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nextDifficulty = static_cast<uint64_t>(ceil(arr[0].GetDouble() * 65536.0));
|
const double diff = arr[0].IsDouble() ? arr[0].GetDouble() : arr[0].GetUint64();
|
||||||
|
m_nextDifficulty = static_cast<uint64_t>(ceil(diff * 65536.0));
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "base/kernel/Platform.h"
|
#include "base/kernel/Platform.h"
|
||||||
#include "base/net/stratum/Client.h"
|
#include "base/net/stratum/Client.h"
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_KAWPOW
|
#if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER
|
||||||
# include "base/net/stratum/AutoClient.h"
|
# include "base/net/stratum/AutoClient.h"
|
||||||
# include "base/net/stratum/EthStratumClient.h"
|
# include "base/net/stratum/EthStratumClient.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -218,7 +218,7 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
|
||||||
IClient *client = nullptr;
|
IClient *client = nullptr;
|
||||||
|
|
||||||
if (m_mode == MODE_POOL) {
|
if (m_mode == MODE_POOL) {
|
||||||
# ifdef XMRIG_ALGO_KAWPOW
|
# if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER
|
||||||
const uint32_t f = m_algorithm.family();
|
const uint32_t f = m_algorithm.family();
|
||||||
if ((f == Algorithm::KAWPOW) || (f == Algorithm::GHOSTRIDER) || (m_coin == Coin::RAVEN)) {
|
if ((f == Algorithm::KAWPOW) || (f == Algorithm::GHOSTRIDER) || (m_coin == Coin::RAVEN)) {
|
||||||
client = new EthStratumClient(id, Platform::userAgent(), listener);
|
client = new EthStratumClient(id, Platform::userAgent(), listener);
|
||||||
|
@ -237,7 +237,7 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
|
||||||
client = new SelfSelectClient(id, Platform::userAgent(), listener, m_submitToOrigin);
|
client = new SelfSelectClient(id, Platform::userAgent(), listener, m_submitToOrigin);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
# ifdef XMRIG_ALGO_KAWPOW
|
# if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER
|
||||||
else if (m_mode == MODE_AUTO_ETH) {
|
else if (m_mode == MODE_AUTO_ETH) {
|
||||||
client = new AutoClient(id, Platform::userAgent(), listener);
|
client = new AutoClient(id, Platform::userAgent(), listener);
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,10 +287,12 @@ public:
|
||||||
|
|
||||||
void printHashrate(bool details)
|
void printHashrate(bool details)
|
||||||
{
|
{
|
||||||
char num[16 * 4] = { 0 };
|
char num[16 * 5] = { 0 };
|
||||||
double speed[3] = { 0.0 };
|
double speed[3] = { 0.0 };
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
|
||||||
|
double avg_hashrate = 0.0;
|
||||||
|
|
||||||
for (auto backend : backends) {
|
for (auto backend : backends) {
|
||||||
const auto hashrate = backend->hashrate();
|
const auto hashrate = backend->hashrate();
|
||||||
if (hashrate) {
|
if (hashrate) {
|
||||||
|
@ -299,6 +301,8 @@ public:
|
||||||
speed[0] += hashrate->calc(Hashrate::ShortInterval);
|
speed[0] += hashrate->calc(Hashrate::ShortInterval);
|
||||||
speed[1] += hashrate->calc(Hashrate::MediumInterval);
|
speed[1] += hashrate->calc(Hashrate::MediumInterval);
|
||||||
speed[2] += hashrate->calc(Hashrate::LargeInterval);
|
speed[2] += hashrate->calc(Hashrate::LargeInterval);
|
||||||
|
|
||||||
|
avg_hashrate += hashrate->average();
|
||||||
}
|
}
|
||||||
|
|
||||||
backend->printHashrate(details);
|
backend->printHashrate(details);
|
||||||
|
@ -318,12 +322,22 @@ public:
|
||||||
h = "MH/s";
|
h = "MH/s";
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("%s " WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("%s") " max " CYAN_BOLD("%s %s"),
|
char avg_hashrate_buf[64];
|
||||||
|
avg_hashrate_buf[0] = '\0';
|
||||||
|
|
||||||
|
# ifdef XMRIG_ALGO_GHOSTRIDER
|
||||||
|
if (algorithm.family() == Algorithm::GHOSTRIDER) {
|
||||||
|
snprintf(avg_hashrate_buf, sizeof(avg_hashrate_buf), " avg " CYAN_BOLD("%s %s"), Hashrate::format(avg_hashrate * scale, num + 16 * 4, 16), h);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
LOG_INFO("%s " WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("%s") " max " CYAN_BOLD("%s %s") "%s",
|
||||||
Tags::miner(),
|
Tags::miner(),
|
||||||
Hashrate::format(speed[0] * scale, num, sizeof(num) / 4),
|
Hashrate::format(speed[0] * scale, num, 16),
|
||||||
Hashrate::format(speed[1] * scale, num + 16, sizeof(num) / 4),
|
Hashrate::format(speed[1] * scale, num + 16, 16),
|
||||||
Hashrate::format(speed[2] * scale, num + 16 * 2, sizeof(num) / 4), h,
|
Hashrate::format(speed[2] * scale, num + 16 * 2, 16), h,
|
||||||
Hashrate::format(maxHashrate[algorithm] * scale, num + 16 * 3, sizeof(num) / 4), h
|
Hashrate::format(maxHashrate[algorithm] * scale, num + 16 * 3, 16), h,
|
||||||
|
avg_hashrate_buf
|
||||||
);
|
);
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||||
|
|
|
@ -348,7 +348,7 @@ xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av,
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_CN_HEAVY
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
// cn-heavy optimization for Zen3 CPUs
|
// cn-heavy optimization for Zen3 CPUs
|
||||||
if ((av == AV_SINGLE) && (assembly != Assembly::NONE) && (Cpu::info()->arch() == ICpuInfo::ARCH_ZEN3)) {
|
if ((av == AV_SINGLE) && (assembly != Assembly::NONE) && (Cpu::info()->arch() == ICpuInfo::ARCH_ZEN3) && (Cpu::info()->model() == 0x21)) {
|
||||||
switch (algorithm.id()) {
|
switch (algorithm.id()) {
|
||||||
case Algorithm::CN_HEAVY_0:
|
case Algorithm::CN_HEAVY_0:
|
||||||
return cryptonight_single_hash<Algorithm::CN_HEAVY_0, false, 3>;
|
return cryptonight_single_hash<Algorithm::CN_HEAVY_0, false, 3>;
|
||||||
|
|
|
@ -450,6 +450,29 @@ const static uint8_t astrobwt_dero_test_out[256] = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_ALGO_GHOSTRIDER
|
||||||
|
// "GhostRider"
|
||||||
|
const static uint8_t test_output_gr[256] = {
|
||||||
|
0x42, 0x17, 0x0C, 0xC1, 0x85, 0xE6, 0x76, 0x3C, 0xC7, 0xCB, 0x27, 0xC4, 0x17, 0x39, 0x2D, 0xE2,
|
||||||
|
0x29, 0x6B, 0x40, 0x66, 0x85, 0xA4, 0xE3, 0xD3, 0x8C, 0xE9, 0xA5, 0x8F, 0x10, 0xFC, 0x81, 0xE4,
|
||||||
|
0x90, 0x56, 0xF2, 0x9E, 0x00, 0xD0, 0xF8, 0xA1, 0x88, 0x82, 0x86, 0xC0, 0x86, 0x04, 0x6B, 0x0E,
|
||||||
|
0x9A, 0xDB, 0xDB, 0xFD, 0x23, 0x16, 0x77, 0x94, 0xFE, 0x58, 0x93, 0x05, 0x10, 0x3F, 0x27, 0x75,
|
||||||
|
0x51, 0x44, 0xF3, 0x5F, 0xE2, 0xF9, 0x61, 0xBE, 0xC0, 0x30, 0xB5, 0x8E, 0xB1, 0x1B, 0xA1, 0xF7,
|
||||||
|
0x06, 0x4E, 0xF1, 0x6A, 0xFD, 0xA5, 0x44, 0x8E, 0x64, 0x47, 0x8C, 0x67, 0x51, 0xE2, 0x5C, 0x55,
|
||||||
|
0x3E, 0x39, 0xA6, 0xA5, 0xF7, 0xB8, 0xD0, 0x5E, 0xE2, 0xBF, 0x92, 0x44, 0xD9, 0xAA, 0x76, 0x22,
|
||||||
|
0xE3, 0x3E, 0x15, 0x96, 0xD8, 0x6A, 0x78, 0x2D, 0xA9, 0x77, 0x24, 0x1A, 0x4B, 0xE7, 0x5A, 0x2E,
|
||||||
|
0x89, 0x77, 0xAE, 0x92, 0xE4, 0xA4, 0x2D, 0xAF, 0x0B, 0x27, 0x09, 0xB2, 0x5F, 0x95, 0x61, 0xA9,
|
||||||
|
0xA8, 0xBE, 0x5D, 0x39, 0xBE, 0x41, 0x5F, 0x9C, 0x67, 0x28, 0x48, 0x4F, 0xAE, 0x2A, 0x50, 0x2B,
|
||||||
|
0xB8, 0xC7, 0x42, 0x73, 0x51, 0x60, 0x59, 0xD8, 0x9C, 0xBA, 0x22, 0x2F, 0x8E, 0x34, 0xDE, 0xC8,
|
||||||
|
0x1B, 0xAE, 0x9E, 0xBD, 0xF7, 0xE8, 0xFD, 0x8A, 0x97, 0xBE, 0xF0, 0x47, 0xAC, 0x27, 0xDD, 0x28,
|
||||||
|
0xC9, 0x28, 0xA8, 0x7B, 0x2A, 0xB8, 0x90, 0x3E, 0xCA, 0xB4, 0x78, 0x44, 0xCE, 0xCD, 0x91, 0xEC,
|
||||||
|
0xC2, 0x5A, 0x17, 0x59, 0x7C, 0x14, 0xF8, 0x95, 0x28, 0x14, 0xC3, 0xAD, 0xC4, 0xE1, 0x13, 0x5A,
|
||||||
|
0xC4, 0xA7, 0xC7, 0x77, 0xAD, 0xF8, 0x09, 0x61, 0x16, 0xBB, 0xAA, 0x7E, 0xAB, 0xC3, 0x00, 0x25,
|
||||||
|
0xBA, 0xA8, 0x97, 0xC7, 0x7D, 0x38, 0x46, 0x0E, 0x59, 0xAC, 0xCB, 0xAE, 0xFE, 0x3C, 0x6F, 0x01
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
} // namespace xmrig
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,11 @@
|
||||||
#include "crypto/cn/soft_aes.h"
|
#include "crypto/cn/soft_aes.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_VAES
|
||||||
|
# include "crypto/cn/CryptoNight_x86_vaes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "crypto/cn/c_groestl.h"
|
#include "crypto/cn/c_groestl.h"
|
||||||
|
@ -289,6 +294,13 @@ static NOINLINE void cn_explode_scratchpad(cryptonight_ctx *ctx)
|
||||||
{
|
{
|
||||||
constexpr CnAlgo<ALGO> props;
|
constexpr CnAlgo<ALGO> props;
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_explode_scratchpad_vaes<ALGO>(ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
constexpr size_t N = (props.memory() / sizeof(__m128i)) / (props.half_mem() ? 2 : 1);
|
constexpr size_t N = (props.memory() / sizeof(__m128i)) / (props.half_mem() ? 2 : 1);
|
||||||
|
|
||||||
__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
|
__m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
|
||||||
|
@ -341,7 +353,7 @@ static NOINLINE void cn_explode_scratchpad(cryptonight_ctx *ctx)
|
||||||
constexpr int output_increment = (64 << interleave) / sizeof(__m128i);
|
constexpr int output_increment = (64 << interleave) / sizeof(__m128i);
|
||||||
constexpr int prefetch_dist = 2048 / sizeof(__m128i);
|
constexpr int prefetch_dist = 2048 / sizeof(__m128i);
|
||||||
|
|
||||||
__m128i* e = output + N - prefetch_dist;
|
__m128i* e = output + (N << interleave) - prefetch_dist;
|
||||||
__m128i* prefetch_ptr = output + prefetch_dist;
|
__m128i* prefetch_ptr = output + prefetch_dist;
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
@ -396,6 +408,13 @@ static NOINLINE void cn_implode_scratchpad(cryptonight_ctx *ctx)
|
||||||
{
|
{
|
||||||
constexpr CnAlgo<ALGO> props;
|
constexpr CnAlgo<ALGO> props;
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_implode_scratchpad_vaes<ALGO>(ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
constexpr bool IS_HEAVY = props.isHeavy();
|
constexpr bool IS_HEAVY = props.isHeavy();
|
||||||
constexpr size_t N = (props.memory() / sizeof(__m128i)) / (props.half_mem() ? 2 : 1);
|
constexpr size_t N = (props.memory() / sizeof(__m128i)) / (props.half_mem() ? 2 : 1);
|
||||||
|
|
||||||
|
@ -996,8 +1015,17 @@ inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_
|
||||||
ctx[0]->first_half = true;
|
ctx[0]->first_half = true;
|
||||||
ctx[1]->first_half = true;
|
ctx[1]->first_half = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
cn_explode_scratchpad<ALGO, false, 0>(ctx[0]);
|
cn_explode_scratchpad<ALGO, false, 0>(ctx[0]);
|
||||||
cn_explode_scratchpad<ALGO, false, 0>(ctx[1]);
|
cn_explode_scratchpad<ALGO, false, 0>(ctx[1]);
|
||||||
|
}
|
||||||
|
|
||||||
if (ALGO == Algorithm::CN_2) {
|
if (ALGO == Algorithm::CN_2) {
|
||||||
cnv2_double_mainloop_sandybridge_asm(ctx);
|
cnv2_double_mainloop_sandybridge_asm(ctx);
|
||||||
|
@ -1036,8 +1064,16 @@ inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_
|
||||||
ctx[0]->generated_code(ctx);
|
ctx[0]->generated_code(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_implode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
cn_implode_scratchpad<ALGO, false, 0>(ctx[0]);
|
cn_implode_scratchpad<ALGO, false, 0>(ctx[0]);
|
||||||
cn_implode_scratchpad<ALGO, false, 0>(ctx[1]);
|
cn_implode_scratchpad<ALGO, false, 0>(ctx[1]);
|
||||||
|
}
|
||||||
|
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[1]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[1]->state), 24);
|
||||||
|
@ -1092,8 +1128,17 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
||||||
ctx[0]->first_half = true;
|
ctx[0]->first_half = true;
|
||||||
ctx[1]->first_half = true;
|
ctx[1]->first_half = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t al0 = h0[0] ^ h0[4];
|
uint64_t al0 = h0[0] ^ h0[4];
|
||||||
uint64_t al1 = h1[0] ^ h1[4];
|
uint64_t al1 = h1[0] ^ h1[4];
|
||||||
|
@ -1288,8 +1333,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
||||||
bx10 = cx1;
|
bx10 = cx1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_implode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
||||||
|
}
|
||||||
|
|
||||||
keccakf(h0, 24);
|
keccakf(h0, 24);
|
||||||
keccakf(h1, 24);
|
keccakf(h1, 24);
|
||||||
|
@ -1350,10 +1403,19 @@ void cryptonight_quad_hash_zen(const uint8_t* __restrict__ input, size_t size, u
|
||||||
ctx[3]->first_half = true;
|
ctx[3]->first_half = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(ctx[2], ctx[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[2]);
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[2]);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[3]);
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[3]);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t al0 = h0[0] ^ h0[4];
|
uint64_t al0 = h0[0] ^ h0[4];
|
||||||
uint64_t al1 = h1[0] ^ h1[4];
|
uint64_t al1 = h1[0] ^ h1[4];
|
||||||
|
@ -1474,10 +1536,19 @@ void cryptonight_quad_hash_zen(const uint8_t* __restrict__ input, size_t size, u
|
||||||
if (!SOFT_AES) cx3 = _mm_load_si128(reinterpret_cast<const __m128i*>(&l3[idx3 & MASK]));
|
if (!SOFT_AES) cx3 = _mm_load_si128(reinterpret_cast<const __m128i*>(&l3[idx3 & MASK]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_implode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
cn_implode_scratchpad_vaes_double<ALGO>(ctx[2], ctx[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[2]);
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[2]);
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[3]);
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[3]);
|
||||||
|
}
|
||||||
|
|
||||||
keccakf(h0, 24);
|
keccakf(h0, 24);
|
||||||
keccakf(h1, 24);
|
keccakf(h1, 24);
|
||||||
|
@ -1714,7 +1785,20 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size
|
||||||
if (props.half_mem()) {
|
if (props.half_mem()) {
|
||||||
ctx[i]->first_half = true;
|
ctx[i]->first_half = true;
|
||||||
}
|
}
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[i]);
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(ctx[2], ctx[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
||||||
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
||||||
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[2]);
|
||||||
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(ctx[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* l0 = ctx[0]->memory;
|
uint8_t* l0 = ctx[0]->memory;
|
||||||
|
@ -1766,8 +1850,21 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size
|
||||||
CN_STEP4(3, ax3, bx30, bx31, cx3, l3, mc3, ptr3, idx3);
|
CN_STEP4(3, ax3, bx30, bx31, cx3, l3, mc3, ptr3, idx3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_VAES
|
||||||
|
if (!SOFT_AES && !props.isHeavy() && Cpu::info()->hasVAES()) {
|
||||||
|
cn_implode_scratchpad_vaes_double<ALGO>(ctx[0], ctx[1]);
|
||||||
|
cn_implode_scratchpad_vaes_double<ALGO>(ctx[2], ctx[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[0]);
|
||||||
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[1]);
|
||||||
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[2]);
|
||||||
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[3]);
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(ctx[i]);
|
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||||
}
|
}
|
||||||
|
|
530
src/crypto/cn/CryptoNight_x86_vaes.cpp
Normal file
530
src/crypto/cn/CryptoNight_x86_vaes.cpp
Normal file
|
@ -0,0 +1,530 @@
|
||||||
|
/* 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 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||||
|
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2020 XMRig <https://github.com/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 "CryptoNight_x86_vaes.h"
|
||||||
|
#include "CryptoNight_monero.h"
|
||||||
|
#include "CryptoNight.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# include <x86intrin.h>
|
||||||
|
#if !defined(__clang__) && !defined(__ICC) && __GNUC__ < 10
|
||||||
|
static inline __m256i
|
||||||
|
__attribute__((__always_inline__))
|
||||||
|
_mm256_loadu2_m128i(const __m128i* const hiaddr, const __m128i* const loaddr)
|
||||||
|
{
|
||||||
|
return _mm256_inserti128_si256(
|
||||||
|
_mm256_castsi128_si256(_mm_loadu_si128(loaddr)), _mm_loadu_si128(hiaddr), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__attribute__((__always_inline__))
|
||||||
|
_mm256_storeu2_m128i(__m128i* const hiaddr, __m128i* const loaddr, const __m256i a)
|
||||||
|
{
|
||||||
|
_mm_storeu_si128(loaddr, _mm256_castsi256_si128(a));
|
||||||
|
_mm_storeu_si128(hiaddr, _mm256_extracti128_si256(a, 1));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
# include <intrin.h>
|
||||||
|
#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 FORCEINLINE __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 FORCEINLINE 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NOINLINE void vaes_genkey(const __m128i* memory, __m256i* k0, __m256i* k1, __m256i* k2, __m256i* k3, __m256i* k4, __m256i* k5, __m256i* k6, __m256i* k7, __m256i* k8, __m256i* k9)
|
||||||
|
{
|
||||||
|
__m128i xout0 = _mm_load_si128(memory);
|
||||||
|
__m128i xout2 = _mm_load_si128(memory + 1);
|
||||||
|
*k0 = _mm256_set_m128i(xout0, xout0);
|
||||||
|
*k1 = _mm256_set_m128i(xout2, xout2);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x01>(&xout0, &xout2);
|
||||||
|
*k2 = _mm256_set_m128i(xout0, xout0);
|
||||||
|
*k3 = _mm256_set_m128i(xout2, xout2);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x02>(&xout0, &xout2);
|
||||||
|
*k4 = _mm256_set_m128i(xout0, xout0);
|
||||||
|
*k5 = _mm256_set_m128i(xout2, xout2);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x04>(&xout0, &xout2);
|
||||||
|
*k6 = _mm256_set_m128i(xout0, xout0);
|
||||||
|
*k7 = _mm256_set_m128i(xout2, xout2);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x08>(&xout0, &xout2);
|
||||||
|
*k8 = _mm256_set_m128i(xout0, xout0);
|
||||||
|
*k9 = _mm256_set_m128i(xout2, xout2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NOINLINE void vaes_genkey_double(const __m128i* memory1, const __m128i* memory2, __m256i* k0, __m256i* k1, __m256i* k2, __m256i* k3, __m256i* k4, __m256i* k5, __m256i* k6, __m256i* k7, __m256i* k8, __m256i* k9)
|
||||||
|
{
|
||||||
|
__m128i xout0 = _mm_load_si128(memory1);
|
||||||
|
__m128i xout1 = _mm_load_si128(memory1 + 1);
|
||||||
|
__m128i xout2 = _mm_load_si128(memory2);
|
||||||
|
__m128i xout3 = _mm_load_si128(memory2 + 1);
|
||||||
|
*k0 = _mm256_set_m128i(xout2, xout0);
|
||||||
|
*k1 = _mm256_set_m128i(xout3, xout1);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x01>(&xout0, &xout1);
|
||||||
|
aes_genkey_sub<0x01>(&xout2, &xout3);
|
||||||
|
*k2 = _mm256_set_m128i(xout2, xout0);
|
||||||
|
*k3 = _mm256_set_m128i(xout3, xout1);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x02>(&xout0, &xout1);
|
||||||
|
aes_genkey_sub<0x02>(&xout2, &xout3);
|
||||||
|
*k4 = _mm256_set_m128i(xout2, xout0);
|
||||||
|
*k5 = _mm256_set_m128i(xout3, xout1);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x04>(&xout0, &xout1);
|
||||||
|
aes_genkey_sub<0x04>(&xout2, &xout3);
|
||||||
|
*k6 = _mm256_set_m128i(xout2, xout0);
|
||||||
|
*k7 = _mm256_set_m128i(xout3, xout1);
|
||||||
|
|
||||||
|
aes_genkey_sub<0x08>(&xout0, &xout1);
|
||||||
|
aes_genkey_sub<0x08>(&xout2, &xout3);
|
||||||
|
*k8 = _mm256_set_m128i(xout2, xout0);
|
||||||
|
*k9 = _mm256_set_m128i(xout3, xout1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FORCEINLINE void vaes_round(__m256i key, __m256i& x01, __m256i& x23, __m256i& x45, __m256i& x67)
|
||||||
|
{
|
||||||
|
x01 = _mm256_aesenc_epi128(x01, key);
|
||||||
|
x23 = _mm256_aesenc_epi128(x23, key);
|
||||||
|
x45 = _mm256_aesenc_epi128(x45, key);
|
||||||
|
x67 = _mm256_aesenc_epi128(x67, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FORCEINLINE void vaes_round(__m256i key, __m256i& x0, __m256i& x1, __m256i& x2, __m256i& x3, __m256i& x4, __m256i& x5, __m256i& x6, __m256i& x7)
|
||||||
|
{
|
||||||
|
x0 = _mm256_aesenc_epi128(x0, key);
|
||||||
|
x1 = _mm256_aesenc_epi128(x1, key);
|
||||||
|
x2 = _mm256_aesenc_epi128(x2, key);
|
||||||
|
x3 = _mm256_aesenc_epi128(x3, key);
|
||||||
|
x4 = _mm256_aesenc_epi128(x4, key);
|
||||||
|
x5 = _mm256_aesenc_epi128(x5, key);
|
||||||
|
x6 = _mm256_aesenc_epi128(x6, key);
|
||||||
|
x7 = _mm256_aesenc_epi128(x7, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Id ALGO>
|
||||||
|
NOINLINE void cn_explode_scratchpad_vaes(cryptonight_ctx* ctx)
|
||||||
|
{
|
||||||
|
constexpr CnAlgo<ALGO> props;
|
||||||
|
|
||||||
|
constexpr size_t N = (props.memory() / sizeof(__m256i)) / (props.half_mem() ? 2 : 1);
|
||||||
|
|
||||||
|
__m256i xin01, xin23, xin45, xin67;
|
||||||
|
__m256i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
|
||||||
|
|
||||||
|
const __m128i* input = reinterpret_cast<const __m128i*>(ctx->state);
|
||||||
|
__m256i* output = reinterpret_cast<__m256i*>(ctx->memory);
|
||||||
|
|
||||||
|
vaes_genkey(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
|
||||||
|
|
||||||
|
if (props.half_mem() && !ctx->first_half) {
|
||||||
|
const __m256i* p = reinterpret_cast<const __m256i*>(ctx->save_state);
|
||||||
|
xin01 = _mm256_load_si256(p + 0);
|
||||||
|
xin23 = _mm256_load_si256(p + 1);
|
||||||
|
xin45 = _mm256_load_si256(p + 2);
|
||||||
|
xin67 = _mm256_load_si256(p + 3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xin01 = _mm256_load_si256(reinterpret_cast<const __m256i*>(input + 4));
|
||||||
|
xin23 = _mm256_load_si256(reinterpret_cast<const __m256i*>(input + 6));
|
||||||
|
xin45 = _mm256_load_si256(reinterpret_cast<const __m256i*>(input + 8));
|
||||||
|
xin67 = _mm256_load_si256(reinterpret_cast<const __m256i*>(input + 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int output_increment = 64 / sizeof(__m256i);
|
||||||
|
constexpr int prefetch_dist = 2048 / sizeof(__m256i);
|
||||||
|
|
||||||
|
__m256i* e = output + N - prefetch_dist;
|
||||||
|
__m256i* prefetch_ptr = output + prefetch_dist;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
do {
|
||||||
|
_mm_prefetch((const char*)(prefetch_ptr), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(prefetch_ptr + output_increment), _MM_HINT_T0);
|
||||||
|
|
||||||
|
vaes_round(k0, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k1, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k2, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k3, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k4, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k5, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k6, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k7, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k8, xin01, xin23, xin45, xin67);
|
||||||
|
vaes_round(k9, xin01, xin23, xin45, xin67);
|
||||||
|
|
||||||
|
_mm256_store_si256(output + 0, xin01);
|
||||||
|
_mm256_store_si256(output + 1, xin23);
|
||||||
|
|
||||||
|
_mm256_store_si256(output + output_increment + 0, xin45);
|
||||||
|
_mm256_store_si256(output + output_increment + 1, xin67);
|
||||||
|
|
||||||
|
output += output_increment * 2;
|
||||||
|
prefetch_ptr += output_increment * 2;
|
||||||
|
} while (output < e);
|
||||||
|
e += prefetch_dist;
|
||||||
|
prefetch_ptr = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.half_mem() && ctx->first_half) {
|
||||||
|
__m256i* p = reinterpret_cast<__m256i*>(ctx->save_state);
|
||||||
|
_mm256_store_si256(p + 0, xin01);
|
||||||
|
_mm256_store_si256(p + 1, xin23);
|
||||||
|
_mm256_store_si256(p + 2, xin45);
|
||||||
|
_mm256_store_si256(p + 3, xin67);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mm256_zeroupper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Id ALGO>
|
||||||
|
NOINLINE void cn_explode_scratchpad_vaes_double(cryptonight_ctx* ctx1, cryptonight_ctx* ctx2)
|
||||||
|
{
|
||||||
|
constexpr CnAlgo<ALGO> props;
|
||||||
|
|
||||||
|
constexpr size_t N = (props.memory() / sizeof(__m128i)) / (props.half_mem() ? 2 : 1);
|
||||||
|
|
||||||
|
__m256i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;
|
||||||
|
__m256i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
|
||||||
|
|
||||||
|
const __m128i* input1 = reinterpret_cast<const __m128i*>(ctx1->state);
|
||||||
|
const __m128i* input2 = reinterpret_cast<const __m128i*>(ctx2->state);
|
||||||
|
|
||||||
|
__m128i* output1 = reinterpret_cast<__m128i*>(ctx1->memory);
|
||||||
|
__m128i* output2 = reinterpret_cast<__m128i*>(ctx2->memory);
|
||||||
|
|
||||||
|
vaes_genkey_double(input1, input2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
|
||||||
|
|
||||||
|
{
|
||||||
|
const bool b = props.half_mem() && !ctx1->first_half && !ctx2->first_half;
|
||||||
|
const __m128i* p1 = b ? reinterpret_cast<const __m128i*>(ctx1->save_state) : (input1 + 4);
|
||||||
|
const __m128i* p2 = b ? reinterpret_cast<const __m128i*>(ctx2->save_state) : (input2 + 4);
|
||||||
|
xin0 = _mm256_loadu2_m128i(p2 + 0, p1 + 0);
|
||||||
|
xin1 = _mm256_loadu2_m128i(p2 + 1, p1 + 1);
|
||||||
|
xin2 = _mm256_loadu2_m128i(p2 + 2, p1 + 2);
|
||||||
|
xin3 = _mm256_loadu2_m128i(p2 + 3, p1 + 3);
|
||||||
|
xin4 = _mm256_loadu2_m128i(p2 + 4, p1 + 4);
|
||||||
|
xin5 = _mm256_loadu2_m128i(p2 + 5, p1 + 5);
|
||||||
|
xin6 = _mm256_loadu2_m128i(p2 + 6, p1 + 6);
|
||||||
|
xin7 = _mm256_loadu2_m128i(p2 + 7, p1 + 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int output_increment = 64 / sizeof(__m128i);
|
||||||
|
constexpr int prefetch_dist = 2048 / sizeof(__m128i);
|
||||||
|
|
||||||
|
__m128i* e = output1 + N - prefetch_dist;
|
||||||
|
__m128i* prefetch_ptr1 = output1 + prefetch_dist;
|
||||||
|
__m128i* prefetch_ptr2 = output2 + prefetch_dist;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
do {
|
||||||
|
_mm_prefetch((const char*)(prefetch_ptr1), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(prefetch_ptr1 + output_increment), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(prefetch_ptr2), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(prefetch_ptr2 + output_increment), _MM_HINT_T0);
|
||||||
|
|
||||||
|
vaes_round(k0, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k1, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k2, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k3, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k4, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k5, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k6, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k7, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k8, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
vaes_round(k9, xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||||
|
|
||||||
|
_mm256_storeu2_m128i(output2 + 0, output1 + 0, xin0);
|
||||||
|
_mm256_storeu2_m128i(output2 + 1, output1 + 1, xin1);
|
||||||
|
_mm256_storeu2_m128i(output2 + 2, output1 + 2, xin2);
|
||||||
|
_mm256_storeu2_m128i(output2 + 3, output1 + 3, xin3);
|
||||||
|
|
||||||
|
_mm256_storeu2_m128i(output2 + output_increment + 0, output1 + output_increment + 0, xin4);
|
||||||
|
_mm256_storeu2_m128i(output2 + output_increment + 1, output1 + output_increment + 1, xin5);
|
||||||
|
_mm256_storeu2_m128i(output2 + output_increment + 2, output1 + output_increment + 2, xin6);
|
||||||
|
_mm256_storeu2_m128i(output2 + output_increment + 3, output1 + output_increment + 3, xin7);
|
||||||
|
|
||||||
|
output1 += output_increment * 2;
|
||||||
|
prefetch_ptr1 += output_increment * 2;
|
||||||
|
output2 += output_increment * 2;
|
||||||
|
prefetch_ptr2 += output_increment * 2;
|
||||||
|
} while (output1 < e);
|
||||||
|
e += prefetch_dist;
|
||||||
|
prefetch_ptr1 = output1;
|
||||||
|
prefetch_ptr2 = output2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.half_mem() && ctx1->first_half && ctx2->first_half) {
|
||||||
|
__m128i* p1 = reinterpret_cast<__m128i*>(ctx1->save_state);
|
||||||
|
__m128i* p2 = reinterpret_cast<__m128i*>(ctx2->save_state);
|
||||||
|
_mm256_storeu2_m128i(p2 + 0, p1 + 0, xin0);
|
||||||
|
_mm256_storeu2_m128i(p2 + 1, p1 + 1, xin1);
|
||||||
|
_mm256_storeu2_m128i(p2 + 2, p1 + 2, xin2);
|
||||||
|
_mm256_storeu2_m128i(p2 + 3, p1 + 3, xin3);
|
||||||
|
_mm256_storeu2_m128i(p2 + 4, p1 + 4, xin4);
|
||||||
|
_mm256_storeu2_m128i(p2 + 5, p1 + 5, xin5);
|
||||||
|
_mm256_storeu2_m128i(p2 + 6, p1 + 6, xin6);
|
||||||
|
_mm256_storeu2_m128i(p2 + 7, p1 + 7, xin7);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mm256_zeroupper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Id ALGO>
|
||||||
|
NOINLINE void cn_implode_scratchpad_vaes(cryptonight_ctx* ctx)
|
||||||
|
{
|
||||||
|
constexpr CnAlgo<ALGO> props;
|
||||||
|
|
||||||
|
constexpr size_t N = (props.memory() / sizeof(__m256i)) / (props.half_mem() ? 2 : 1);
|
||||||
|
|
||||||
|
__m256i xout01, xout23, xout45, xout67;
|
||||||
|
__m256i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
|
||||||
|
|
||||||
|
const __m256i* input = reinterpret_cast<const __m256i*>(ctx->memory);
|
||||||
|
__m256i* output = reinterpret_cast<__m256i*>(ctx->state);
|
||||||
|
|
||||||
|
vaes_genkey(reinterpret_cast<__m128i*>(output) + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
|
||||||
|
|
||||||
|
xout01 = _mm256_load_si256(output + 2);
|
||||||
|
xout23 = _mm256_load_si256(output + 3);
|
||||||
|
xout45 = _mm256_load_si256(output + 4);
|
||||||
|
xout67 = _mm256_load_si256(output + 5);
|
||||||
|
|
||||||
|
const __m256i* input_begin = input;
|
||||||
|
for (size_t part = 0; part < (props.half_mem() ? 2 : 1); ++part) {
|
||||||
|
if (props.half_mem() && (part == 1)) {
|
||||||
|
input = input_begin;
|
||||||
|
ctx->first_half = false;
|
||||||
|
cn_explode_scratchpad_vaes<ALGO>(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < N;) {
|
||||||
|
xout01 = _mm256_xor_si256(xout01, input[0]);
|
||||||
|
xout23 = _mm256_xor_si256(xout23, input[1]);
|
||||||
|
|
||||||
|
constexpr int input_increment = 64 / sizeof(__m256i);
|
||||||
|
|
||||||
|
xout45 = _mm256_xor_si256(xout45, input[input_increment]);
|
||||||
|
xout67 = _mm256_xor_si256(xout67, input[input_increment + 1]);
|
||||||
|
|
||||||
|
input += input_increment * 2;
|
||||||
|
i += 4;
|
||||||
|
|
||||||
|
if (i < N) {
|
||||||
|
_mm_prefetch((const char*)(input), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(input + input_increment), _MM_HINT_T0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vaes_round(k0, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k1, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k2, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k3, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k4, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k5, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k6, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k7, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k8, xout01, xout23, xout45, xout67);
|
||||||
|
vaes_round(k9, xout01, xout23, xout45, xout67);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_mm256_store_si256(output + 2, xout01);
|
||||||
|
_mm256_store_si256(output + 3, xout23);
|
||||||
|
_mm256_store_si256(output + 4, xout45);
|
||||||
|
_mm256_store_si256(output + 5, xout67);
|
||||||
|
|
||||||
|
_mm256_zeroupper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Id ALGO>
|
||||||
|
NOINLINE void cn_implode_scratchpad_vaes_double(cryptonight_ctx* ctx1, cryptonight_ctx* ctx2)
|
||||||
|
{
|
||||||
|
constexpr CnAlgo<ALGO> props;
|
||||||
|
|
||||||
|
constexpr size_t N = (props.memory() / sizeof(__m128i)) / (props.half_mem() ? 2 : 1);
|
||||||
|
|
||||||
|
__m256i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7;
|
||||||
|
__m256i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;
|
||||||
|
|
||||||
|
const __m128i* input1 = reinterpret_cast<const __m128i*>(ctx1->memory);
|
||||||
|
const __m128i* input2 = reinterpret_cast<const __m128i*>(ctx2->memory);
|
||||||
|
|
||||||
|
__m128i* output1 = reinterpret_cast<__m128i*>(ctx1->state);
|
||||||
|
__m128i* output2 = reinterpret_cast<__m128i*>(ctx2->state);
|
||||||
|
|
||||||
|
vaes_genkey_double(output1 + 2, output2 + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);
|
||||||
|
|
||||||
|
xout0 = _mm256_loadu2_m128i(output2 + 4, output1 + 4);
|
||||||
|
xout1 = _mm256_loadu2_m128i(output2 + 5, output1 + 5);
|
||||||
|
xout2 = _mm256_loadu2_m128i(output2 + 6, output1 + 6);
|
||||||
|
xout3 = _mm256_loadu2_m128i(output2 + 7, output1 + 7);
|
||||||
|
xout4 = _mm256_loadu2_m128i(output2 + 8, output1 + 8);
|
||||||
|
xout5 = _mm256_loadu2_m128i(output2 + 9, output1 + 9);
|
||||||
|
xout6 = _mm256_loadu2_m128i(output2 + 10, output1 + 10);
|
||||||
|
xout7 = _mm256_loadu2_m128i(output2 + 11, output1 + 11);
|
||||||
|
|
||||||
|
const __m128i* input_begin1 = input1;
|
||||||
|
const __m128i* input_begin2 = input2;
|
||||||
|
for (size_t part = 0; part < (props.half_mem() ? 2 : 1); ++part) {
|
||||||
|
if (props.half_mem() && (part == 1)) {
|
||||||
|
input1 = input_begin1;
|
||||||
|
input2 = input_begin2;
|
||||||
|
ctx1->first_half = false;
|
||||||
|
ctx2->first_half = false;
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(ctx1, ctx2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < N;) {
|
||||||
|
xout0 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + 0, input1 + 0), xout0);
|
||||||
|
xout1 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + 1, input1 + 1), xout1);
|
||||||
|
xout2 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + 2, input1 + 2), xout2);
|
||||||
|
xout3 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + 3, input1 + 3), xout3);
|
||||||
|
|
||||||
|
constexpr int input_increment = 64 / sizeof(__m128i);
|
||||||
|
|
||||||
|
xout4 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + input_increment + 0, input1 + input_increment + 0), xout4);
|
||||||
|
xout5 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + input_increment + 1, input1 + input_increment + 1), xout5);
|
||||||
|
xout6 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + input_increment + 2, input1 + input_increment + 2), xout6);
|
||||||
|
xout7 = _mm256_xor_si256(_mm256_loadu2_m128i(input2 + input_increment + 3, input1 + input_increment + 3), xout7);
|
||||||
|
|
||||||
|
input1 += input_increment * 2;
|
||||||
|
input2 += input_increment * 2;
|
||||||
|
i += 8;
|
||||||
|
|
||||||
|
if (i < N) {
|
||||||
|
_mm_prefetch((const char*)(input1), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(input1 + input_increment), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(input2), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(input2 + input_increment), _MM_HINT_T0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vaes_round(k0, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k1, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k2, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k3, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k4, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k5, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k6, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k7, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k8, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
vaes_round(k9, xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_mm256_storeu2_m128i(output2 + 4, output1 + 4, xout0);
|
||||||
|
_mm256_storeu2_m128i(output2 + 5, output1 + 5, xout1);
|
||||||
|
_mm256_storeu2_m128i(output2 + 6, output1 + 6, xout2);
|
||||||
|
_mm256_storeu2_m128i(output2 + 7, output1 + 7, xout3);
|
||||||
|
_mm256_storeu2_m128i(output2 + 8, output1 + 8, xout4);
|
||||||
|
_mm256_storeu2_m128i(output2 + 9, output1 + 9, xout5);
|
||||||
|
_mm256_storeu2_m128i(output2 + 10, output1 + 10, xout6);
|
||||||
|
_mm256_storeu2_m128i(output2 + 11, output1 + 11, xout7);
|
||||||
|
|
||||||
|
_mm256_zeroupper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Id ALGO>
|
||||||
|
void VAES_Instance()
|
||||||
|
{
|
||||||
|
cn_explode_scratchpad_vaes<ALGO>(nullptr);
|
||||||
|
cn_explode_scratchpad_vaes_double<ALGO>(nullptr, nullptr);
|
||||||
|
cn_implode_scratchpad_vaes<ALGO>(nullptr);
|
||||||
|
cn_implode_scratchpad_vaes_double<ALGO>(nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void (*vaes_instances[])() = {
|
||||||
|
VAES_Instance<Algorithm::CN_0>,
|
||||||
|
VAES_Instance<Algorithm::CN_1>,
|
||||||
|
VAES_Instance<Algorithm::CN_2>,
|
||||||
|
VAES_Instance<Algorithm::CN_R>,
|
||||||
|
VAES_Instance<Algorithm::CN_FAST>,
|
||||||
|
VAES_Instance<Algorithm::CN_HALF>,
|
||||||
|
VAES_Instance<Algorithm::CN_XAO>,
|
||||||
|
VAES_Instance<Algorithm::CN_RTO>,
|
||||||
|
VAES_Instance<Algorithm::CN_RWZ>,
|
||||||
|
VAES_Instance<Algorithm::CN_ZLS>,
|
||||||
|
VAES_Instance<Algorithm::CN_DOUBLE>,
|
||||||
|
VAES_Instance<Algorithm::CN_CCX>,
|
||||||
|
VAES_Instance<Algorithm::CN_LITE_0>,
|
||||||
|
VAES_Instance<Algorithm::CN_LITE_1>,
|
||||||
|
VAES_Instance<Algorithm::CN_HEAVY_0>,
|
||||||
|
VAES_Instance<Algorithm::CN_HEAVY_TUBE>,
|
||||||
|
VAES_Instance<Algorithm::CN_HEAVY_XHV>,
|
||||||
|
VAES_Instance<Algorithm::CN_PICO_0>,
|
||||||
|
VAES_Instance<Algorithm::CN_PICO_TLO>,
|
||||||
|
VAES_Instance<Algorithm::CN_UPX2>,
|
||||||
|
VAES_Instance<Algorithm::CN_GR_0>,
|
||||||
|
VAES_Instance<Algorithm::CN_GR_1>,
|
||||||
|
VAES_Instance<Algorithm::CN_GR_2>,
|
||||||
|
VAES_Instance<Algorithm::CN_GR_3>,
|
||||||
|
VAES_Instance<Algorithm::CN_GR_4>,
|
||||||
|
VAES_Instance<Algorithm::CN_GR_5>,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // xmrig
|
48
src/crypto/cn/CryptoNight_x86_vaes.h
Normal file
48
src/crypto/cn/CryptoNight_x86_vaes.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* 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 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||||
|
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2020 XMRig <https://github.com/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 XMRIG_CRYPTONIGHT_X86_VAES_H
|
||||||
|
#define XMRIG_CRYPTONIGHT_X86_VAES_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "crypto/cn/CnAlgo.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct cryptonight_ctx;
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Id ALGO> void cn_explode_scratchpad_vaes(cryptonight_ctx* ctx);
|
||||||
|
template<Algorithm::Id ALGO> void cn_explode_scratchpad_vaes_double(cryptonight_ctx* ctx1, cryptonight_ctx* ctx2);
|
||||||
|
template<Algorithm::Id ALGO> void cn_implode_scratchpad_vaes(cryptonight_ctx* ctx);
|
||||||
|
template<Algorithm::Id ALGO> void cn_implode_scratchpad_vaes_double(cryptonight_ctx* ctx1, cryptonight_ctx* ctx2);
|
||||||
|
|
||||||
|
|
||||||
|
} // xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_CRYPTONIGHT_X86_VAES_H */
|
|
@ -18,19 +18,21 @@ xmrig -a gr -o us.flockpool.com:5555 --tls -u WALLET_ADDRESS
|
||||||
|
|
||||||
You can use **rtm_ghostrider_example.cmd** as a template and put pool URL and your wallet address there. The general XMRig documentation is available [here](https://xmrig.com/docs/miner).
|
You can use **rtm_ghostrider_example.cmd** as a template and put pool URL and your wallet address there. The general XMRig documentation is available [here](https://xmrig.com/docs/miner).
|
||||||
|
|
||||||
|
**Using `--threads` or `-t` option is NOT recommended because it turns off advanced built-in config.** If you want to tweak the nubmer of threads used for GhostRider, it's recommended to start using config.json instead of command line. The best suitable command line option for this is `--cpu-max-threads-hint=N` where N can be between 0 and 100.
|
||||||
|
|
||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
While individual algorithm implementations are a bit unoptimized, XMRig achieves higher hashrates by employing better auto-config and more fine-grained thread scheduling: it can calculate a single batch of hashes using 2 threads for parts that don't require much cache. For example, on a typical Intel CPU (2 MB cache per core) it will use 1 thread per core for cn/fast, and 2 threads per core for other Cryptonight variants while calculating the same batch of hashes, always achieving more than 50% CPU load.
|
While individual algorithm implementations are a bit unoptimized, XMRig achieves higher hashrates by employing better auto-config and more fine-grained thread scheduling: it can calculate a single batch of hashes using 2 threads for parts that don't require much cache. For example, on a typical Intel CPU (2 MB cache per core) it will use 1 thread per core for cn/fast, and 2 threads per core for other Cryptonight variants while calculating the same batch of hashes, always achieving more than 50% CPU load.
|
||||||
|
|
||||||
For the same reason, XMRig can sometimes use less than 100% CPU on Ryzen 3000/5000 CPUs if it finds that running 1 thread per core is faster for some Cryptonight variants on your system. Also, this is why it reports using only half the threads at startup - it's actually 2 threads per each reported thread.
|
For the same reason, XMRig can sometimes use less than 100% CPU on Ryzen 3000/5000 CPUs if it finds that running 1 thread per core is faster for some Cryptonight variants on your system.
|
||||||
|
|
||||||
**Windows** (detailed results [here](https://imgur.com/a/GCjEWpl))
|
**Windows** (detailed results [here](https://imgur.com/a/uRU1yO2))
|
||||||
CPU|cpuminer-gr-avx2 (tuned), h/s|XMRig (MSVC build), h/s|Speedup
|
CPU|cpuminer-gr-avx2 (tuned), h/s|XMRig (MSVC build), h/s|Speedup
|
||||||
-|-|-|-
|
-|-|-|-
|
||||||
AMD Ryzen 7 4700U|632.6|731|+15.5%
|
AMD Ryzen 7 4700U|632.6|731|+15.5%
|
||||||
Intel Core i7-2600|496.4|533.6|+7.5%
|
Intel Core i7-2600|496.4|533.6|+7.5%
|
||||||
AMD Ryzen 7 3700X @ 4.1 GHz|2453.0|2469.1|+0.65%
|
AMD Ryzen 7 3700X @ 4.1 GHz|2453.0|2469.1|+0.65%
|
||||||
AMD Ryzen 5 5600X @ 4.65 GHz|2112.6|2221.2|+5.1%
|
AMD Ryzen 5 5600X @ 4.65 GHz|2112.6|2313.2|+9.5%
|
||||||
|
|
||||||
**Linux** (tested by **Delgon**, detailed results [here](https://cdn.discordapp.com/attachments/604375870236524574/913167614749048872/unknown.png))
|
**Linux** (tested by **Delgon**, detailed results [here](https://cdn.discordapp.com/attachments/604375870236524574/913167614749048872/unknown.png))
|
||||||
CPU|cpuminer-gr-avx2 (tuned), h/s|XMRig (GCC build), h/s|Speedup
|
CPU|cpuminer-gr-avx2 (tuned), h/s|XMRig (GCC build), h/s|Speedup
|
||||||
|
|
|
@ -538,7 +538,7 @@ void destroy_helper_thread(HelperThread* t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread* helper)
|
void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread* helper, bool verbose)
|
||||||
{
|
{
|
||||||
enum { N = 8 };
|
enum { N = 8 };
|
||||||
|
|
||||||
|
@ -554,6 +554,7 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct
|
||||||
uint32_t cn_indices[6];
|
uint32_t cn_indices[6];
|
||||||
select_indices(cn_indices, data + 4);
|
select_indices(cn_indices, data + 4);
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
static uint32_t prev_indices[3];
|
static uint32_t prev_indices[3];
|
||||||
if (memcmp(cn_indices, prev_indices, sizeof(prev_indices)) != 0) {
|
if (memcmp(cn_indices, prev_indices, sizeof(prev_indices)) != 0) {
|
||||||
memcpy(prev_indices, cn_indices, sizeof(prev_indices));
|
memcpy(prev_indices, cn_indices, sizeof(prev_indices));
|
||||||
|
@ -561,6 +562,7 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct
|
||||||
LOG_INFO("%s GhostRider algo %d: %s", Tags::cpu(), i + 1, cn_names[cn_indices[i]]);
|
LOG_INFO("%s GhostRider algo %d: %s", Tags::cpu(), i + 1, cn_names[cn_indices[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CnHash::AlgoVariant* av = Cpu::info()->hasAES() ? av_hw_aes : av_soft_aes;
|
const CnHash::AlgoVariant* av = Cpu::info()->hasAES() ? av_hw_aes : av_soft_aes;
|
||||||
const AlgoTune* tune = (helper && helper->m_is8MB) ? tune8MB : tuneDefault;
|
const AlgoTune* tune = (helper && helper->m_is8MB) ? tune8MB : tuneDefault;
|
||||||
|
@ -765,7 +767,7 @@ HelperThread* create_helper_thread(int64_t, const std::vector<int64_t>&) { retur
|
||||||
void destroy_helper_thread(HelperThread*) {}
|
void destroy_helper_thread(HelperThread*) {}
|
||||||
|
|
||||||
|
|
||||||
void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread*)
|
void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread*, bool verbose)
|
||||||
{
|
{
|
||||||
constexpr uint32_t N = 8;
|
constexpr uint32_t N = 8;
|
||||||
|
|
||||||
|
@ -784,6 +786,7 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct
|
||||||
uint32_t step[6] = { 4, 4, 1, 2, 4, 4 };
|
uint32_t step[6] = { 4, 4, 1, 2, 4, 4 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
static uint32_t prev_indices[3];
|
static uint32_t prev_indices[3];
|
||||||
if (memcmp(cn_indices, prev_indices, sizeof(prev_indices)) != 0) {
|
if (memcmp(cn_indices, prev_indices, sizeof(prev_indices)) != 0) {
|
||||||
memcpy(prev_indices, cn_indices, sizeof(prev_indices));
|
memcpy(prev_indices, cn_indices, sizeof(prev_indices));
|
||||||
|
@ -791,6 +794,7 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct
|
||||||
LOG_INFO("%s GhostRider algo %d: %s", Tags::cpu(), i + 1, cn_names[cn_indices[i]]);
|
LOG_INFO("%s GhostRider algo %d: %s", Tags::cpu(), i + 1, cn_names[cn_indices[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CnHash::AlgoVariant* av = Cpu::info()->hasAES() ? av_hw_aes : av_soft_aes;
|
const CnHash::AlgoVariant* av = Cpu::info()->hasAES() ? av_hw_aes : av_soft_aes;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct HelperThread;
|
||||||
void benchmark();
|
void benchmark();
|
||||||
HelperThread* create_helper_thread(int64_t cpu_index, const std::vector<int64_t>& affinities);
|
HelperThread* create_helper_thread(int64_t cpu_index, const std::vector<int64_t>& affinities);
|
||||||
void destroy_helper_thread(HelperThread* t);
|
void destroy_helper_thread(HelperThread* t);
|
||||||
void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread* helper);
|
void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ctx** ctx, HelperThread* helper, bool verbose = true);
|
||||||
|
|
||||||
|
|
||||||
} // namespace ghostrider
|
} // namespace ghostrider
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#define APP_ID "xmrig"
|
#define APP_ID "xmrig"
|
||||||
#define APP_NAME "XMRig"
|
#define APP_NAME "XMRig"
|
||||||
#define APP_DESC "XMRig miner"
|
#define APP_DESC "XMRig miner"
|
||||||
#define APP_VERSION "6.16.0"
|
#define APP_VERSION "6.16.1-dev"
|
||||||
#define APP_DOMAIN "xmrig.com"
|
#define APP_DOMAIN "xmrig.com"
|
||||||
#define APP_SITE "www.xmrig.com"
|
#define APP_SITE "www.xmrig.com"
|
||||||
#define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com"
|
#define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com"
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#define APP_VER_MAJOR 6
|
#define APP_VER_MAJOR 6
|
||||||
#define APP_VER_MINOR 16
|
#define APP_VER_MINOR 16
|
||||||
#define APP_VER_PATCH 0
|
#define APP_VER_PATCH 1
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# if (_MSC_VER >= 1920)
|
# if (_MSC_VER >= 1920)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue