mirror of
https://git.wownero.com/wownero/RandomWOW.git
synced 2024-12-22 07:48:54 +00:00
API documentation
'dataset block' -> 'dataset item' customizable benchmark seed
This commit is contained in:
parent
bc78b628ea
commit
87b8253374
@ -59,7 +59,7 @@ namespace randomx {
|
||||
constexpr uint32_t CacheLineAlignMask = (RANDOMX_DATASET_SIZE - 1) & ~(CacheLineSize - 1);
|
||||
constexpr uint32_t CacheSize = RANDOMX_ARGON_MEMORY * 1024;
|
||||
|
||||
static_assert(RANDOMX_DATASET_BLOCKS == RANDOMX_DATASET_SIZE / CacheLineSize, "Invalid value of RANDOMX_DATASET_BLOCKS");
|
||||
static_assert(RANDOMX_DATASET_ITEMS == RANDOMX_DATASET_SIZE / CacheLineSize, "Invalid value of RANDOMX_DATASET_ITEMS");
|
||||
|
||||
#ifdef TRACE
|
||||
constexpr bool trace = true;
|
||||
|
@ -180,11 +180,11 @@ namespace randomx {
|
||||
return memory + (registerValue & mask) * CacheLineSize;
|
||||
}
|
||||
|
||||
void initDatasetBlock(randomx_cache* cache, uint8_t* out, uint64_t blockNumber) {
|
||||
void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t itemNumber) {
|
||||
int_reg_t rl[8];
|
||||
uint8_t* mixBlock;
|
||||
uint64_t registerValue = blockNumber;
|
||||
rl[0] = (blockNumber + 1) * superscalarMul0;
|
||||
uint64_t registerValue = itemNumber;
|
||||
rl[0] = (itemNumber + 1) * superscalarMul0;
|
||||
rl[1] = rl[0] ^ superscalarAdd1;
|
||||
rl[2] = rl[0] ^ superscalarAdd2;
|
||||
rl[3] = rl[0] ^ superscalarAdd3;
|
||||
@ -207,8 +207,8 @@ namespace randomx {
|
||||
memcpy(out, &rl, CacheLineSize);
|
||||
}
|
||||
|
||||
void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock) {
|
||||
for (uint32_t blockNumber = startBlock; blockNumber < endBlock; ++blockNumber, dataset += CacheLineSize)
|
||||
initDatasetBlock(cache, dataset, blockNumber);
|
||||
void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startItem, uint32_t endItem) {
|
||||
for (uint32_t itemNumber = startItem; itemNumber < endItem; ++itemNumber, dataset += CacheLineSize)
|
||||
initDatasetItem(cache, dataset, itemNumber);
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,6 @@ namespace randomx {
|
||||
using CacheLargePage = Cache<LargePageAllocator>;
|
||||
using CacheWithJitLargePage = CacheWithJit<LargePageAllocator>;
|
||||
|
||||
void initDatasetBlock(randomx_cache* cache, uint8_t* out, uint64_t blockNumber);
|
||||
void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t blockNumber);
|
||||
void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock);
|
||||
}
|
||||
|
@ -90,9 +90,9 @@ extern "C" {
|
||||
return dataset;
|
||||
}
|
||||
|
||||
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startBlock, unsigned long blockCount) {
|
||||
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startItem, unsigned long itemCount) {
|
||||
randomx::DatasetInitFunc dsfunc = cache->getInitFunc();
|
||||
dsfunc(cache, dataset->memory + startBlock * randomx::CacheLineSize, startBlock, startBlock + blockCount);
|
||||
dsfunc(cache, dataset->memory + startItem * randomx::CacheLineSize, startItem, startItem + itemCount);
|
||||
}
|
||||
|
||||
void randomx_release_dataset(randomx_dataset *dataset) {
|
||||
|
112
src/randomx.h
112
src/randomx.h
@ -23,7 +23,7 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||
#include <stddef.h>
|
||||
|
||||
#define RANDOMX_HASH_SIZE 32
|
||||
#define RANDOMX_DATASET_BLOCKS 33554432UL
|
||||
#define RANDOMX_DATASET_ITEMS 33554432UL
|
||||
|
||||
typedef enum {
|
||||
RANDOMX_FLAG_DEFAULT = 0,
|
||||
@ -41,19 +41,127 @@ typedef struct randomx_vm randomx_vm;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates a randomx_cache structure and allocates memory for RandomX Cache.
|
||||
*
|
||||
* @param flags is any combination of these 2 flags (each flag can be set or not set):
|
||||
* RANDOMX_FLAG_LARGE_PAGES - allocate memory in large pages
|
||||
* RANDOMX_FLAG_JIT - create cache structure with JIT compilation support; this makes
|
||||
* subsequent Dataset initialization faster
|
||||
*
|
||||
* @return Pointer to an allocated randomx_cache structure.
|
||||
NULL is returned if memory allocation fails or if the RANDOMX_FLAG_JIT
|
||||
is set and JIT compilation is not supported on the current platform.
|
||||
*/
|
||||
randomx_cache *randomx_alloc_cache(randomx_flags flags);
|
||||
|
||||
/**
|
||||
* Initializes the cache memory and SuperscalarHash using the provided seed value.
|
||||
*
|
||||
* @param cache is a pointer to a previously allocated randomx_cache structure. Must not be NULL.
|
||||
* @param seed is a pointer to memory which contains the seed value. Must not be NULL.
|
||||
* @param seedSize is the number of bytes of the seed.
|
||||
*/
|
||||
void randomx_init_cache(randomx_cache *cache, const void *seed, size_t seedSize);
|
||||
|
||||
/**
|
||||
* Releases all memory occupied by the randomx_cache structure.
|
||||
*
|
||||
* @param cache is a pointer to a previously allocated randomx_cache structure.
|
||||
*/
|
||||
void randomx_release_cache(randomx_cache* cache);
|
||||
|
||||
/**
|
||||
* Creates a randomx_dataset structure and allocates memory for RandomX Dataset.
|
||||
*
|
||||
* @param flags is the initialization flags. Only one flag is supported (can be set or not set):
|
||||
* RANDOMX_FLAG_LARGE_PAGES - allocate memory in large pages
|
||||
|
||||
* @return Pointer to an allocated randomx_cache structure.
|
||||
NULL is returned if memory allocation fails.
|
||||
*/
|
||||
randomx_dataset *randomx_alloc_dataset(randomx_flags flags);
|
||||
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startBlock, unsigned long blockCount);
|
||||
|
||||
/**
|
||||
* Initializes dataset items.
|
||||
*
|
||||
* Note: In order to use the Dataset, all items from 0 to (RANDOMX_DATASET_ITEMS - 1) must be initialized.
|
||||
* This may be done by several calls to this function using non-overlapping item sequences.
|
||||
*
|
||||
* @param dataset is a pointer to a previously allocated randomx_dataset structure. Must not be NULL.
|
||||
* @param cache is a pointer to a previously allocated and initialized randomx_cache structure. Must not be NULL.
|
||||
* @param startItem is the item number where intialization should start.
|
||||
* @param itemCount is the number of items that should be initialized.
|
||||
*/
|
||||
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startItem, unsigned long itemCount);
|
||||
|
||||
/**
|
||||
* Releases all memory occupied by the randomx_dataset structure.
|
||||
*
|
||||
* @param dataset is a pointer to a previously allocated randomx_dataset structure.
|
||||
*/
|
||||
void randomx_release_dataset(randomx_dataset *dataset);
|
||||
|
||||
/**
|
||||
* Creates and initializes a RandomX virtual machine.
|
||||
*
|
||||
* @param flags is any combination of these 4 flags (each flag can be set or not set):
|
||||
* RANDOMX_FLAG_LARGE_PAGES - allocate scratchpad memory in large pages
|
||||
* RANDOMX_FLAG_HARD_AES - virtual machine will use hardware accelerated AES
|
||||
* RANDOMX_FLAG_FULL_MEM - virtual machine will use the full dataset
|
||||
* RANDOMX_FLAG_JIT - virtual machine will use a JIT compiler
|
||||
* The numeric values of the flags are ordered so that a higher value will provide
|
||||
* faster hash calculation and a lower numeric value will provide higher portability.
|
||||
* Using RANDOMX_FLAG_DEFAULT (all flags not set) works on all platforms, but is the slowest.
|
||||
* @param cache is a pointer to an initialized randomx_cache structure. Can be
|
||||
* NULL if RANDOMX_FLAG_FULL_MEM is set.
|
||||
* @param dataset is a pointer to a randomx_dataset structure. Can be NULL
|
||||
* if RANDOMX_FLAG_FULL_MEM is not set.
|
||||
*
|
||||
* @return Pointer to an initialized randomx_vm structure.
|
||||
* Returns NULL if:
|
||||
* (1) Scratchpad memory allocation fails.
|
||||
* (2) The requested initialization flags are not supported on the current platform.
|
||||
* (3) cache parameter is NULL and RANDOMX_FLAG_FULL_MEM is not set
|
||||
* (4) dataset parameter is NULL and RANDOMX_FLAG_FULL_MEM is set
|
||||
*/
|
||||
randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset);
|
||||
|
||||
/**
|
||||
* Reinitializes a virtual machine with a new Cache. This function should be called anytime
|
||||
* the Cache is reinitialized with a new seed.
|
||||
*
|
||||
* @param machine is a pointer to a randomx_vm structure that was initialized
|
||||
* without RANDOMX_FLAG_FULL_MEM. Must not be NULL.
|
||||
* @param cache is a pointer to an initialized randomx_cache structure. Must not be NULL.
|
||||
*/
|
||||
void randomx_vm_set_cache(randomx_vm *machine, randomx_cache* cache);
|
||||
|
||||
/**
|
||||
* Reinitializes a virtual machine with a new Dataset.
|
||||
*
|
||||
* @param machine is a pointer to a randomx_vm structure that was initialized
|
||||
* with RANDOMX_FLAG_FULL_MEM. Must not be NULL.
|
||||
* @param dataset is a pointer to an initialized randomx_dataset structure. Must not be NULL.
|
||||
*/
|
||||
void randomx_vm_set_dataset(randomx_vm *machine, randomx_dataset *dataset);
|
||||
|
||||
/**
|
||||
* Releases all memory occupied by the randomx_vm structure.
|
||||
*
|
||||
* @param machine is a pointer to a previously created randomx_vm structure.
|
||||
*/
|
||||
void randomx_destroy_vm(randomx_vm *machine);
|
||||
|
||||
/**
|
||||
* Calculates a RandomX hash value.
|
||||
*
|
||||
* @param machine is a pointer to a randomx_vm structure. Must not be NULL.
|
||||
* @param input is a pointer to memory to be hashed. Must not be NULL.
|
||||
* @param inputSize is the number of bytes to be hashed.
|
||||
* @param output is a pointer to memory where the hash will be stored. Must not
|
||||
* be NULL and at least RANDOMX_HASH_SIZE bytes must be available for writing.
|
||||
*/
|
||||
void randomx_calculate_hash(randomx_vm *machine, const void *input, size_t inputSize, void *output);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
@ -20,8 +20,8 @@ int main() {
|
||||
std::cout << "Dataset allocation failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::thread t1(&randomx_init_dataset, myDataset, myCache, 0, RANDOMX_DATASET_BLOCKS / 2);
|
||||
std::thread t2(&randomx_init_dataset, myDataset, myCache, RANDOMX_DATASET_BLOCKS / 2, RANDOMX_DATASET_BLOCKS / 2);
|
||||
std::thread t1(&randomx_init_dataset, myDataset, myCache, 0, RANDOMX_DATASET_ITEMS / 2);
|
||||
std::thread t2(&randomx_init_dataset, myDataset, myCache, RANDOMX_DATASET_ITEMS / 2, RANDOMX_DATASET_ITEMS / 2);
|
||||
t1.join();
|
||||
t2.join();
|
||||
randomx_release_cache(myCache);
|
||||
|
@ -30,8 +30,6 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||
#include "../randomx.h"
|
||||
#include "../blake2/endian.h"
|
||||
|
||||
const uint8_t seed[32] = { 191, 182, 222, 175, 249, 89, 134, 104, 241, 68, 191, 62, 162, 166, 61, 64, 123, 191, 227, 193, 118, 60, 188, 53, 223, 133, 175, 24, 123, 230, 55, 74 };
|
||||
|
||||
const uint8_t blockTemplate_[] = {
|
||||
0x07, 0x07, 0xf7, 0xa4, 0xf0, 0xd6, 0x05, 0xb3, 0x03, 0x26, 0x08, 0x16, 0xba, 0x3f, 0x10, 0x90, 0x2e, 0x1a, 0x14,
|
||||
0x5a, 0xc5, 0xfa, 0xd3, 0xaa, 0x3a, 0xf6, 0xea, 0x44, 0xc1, 0x18, 0x69, 0xdc, 0x4f, 0x85, 0x3f, 0x00, 0x2b, 0x2e,
|
||||
@ -82,6 +80,7 @@ void printUsage(const char* executable) {
|
||||
std::cout << " --threads T use T threads (default: 1)" << std::endl;
|
||||
std::cout << " --init Q initialize dataset with Q threads (default: 1)" << std::endl;
|
||||
std::cout << " --nonces N run N nonces (default: 1000)" << std::endl;
|
||||
std::cout << " --seed S seed for cache initialization (default: 0)" << std::endl;
|
||||
}
|
||||
|
||||
void mine(randomx_vm* vm, std::atomic<uint32_t>& atomicNonce, AtomicHash& result, uint32_t noncesCount, int thread) {
|
||||
@ -102,6 +101,7 @@ void mine(randomx_vm* vm, std::atomic<uint32_t>& atomicNonce, AtomicHash& result
|
||||
int main(int argc, char** argv) {
|
||||
bool softAes, miningMode, verificationMode, help, largePages, jit;
|
||||
int noncesCount, threadCount, initThreadCount;
|
||||
int32_t seed;
|
||||
|
||||
readOption("--softAes", argc, argv, softAes);
|
||||
readOption("--mine", argc, argv, miningMode);
|
||||
@ -109,6 +109,7 @@ int main(int argc, char** argv) {
|
||||
readIntOption("--threads", argc, argv, threadCount, 1);
|
||||
readIntOption("--nonces", argc, argv, noncesCount, 1000);
|
||||
readIntOption("--init", argc, argv, initThreadCount, 1);
|
||||
readIntOption("--seed", argc, argv, seed, 0);
|
||||
readOption("--largePages", argc, argv, largePages);
|
||||
readOption("--jit", argc, argv, jit);
|
||||
readOption("--help", argc, argv, help);
|
||||
@ -172,7 +173,7 @@ int main(int argc, char** argv) {
|
||||
std::cout << "ERROR: Cache allocation failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
randomx_init_cache(cache, seed, sizeof(seed));
|
||||
randomx_init_cache(cache, &seed, sizeof(seed));
|
||||
if (miningMode) {
|
||||
dataset = randomx_alloc_dataset(flags);
|
||||
if (dataset == nullptr) {
|
||||
@ -180,20 +181,20 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
if (initThreadCount > 1) {
|
||||
auto perThread = RANDOMX_DATASET_BLOCKS / initThreadCount;
|
||||
auto remainder = RANDOMX_DATASET_BLOCKS % initThreadCount;
|
||||
uint32_t startBlock = 0;
|
||||
auto perThread = RANDOMX_DATASET_ITEMS / initThreadCount;
|
||||
auto remainder = RANDOMX_DATASET_ITEMS % initThreadCount;
|
||||
uint32_t startItem = 0;
|
||||
for (int i = 0; i < initThreadCount; ++i) {
|
||||
auto count = perThread + (i == initThreadCount - 1 ? remainder : 0);
|
||||
threads.push_back(std::thread(&randomx_init_dataset, dataset, cache, startBlock, count));
|
||||
startBlock += count;
|
||||
threads.push_back(std::thread(&randomx_init_dataset, dataset, cache, startItem, count));
|
||||
startItem += count;
|
||||
}
|
||||
for (unsigned i = 0; i < threads.size(); ++i) {
|
||||
threads[i].join();
|
||||
}
|
||||
}
|
||||
else {
|
||||
randomx_init_dataset(dataset, cache, 0, RANDOMX_DATASET_BLOCKS);
|
||||
randomx_init_dataset(dataset, cache, 0, RANDOMX_DATASET_ITEMS);
|
||||
}
|
||||
randomx_release_cache(cache);
|
||||
threads.clear();
|
||||
@ -227,8 +228,8 @@ int main(int argc, char** argv) {
|
||||
double elapsed = sw.getElapsed();
|
||||
std::cout << "Calculated result: ";
|
||||
result.print(std::cout);
|
||||
if (noncesCount == 1000)
|
||||
std::cout << "Reference result: dc34604eed2fbba0e8fae26b2270b90d8aad9466ba39950fd8904248442e850a" << std::endl;
|
||||
if (noncesCount == 1000 && seed == 0)
|
||||
std::cout << "Reference result: b69741719152625854031c2337ceae68c3030f2b9581a73acebaa69fc9b555fc" << std::endl;
|
||||
if (!miningMode) {
|
||||
std::cout << "Performance: " << 1000 * elapsed / noncesCount << " ms per hash" << std::endl;
|
||||
}
|
||||
|
@ -31,10 +31,10 @@ namespace randomx {
|
||||
|
||||
template<class Allocator, bool softAes>
|
||||
void InterpretedLightVm<Allocator, softAes>::datasetRead(uint32_t address, int_reg_t(&r)[8]) {
|
||||
uint32_t blockNumber = address / CacheLineSize;
|
||||
uint32_t itemNumber = address / CacheLineSize;
|
||||
int_reg_t rl[8];
|
||||
|
||||
initDatasetBlock(cachePtr, (uint8_t*)rl, blockNumber);
|
||||
initDatasetItem(cachePtr, (uint8_t*)rl, itemNumber);
|
||||
|
||||
for (unsigned q = 0; q < 8; ++q)
|
||||
r[q] ^= rl[q];
|
||||
|
Loading…
Reference in New Issue
Block a user