- One-time difficulty reset to minimum for 17 blocks at activation height - Separate RandomX build dirs for linux/win64 cross-compilation - Add build target tracking to auto-clean on target switch - Automated win64 release packaging to release-win64/ - Add build artifacts to .gitignore - Miner memory diagnostics and large-page dataset fallback
64 lines
2.5 KiB
Markdown
64 lines
2.5 KiB
Markdown
# Changelog: RandomX Mining Optimization
|
||
|
||
## Summary
|
||
|
||
Optimizes RandomX miner memory usage by replacing per-thread dataset/cache allocation with a shared `RandomXDatasetManager`. Reduces memory footprint from ~2.3GB × N threads to ~2.3GB total.
|
||
|
||
## Problem
|
||
|
||
The original RandomX miner implementation allocated a full RandomX dataset (~2GB) and cache (~256MB) for each mining thread. With multiple threads, this quickly exhausted available memory:
|
||
|
||
- 4 threads: ~9.2GB
|
||
- 8 threads: ~18.4GB
|
||
- 16 threads: ~36.8GB
|
||
|
||
## Solution
|
||
|
||
Implemented a shared `RandomXDatasetManager` that allocates a single dataset and cache, shared by all miner threads via read-only access (explicitly supported by RandomX design).
|
||
|
||
## Changes
|
||
|
||
### `src/miner.cpp`
|
||
|
||
- **Added `RandomXDatasetManager` class:**
|
||
- Manages a single shared RandomX cache and dataset.
|
||
- Thread-safe key updates using `boost::shared_mutex` (readers-writer lock).
|
||
- `Initialize(key)`: Allocates cache and dataset, initializes with key, builds dataset using all CPU cores.
|
||
- `UpdateKey(newKey)`: Acquires exclusive lock, reinitializes cache with new key, rebuilds dataset.
|
||
- `GetDataset()`: Returns pointer to shared dataset for VM creation.
|
||
- `AcquireSharedLock()` / `ReleaseSharedLock()`: Miner threads hold shared lock while hashing to prevent key updates mid-hash.
|
||
- `Shutdown()`: Releases all RandomX resources.
|
||
|
||
- **Modified `GenerateBitcoins()`:**
|
||
- Initializes `RandomXDatasetManager` with initial key before spawning miner threads.
|
||
- Calls `Shutdown()` when mining stops.
|
||
|
||
- **Modified `RandomXMiner()`:**
|
||
- Creates lightweight per-thread VM using shared dataset (`randomx_create_vm(..., manager.GetDataset())`).
|
||
- Acquires shared lock before hashing, releases after.
|
||
- On key rotation: releases shared lock, calls `manager.UpdateKey()`, reacquires shared lock, recreates VM.
|
||
- Cleanup only destroys thread's VM — dataset/cache owned by manager.
|
||
|
||
## Memory Usage
|
||
|
||
| Threads | Before | After |
|
||
|---------|--------|-------|
|
||
| 1 | ~2.3GB | ~2.3GB |
|
||
| 4 | ~9.2GB | ~2.3GB |
|
||
| 8 | ~18.4GB | ~2.3GB |
|
||
| 16 | ~36.8GB | ~2.3GB |
|
||
|
||
## Thread Safety
|
||
|
||
- RandomX dataset is read-only after initialization — safe to share across threads.
|
||
- `boost::shared_mutex` ensures:
|
||
- Multiple threads can hash concurrently (shared lock).
|
||
- Key updates are exclusive (exclusive lock blocks until all shared locks release).
|
||
- No thread hashes with stale dataset during key change.
|
||
|
||
## Files Modified
|
||
|
||
| File | Lines Added | Lines Removed |
|
||
|------|-------------|---------------|
|
||
| `src/miner.cpp` | ~80 | ~20 |
|