mirror of
https://git.wownero.com/wownero/RandomWOW.git
synced 2024-08-15 00:23:14 +00:00
Separate executeSuperscalar function
Tweaked superscalar hash constants
This commit is contained in:
parent
2132e5fef5
commit
2e68c89740
4 changed files with 66 additions and 54 deletions
|
@ -453,7 +453,7 @@ namespace RandomX {
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uint64_t superscalarMul0 = 6364136223846793005ULL;
|
constexpr uint64_t superscalarMul0 = 6364136223846793005ULL;
|
||||||
constexpr uint64_t superscalarAdd1 = 9298410992540426048ULL;
|
constexpr uint64_t superscalarAdd1 = 9298410992540426748ULL;
|
||||||
constexpr uint64_t superscalarAdd2 = 12065312585734608966ULL;
|
constexpr uint64_t superscalarAdd2 = 12065312585734608966ULL;
|
||||||
constexpr uint64_t superscalarAdd3 = 9306329213124610396ULL;
|
constexpr uint64_t superscalarAdd3 = 9306329213124610396ULL;
|
||||||
constexpr uint64_t superscalarAdd4 = 5281919268842080866ULL;
|
constexpr uint64_t superscalarAdd4 = 5281919268842080866ULL;
|
||||||
|
@ -474,6 +474,55 @@ namespace RandomX {
|
||||||
return mixBlock;
|
return mixBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool superscalar>
|
||||||
|
void InterpretedVirtualMachine<superscalar>::executeSuperscalar(int_reg_t(&r)[8], LightProgram& prog, std::vector<uint64_t>& reciprocals) {
|
||||||
|
for (unsigned j = 0; j < prog.getSize(); ++j) {
|
||||||
|
Instruction& instr = prog(j);
|
||||||
|
switch (instr.opcode)
|
||||||
|
{
|
||||||
|
case RandomX::LightInstructionType::ISUB_R:
|
||||||
|
r[instr.dst] -= r[instr.src];
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IXOR_R:
|
||||||
|
r[instr.dst] ^= r[instr.src];
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IADD_RS:
|
||||||
|
r[instr.dst] += r[instr.src] << (instr.mod % 4);
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IMUL_R:
|
||||||
|
r[instr.dst] *= r[instr.src];
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IROR_C:
|
||||||
|
r[instr.dst] = rotr(r[instr.dst], instr.getImm32());
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IADD_C7:
|
||||||
|
case RandomX::LightInstructionType::IADD_C8:
|
||||||
|
case RandomX::LightInstructionType::IADD_C9:
|
||||||
|
r[instr.dst] += signExtend2sCompl(instr.getImm32());
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IXOR_C7:
|
||||||
|
case RandomX::LightInstructionType::IXOR_C8:
|
||||||
|
case RandomX::LightInstructionType::IXOR_C9:
|
||||||
|
r[instr.dst] ^= signExtend2sCompl(instr.getImm32());
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IMULH_R:
|
||||||
|
r[instr.dst] = mulh(r[instr.dst], r[instr.src]);
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::ISMULH_R:
|
||||||
|
r[instr.dst] = smulh(r[instr.dst], r[instr.src]);
|
||||||
|
break;
|
||||||
|
case RandomX::LightInstructionType::IMUL_RCP:
|
||||||
|
if(superscalar)
|
||||||
|
r[instr.dst] *= reciprocals[instr.getImm32()];
|
||||||
|
else
|
||||||
|
r[instr.dst] *= reciprocal(instr.getImm32());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<bool superscalar>
|
template<bool superscalar>
|
||||||
void InterpretedVirtualMachine<superscalar>::executeSuperscalar(uint32_t blockNumber, int_reg_t(&r)[8]) {
|
void InterpretedVirtualMachine<superscalar>::executeSuperscalar(uint32_t blockNumber, int_reg_t(&r)[8]) {
|
||||||
int_reg_t rl[8];
|
int_reg_t rl[8];
|
||||||
|
@ -491,48 +540,8 @@ namespace RandomX {
|
||||||
for (unsigned i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
for (unsigned i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
||||||
mixBlock = getMixBlock(registerValue, cache);
|
mixBlock = getMixBlock(registerValue, cache);
|
||||||
LightProgram& prog = superScalarPrograms[i];
|
LightProgram& prog = superScalarPrograms[i];
|
||||||
for (unsigned j = 0; j < prog.getSize(); ++j) {
|
|
||||||
Instruction& instr = prog(j);
|
executeSuperscalar(rl, prog, reciprocals);
|
||||||
switch (instr.opcode)
|
|
||||||
{
|
|
||||||
case RandomX::LightInstructionType::ISUB_R:
|
|
||||||
rl[instr.dst] -= rl[instr.src];
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IXOR_R:
|
|
||||||
rl[instr.dst] ^= rl[instr.src];
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IADD_RS:
|
|
||||||
rl[instr.dst] += rl[instr.src] << (instr.mod % 4);
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IMUL_R:
|
|
||||||
rl[instr.dst] *= rl[instr.src];
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IROR_C:
|
|
||||||
rl[instr.dst] = rotr(rl[instr.dst], instr.getImm32());
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IADD_C7:
|
|
||||||
case RandomX::LightInstructionType::IADD_C8:
|
|
||||||
case RandomX::LightInstructionType::IADD_C9:
|
|
||||||
rl[instr.dst] += signExtend2sCompl(instr.getImm32());
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IXOR_C7:
|
|
||||||
case RandomX::LightInstructionType::IXOR_C8:
|
|
||||||
case RandomX::LightInstructionType::IXOR_C9:
|
|
||||||
rl[instr.dst] ^= signExtend2sCompl(instr.getImm32());
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IMULH_R:
|
|
||||||
rl[instr.dst] = mulh(rl[instr.dst], rl[instr.src]);
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::ISMULH_R:
|
|
||||||
rl[instr.dst] = smulh(rl[instr.dst], rl[instr.src]);
|
|
||||||
break;
|
|
||||||
case RandomX::LightInstructionType::IMUL_RCP:
|
|
||||||
rl[instr.dst] *= reciprocals[instr.getImm32()];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned q = 0; q < 8; ++q)
|
for(unsigned q = 0; q < 8; ++q)
|
||||||
rl[q] ^= load64(mixBlock + 8 * q);
|
rl[q] ^= load64(mixBlock + 8 * q);
|
||||||
|
|
|
@ -73,6 +73,7 @@ namespace RandomX {
|
||||||
void setDataset(dataset_t ds, uint64_t size, LightProgram(&programs)[RANDOMX_CACHE_ACCESSES]) override;
|
void setDataset(dataset_t ds, uint64_t size, LightProgram(&programs)[RANDOMX_CACHE_ACCESSES]) override;
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
void execute() override;
|
void execute() override;
|
||||||
|
static void executeSuperscalar(int_reg_t(&r)[8], LightProgram& prog, std::vector<uint64_t>& reciprocals);
|
||||||
private:
|
private:
|
||||||
static InstructionHandler<superscalar> engine[256];
|
static InstructionHandler<superscalar> engine[256];
|
||||||
DatasetReadFunc readDataset;
|
DatasetReadFunc readDataset;
|
||||||
|
|
|
@ -2,8 +2,8 @@ r0_mul:
|
||||||
;#/ 6364136223846793005
|
;#/ 6364136223846793005
|
||||||
db 45, 127, 149, 76, 45, 244, 81, 88
|
db 45, 127, 149, 76, 45, 244, 81, 88
|
||||||
r1_add:
|
r1_add:
|
||||||
;#/ 9298410992540426048
|
;#/ 9298410992540426748
|
||||||
db 64, 159, 245, 89, 136, 151, 10, 129
|
db 252, 161, 245, 89, 136, 151, 10, 129
|
||||||
r2_add:
|
r2_add:
|
||||||
;#/ 12065312585734608966
|
;#/ 12065312585734608966
|
||||||
db 70, 216, 194, 56, 223, 153, 112, 167
|
db 70, 216, 194, 56, 223, 153, 112, 167
|
||||||
|
|
20
src/main.cpp
20
src/main.cpp
|
@ -177,7 +177,6 @@ void mine(RandomX::VirtualMachine* vm, std::atomic<uint32_t>& atomicNonce, Atomi
|
||||||
fillAes1Rx4<softAes>((void*)hash, RANDOMX_SCRATCHPAD_L3, scratchpad);
|
fillAes1Rx4<softAes>((void*)hash, RANDOMX_SCRATCHPAD_L3, scratchpad);
|
||||||
vm->resetRoundingMode();
|
vm->resetRoundingMode();
|
||||||
vm->setScratchpad(scratchpad);
|
vm->setScratchpad(scratchpad);
|
||||||
//dump((char*)scratchpad, RandomX::ScratchpadSize, "spad-before.txt");
|
|
||||||
for (int chain = 0; chain < RANDOMX_PROGRAM_COUNT - 1; ++chain) {
|
for (int chain = 0; chain < RANDOMX_PROGRAM_COUNT - 1; ++chain) {
|
||||||
fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer());
|
fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer());
|
||||||
vm->initialize();
|
vm->initialize();
|
||||||
|
@ -194,6 +193,7 @@ void mine(RandomX::VirtualMachine* vm, std::atomic<uint32_t>& atomicNonce, Atomi
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
vm->getResult<softAes>(scratchpad, RANDOMX_SCRATCHPAD_L3, hash);
|
vm->getResult<softAes>(scratchpad, RANDOMX_SCRATCHPAD_L3, hash);
|
||||||
|
//dump((char*)scratchpad, RANDOMX_SCRATCHPAD_L3, "spad.txt");
|
||||||
result.xorWith(hash);
|
result.xorWith(hash);
|
||||||
if (RandomX::trace) {
|
if (RandomX::trace) {
|
||||||
std::cout << "Nonce: " << nonce << " ";
|
std::cout << "Nonce: " << nonce << " ";
|
||||||
|
@ -204,8 +204,10 @@ void mine(RandomX::VirtualMachine* vm, std::atomic<uint32_t>& atomicNonce, Atomi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
bool softAes, genAsm, miningMode, verificationMode, help, largePages, async, genNative, jit, genSuperscalar, useSuperscalar;
|
bool softAes, genAsm, miningMode, verificationMode, help, largePages, async, genNative, jit, genSuperscalar, legacy;
|
||||||
int programCount, threadCount, initThreadCount, epoch;
|
int programCount, threadCount, initThreadCount, epoch;
|
||||||
|
|
||||||
readOption("--softAes", argc, argv, softAes);
|
readOption("--softAes", argc, argv, softAes);
|
||||||
|
@ -221,7 +223,7 @@ int main(int argc, char** argv) {
|
||||||
readOption("--genNative", argc, argv, genNative);
|
readOption("--genNative", argc, argv, genNative);
|
||||||
readOption("--help", argc, argv, help);
|
readOption("--help", argc, argv, help);
|
||||||
readOption("--genSuperscalar", argc, argv, genSuperscalar);
|
readOption("--genSuperscalar", argc, argv, genSuperscalar);
|
||||||
readOption("--useSuperscalar", argc, argv, useSuperscalar);
|
readOption("--legacy", argc, argv, legacy);
|
||||||
|
|
||||||
if (genSuperscalar) {
|
if (genSuperscalar) {
|
||||||
RandomX::LightProgram p;
|
RandomX::LightProgram p;
|
||||||
|
@ -283,7 +285,7 @@ int main(int argc, char** argv) {
|
||||||
outputHex(std::cout, (char*)dataset.cache.memory, sizeof(__m128i));
|
outputHex(std::cout, (char*)dataset.cache.memory, sizeof(__m128i));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
if (useSuperscalar) {
|
if (!legacy) {
|
||||||
RandomX::Blake2Generator gen(seed, programCount);
|
RandomX::Blake2Generator gen(seed, programCount);
|
||||||
for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
||||||
RandomX::generateLightProg2(programs[i], gen);
|
RandomX::generateLightProg2(programs[i], gen);
|
||||||
|
@ -297,7 +299,7 @@ int main(int argc, char** argv) {
|
||||||
dataset.dataset.size = datasetSize;
|
dataset.dataset.size = datasetSize;
|
||||||
RandomX::datasetAlloc(dataset, largePages);
|
RandomX::datasetAlloc(dataset, largePages);
|
||||||
const uint64_t datasetBlockCount = datasetSize / RandomX::CacheLineSize;
|
const uint64_t datasetBlockCount = datasetSize / RandomX::CacheLineSize;
|
||||||
if (useSuperscalar) {
|
if (!legacy) {
|
||||||
RandomX::JitCompilerX86 jit86;
|
RandomX::JitCompilerX86 jit86;
|
||||||
jit86.generateSuperScalarHash(programs);
|
jit86.generateSuperScalarHash(programs);
|
||||||
jit86.getDatasetInitFunc()(cache.memory, dataset.dataset.memory, 0, datasetBlockCount);
|
jit86.getDatasetInitFunc()(cache.memory, dataset.dataset.memory, 0, datasetBlockCount);
|
||||||
|
@ -330,11 +332,11 @@ int main(int argc, char** argv) {
|
||||||
vm = new RandomX::CompiledVirtualMachine();
|
vm = new RandomX::CompiledVirtualMachine();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (jit && useSuperscalar)
|
if (jit && !legacy)
|
||||||
vm = new RandomX::CompiledLightVirtualMachine<true>();
|
vm = new RandomX::CompiledLightVirtualMachine<true>();
|
||||||
else if (jit)
|
else if (jit)
|
||||||
vm = new RandomX::CompiledLightVirtualMachine<false>();
|
vm = new RandomX::CompiledLightVirtualMachine<false>();
|
||||||
else if (useSuperscalar)
|
else if (!legacy)
|
||||||
vm = new RandomX::InterpretedVirtualMachine<true>(softAes);
|
vm = new RandomX::InterpretedVirtualMachine<true>(softAes);
|
||||||
else
|
else
|
||||||
vm = new RandomX::InterpretedVirtualMachine<false>(softAes);
|
vm = new RandomX::InterpretedVirtualMachine<false>(softAes);
|
||||||
|
@ -373,8 +375,8 @@ int main(int argc, char** argv) {
|
||||||
double elapsed = sw.getElapsed();
|
double elapsed = sw.getElapsed();
|
||||||
std::cout << "Calculated result: ";
|
std::cout << "Calculated result: ";
|
||||||
result.print(std::cout);
|
result.print(std::cout);
|
||||||
if(programCount == 1000)
|
if(!legacy && programCount == 1000)
|
||||||
std::cout << "Reference result: 83875c55fb9ff4a75205a744b82926ebbe23219c6291889c9ee91603c845c597" << std::endl;
|
std::cout << "Reference result: 4a74a376d490c8b41d42887e86d4addb5a95572e0c663d1e81aec928e4e094e1" << std::endl;
|
||||||
if (!miningMode) {
|
if (!miningMode) {
|
||||||
std::cout << "Performance: " << 1000 * elapsed / programCount << " ms per hash" << std::endl;
|
std::cout << "Performance: " << 1000 * elapsed / programCount << " ms per hash" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue