mirror of
https://codeberg.org/wownero/RandomWOW
synced 2026-03-05 22:27:33 -05:00
Configuration guidelines (#59)
* added detailed guidelines for the selection of configuration values * added additional compile-time checks to prevent bad configurations * removed RANDOMX_SUPERSCALAR_MAX_SIZE parameter
This commit is contained in:
@@ -5,7 +5,6 @@ RANDOMX_ARGON_LANES EQU 1t
|
||||
RANDOMX_ARGON_SALT TEXTEQU <"RandomX\x03">
|
||||
RANDOMX_CACHE_ACCESSES EQU 8t
|
||||
RANDOMX_SUPERSCALAR_LATENCY EQU 170t
|
||||
RANDOMX_SUPERSCALAR_MAX_SIZE EQU 512t
|
||||
RANDOMX_DATASET_BASE_SIZE EQU 2147483648t
|
||||
RANDOMX_DATASET_EXTRA_SIZE EQU 33554368t
|
||||
RANDOMX_PROGRAM_SIZE EQU 256t
|
||||
|
||||
@@ -37,7 +37,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace randomx {
|
||||
|
||||
static_assert(RANDOMX_ARGON_MEMORY > 0, "RANDOMX_ARGON_MEMORY must be greater than 0.");
|
||||
static_assert((RANDOMX_ARGON_MEMORY & (RANDOMX_ARGON_MEMORY - 1)) == 0, "RANDOMX_ARGON_MEMORY must be a power of 2.");
|
||||
static_assert(RANDOMX_DATASET_BASE_SIZE >= 64, "RANDOMX_DATASET_BASE_SIZE must be at least 64.");
|
||||
static_assert((RANDOMX_DATASET_BASE_SIZE & (RANDOMX_DATASET_BASE_SIZE - 1)) == 0, "RANDOMX_DATASET_BASE_SIZE must be a power of 2.");
|
||||
static_assert(RANDOMX_DATASET_BASE_SIZE <= 4294967296ULL, "RANDOMX_DATASET_BASE_SIZE must not exceed 4294967296.");
|
||||
static_assert(RANDOMX_DATASET_EXTRA_SIZE % 64 == 0, "RANDOMX_DATASET_EXTRA_SIZE must be divisible by 64.");
|
||||
@@ -48,8 +50,10 @@ namespace randomx {
|
||||
static_assert(RANDOMX_SCRATCHPAD_L3 >= RANDOMX_SCRATCHPAD_L2, "RANDOMX_SCRATCHPAD_L3 must be greater than or equal to RANDOMX_SCRATCHPAD_L2.");
|
||||
static_assert((RANDOMX_SCRATCHPAD_L2 & (RANDOMX_SCRATCHPAD_L2 - 1)) == 0, "RANDOMX_SCRATCHPAD_L2 must be a power of 2.");
|
||||
static_assert(RANDOMX_SCRATCHPAD_L2 >= RANDOMX_SCRATCHPAD_L1, "RANDOMX_SCRATCHPAD_L2 must be greater than or equal to RANDOMX_SCRATCHPAD_L1.");
|
||||
static_assert(RANDOMX_SCRATCHPAD_L1 >= 64, "RANDOMX_SCRATCHPAD_L1 must be at least 64.");
|
||||
static_assert((RANDOMX_SCRATCHPAD_L1 & (RANDOMX_SCRATCHPAD_L1 - 1)) == 0, "RANDOMX_SCRATCHPAD_L1 must be a power of 2.");
|
||||
static_assert(RANDOMX_CACHE_ACCESSES > 1, "RANDOMX_CACHE_ACCESSES must be greater than 1");
|
||||
static_assert(RANDOMX_SUPERSCALAR_LATENCY > 0, "RANDOMX_SUPERSCALAR_LATENCY must be greater than 0");
|
||||
static_assert(RANDOMX_JUMP_BITS > 0, "RANDOMX_JUMP_BITS must be greater than 0.");
|
||||
static_assert(RANDOMX_JUMP_OFFSET >= 0, "RANDOMX_JUMP_OFFSET must be greater than or equal to 0.");
|
||||
static_assert(RANDOMX_JUMP_BITS + RANDOMX_JUMP_OFFSET <= 16, "RANDOMX_JUMP_BITS + RANDOMX_JUMP_OFFSET must not exceed 16.");
|
||||
@@ -64,8 +68,10 @@ namespace randomx {
|
||||
|
||||
static_assert(wtSum == 256, "Sum of instruction frequencies must be 256.");
|
||||
|
||||
|
||||
constexpr int ArgonBlockSize = 1024;
|
||||
constexpr int ArgonSaltSize = sizeof(RANDOMX_ARGON_SALT) - 1;
|
||||
constexpr int ArgonSaltSize = sizeof("" RANDOMX_ARGON_SALT) - 1;
|
||||
constexpr int SuperscalarMaxSize = 3 * RANDOMX_SUPERSCALAR_LATENCY + 2;
|
||||
constexpr int CacheLineSize = RANDOMX_DATASET_ITEM_SIZE;
|
||||
constexpr int ScratchpadSize = RANDOMX_SCRATCHPAD_L3;
|
||||
constexpr uint32_t CacheLineAlignMask = (RANDOMX_DATASET_BASE_SIZE - 1) & ~(CacheLineSize - 1);
|
||||
@@ -76,6 +82,15 @@ namespace randomx {
|
||||
constexpr int ConditionOffset = RANDOMX_JUMP_OFFSET;
|
||||
constexpr int StoreL3Condition = 14;
|
||||
|
||||
//Prevent some unsafe configurations.
|
||||
#ifndef RANDOMX_UNSAFE
|
||||
static_assert(RANDOMX_CACHE_ACCESSES * RANDOMX_ARGON_MEMORY * ArgonBlockSize + 33554432 >= RANDOMX_DATASET_BASE_SIZE + RANDOMX_DATASET_EXTRA_SIZE, "Unsafe configuration: Memory-time tradeoffs");
|
||||
static_assert((128 + RANDOMX_PROGRAM_SIZE * RANDOMX_FREQ_ISTORE / 256) * (RANDOMX_PROGRAM_COUNT * RANDOMX_PROGRAM_ITERATIONS) >= RANDOMX_SCRATCHPAD_L3, "Unsafe configuration: Insufficient Scratchpad writes");
|
||||
static_assert(RANDOMX_PROGRAM_COUNT > 1, "Unsafe configuration: Program filtering strategies");
|
||||
static_assert(RANDOMX_PROGRAM_SIZE >= 64, "Unsafe configuration: Low program entropy");
|
||||
static_assert(RANDOMX_PROGRAM_ITERATIONS >= 400, "Unsafe configuration: High compilation overhead");
|
||||
#endif
|
||||
|
||||
#ifdef TRACE
|
||||
constexpr bool trace = true;
|
||||
#else
|
||||
|
||||
@@ -31,10 +31,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//Cache size in KiB. Must be a power of 2.
|
||||
#define RANDOMX_ARGON_MEMORY 262144
|
||||
|
||||
//Number of Argon2d iterations for Cache initialization
|
||||
//Number of Argon2d iterations for Cache initialization.
|
||||
#define RANDOMX_ARGON_ITERATIONS 3
|
||||
|
||||
//Number of parallel lanes for Cache initialization
|
||||
//Number of parallel lanes for Cache initialization.
|
||||
#define RANDOMX_ARGON_LANES 1
|
||||
|
||||
//Argon2d salt
|
||||
@@ -46,22 +46,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//Target latency for SuperscalarHash (in cycles of the reference CPU).
|
||||
#define RANDOMX_SUPERSCALAR_LATENCY 170
|
||||
|
||||
//The maximum size of a SuperscalarHash program (number of instructions).
|
||||
#define RANDOMX_SUPERSCALAR_MAX_SIZE 512
|
||||
|
||||
//Dataset base size in bytes. Must be a power of 2.
|
||||
#define RANDOMX_DATASET_BASE_SIZE 2147483648
|
||||
|
||||
//Dataset extra size. Must be divisible by 64.
|
||||
#define RANDOMX_DATASET_EXTRA_SIZE 33554368
|
||||
|
||||
//Number of instructions in a RandomX program
|
||||
//Number of instructions in a RandomX program. Must be divisible by 8.
|
||||
#define RANDOMX_PROGRAM_SIZE 256
|
||||
|
||||
//Number of iterations during VM execution
|
||||
//Number of iterations during VM execution.
|
||||
#define RANDOMX_PROGRAM_ITERATIONS 2048
|
||||
|
||||
//Number of chained VM executions per hash
|
||||
//Number of chained VM executions per hash.
|
||||
#define RANDOMX_PROGRAM_COUNT 8
|
||||
|
||||
//Scratchpad L3 size in bytes. Must be a power of 2.
|
||||
@@ -70,13 +67,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//Scratchpad L2 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L3.
|
||||
#define RANDOMX_SCRATCHPAD_L2 262144
|
||||
|
||||
//Scratchpad L1 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L2.
|
||||
//Scratchpad L1 size in bytes. Must be a power of two (minimum 64) and less than or equal to RANDOMX_SCRATCHPAD_L2.
|
||||
#define RANDOMX_SCRATCHPAD_L1 16384
|
||||
|
||||
//Jump condition mask size in bits.
|
||||
#define RANDOMX_JUMP_BITS 8
|
||||
|
||||
//Jump condition mask offset in bits.
|
||||
//Jump condition mask offset in bits. The sum of RANDOMX_JUMP_BITS and RANDOMX_JUMP_OFFSET must not exceed 16.
|
||||
#define RANDOMX_JUMP_OFFSET 8
|
||||
|
||||
/*
|
||||
@@ -84,6 +81,7 @@ Instruction frequencies (per 256 opcodes)
|
||||
Total sum of frequencies must be 256
|
||||
*/
|
||||
|
||||
//Integer instructions
|
||||
#define RANDOMX_FREQ_IADD_RS 25
|
||||
#define RANDOMX_FREQ_IADD_M 7
|
||||
#define RANDOMX_FREQ_ISUB_R 16
|
||||
@@ -102,6 +100,7 @@ Total sum of frequencies must be 256
|
||||
#define RANDOMX_FREQ_IROL_R 0
|
||||
#define RANDOMX_FREQ_ISWAP_R 4
|
||||
|
||||
//Floating point instructions
|
||||
#define RANDOMX_FREQ_FSWAP_R 8
|
||||
#define RANDOMX_FREQ_FADD_R 20
|
||||
#define RANDOMX_FREQ_FADD_M 5
|
||||
@@ -112,11 +111,14 @@ Total sum of frequencies must be 256
|
||||
#define RANDOMX_FREQ_FDIV_M 4
|
||||
#define RANDOMX_FREQ_FSQRT_R 6
|
||||
|
||||
//Control instructions
|
||||
#define RANDOMX_FREQ_CBRANCH 16
|
||||
#define RANDOMX_FREQ_CFROUND 1
|
||||
|
||||
//Store instruction
|
||||
#define RANDOMX_FREQ_ISTORE 16
|
||||
|
||||
//No-op instruction
|
||||
#define RANDOMX_FREQ_NOP 0
|
||||
/* ------
|
||||
256
|
||||
|
||||
@@ -673,8 +673,8 @@ namespace randomx {
|
||||
//Each decode cycle decodes 16 bytes of x86 code.
|
||||
//Since a decode cycle produces on average 3.45 macro-ops and there are only 3 ALU ports, execution ports are always
|
||||
//saturated first. The cycle limit is present only to guarantee loop termination.
|
||||
//Program size is limited to RANDOMX_SUPERSCALAR_MAX_SIZE instructions.
|
||||
for (decodeCycle = 0; decodeCycle < RANDOMX_SUPERSCALAR_LATENCY && !portsSaturated && programSize < RANDOMX_SUPERSCALAR_MAX_SIZE; ++decodeCycle) {
|
||||
//Program size is limited to SuperscalarMaxSize instructions.
|
||||
for (decodeCycle = 0; decodeCycle < RANDOMX_SUPERSCALAR_LATENCY && !portsSaturated && programSize < SuperscalarMaxSize; ++decodeCycle) {
|
||||
|
||||
//select a decode configuration
|
||||
decodeBuffer = decodeBuffer->fetchNext(currentInstruction.getType(), decodeCycle, mulCount, gen);
|
||||
@@ -688,7 +688,7 @@ namespace randomx {
|
||||
|
||||
//if we have issued all macro-ops for the current RandomX instruction, create a new instruction
|
||||
if (macroOpIndex >= currentInstruction.getInfo().getSize()) {
|
||||
if (portsSaturated || programSize >= RANDOMX_SUPERSCALAR_MAX_SIZE)
|
||||
if (portsSaturated || programSize >= SuperscalarMaxSize)
|
||||
break;
|
||||
//select an instruction so that the first macro-op fits into the current slot
|
||||
currentInstruction.createForSlot(gen, decodeBuffer->getCounts()[bufferIndex], decodeBuffer->getIndex(), decodeBuffer->getSize() == bufferIndex + 1, bufferIndex == 0);
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace randomx {
|
||||
addrReg = val;
|
||||
}
|
||||
|
||||
Instruction programBuffer[RANDOMX_SUPERSCALAR_MAX_SIZE];
|
||||
Instruction programBuffer[SuperscalarMaxSize];
|
||||
uint32_t size;
|
||||
int addrReg;
|
||||
double ipc;
|
||||
|
||||
Reference in New Issue
Block a user