Skip to content

Commit

Permalink
Small refactoring
Browse files Browse the repository at this point in the history
Signed-off-by: Pttn <28868425+Pttn@users.noreply.github.com>
  • Loading branch information
Pttn committed Nov 24, 2018
1 parent d4ac52c commit 21c1a1e
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 56 deletions.
6 changes: 2 additions & 4 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ Some parts were adapted from other projects:

These parts are subject to their respective licenses.

Michael Bell provided the miner optimizations in the MIT license.
Else, this work (including contributions to its code) is released under the following MIT license. https://opensource.org/licenses/MIT

Else, this work is released under the following MIT license. https://opensource.org/licenses/MIT

Copyright 2017-2018 Pttn (https://github.com/Pttn/)
Copyright 2017-2018 Pttn and contributors (https://github.com/Pttn/)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
45 changes: 23 additions & 22 deletions Miner.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* (c) 2014-2017 dave-andersen (base code) (http://www.cs.cmu.edu/~dga/)
(c) 2017-2018 Pttn (refactoring and porting to modern C++) (https://ric.pttn.me/)
(c) 2018 Michael Bell/Rockhawk (assembly optimizations, improvement of work management between threads, and some more) (https://github.com/MichaelBell/) */
(c) 2018 Michael Bell/Rockhawk (assembly optimizations, improvements of work management between threads, and some more) (https://github.com/MichaelBell/) */

#include "Miner.hpp"
#include "external/gmp_util.h"
Expand All @@ -24,12 +24,13 @@ void Miner::init() {
if (_parameters.sieveWorkers == 0) {
_parameters.sieveWorkers = std::max(_manager->options().threads()/5, 1);
}
std::cout << "Sieve Workers = " << _parameters.sieveWorkers << std::endl;
_parameters.sieveWorkers = std::min(_parameters.sieveWorkers, MAX_SIEVE_WORKERS);
_parameters.sieveWorkers = std::min(_parameters.sieveWorkers, int(_parameters.primorialOffset.size()));
_parameters.sieveBits = _manager->options().sieveBits();
_parameters.sieveSize = 1 << _parameters.sieveBits;
_parameters.sieveWords = _parameters.sieveSize / 64;
_parameters.maxIter = _parameters.maxIncrements / _parameters.sieveSize;
_parameters.sieveWords = _parameters.sieveSize/64;
_parameters.maxIter = _parameters.maxIncrements/_parameters.sieveSize;
_parameters.solo = !(_manager->options().protocol() == "Stratum");
_parameters.tuples = _manager->options().tuples();
_parameters.sieve = _manager->options().sieve();
Expand Down Expand Up @@ -104,7 +105,7 @@ void Miner::init() {
_parameters.modPrecompute.resize(precompPrimes*4);

_startingPrimeIndex = _parameters.primorialNumber;
uint64_t blockSize((_nPrimes - _startingPrimeIndex + _parameters.threads - 1) / _parameters.threads);
uint64_t blockSize((_nPrimes - _startingPrimeIndex + _parameters.threads - 1)/_parameters.threads);
std::thread threads[_parameters.threads];
for (int16_t j(0) ; j < _parameters.threads ; j++) {
threads[j] = std::thread([&, j]() {
Expand Down Expand Up @@ -232,7 +233,7 @@ void Miner::_updateRemainders(uint32_t workDataIndex, uint64_t start_i, uint64_t
for (int i(0); i < _parameters.sieveWorkers; ++i)
offset_stack[i] = new uint64_t[OFFSET_STACK_SIZE];
}
uint64_t precompLimit = _parameters.modPrecompute.size()/4;
uint64_t precompLimit(_parameters.modPrecompute.size()/4);

for (uint64_t i(start_i) ; i < end_i ; i++) {
uint64_t p(_parameters.primes[i]);
Expand Down Expand Up @@ -536,13 +537,13 @@ too for the one-in-a-whatever case that Fermat is wrong. */
if (job.type == TYPE_SIEVE) {
_runSieve(_sieves[job.sieveWork.sieveId], job.workDataIndex);
_workDoneQueue.push_back(-1);
auto myTime = std::chrono::duration_cast<decltype(_sieveTime)>(std::chrono::high_resolution_clock::now() - startTime);
//std::cout << "Sieve " << job.sieveWork.sieveId << " Time: " << myTime.count() << std::endl;
_sieveTime += myTime;
auto dt(std::chrono::duration_cast<decltype(_sieveTime)>(std::chrono::high_resolution_clock::now() - startTime));
//std::cout << "Sieve " << job.sieveWork.sieveId << " Time: " << dt.count() << std::endl;
_sieveTime += dt;
continue;
}
// fallthrough: job.type == TYPE_CHECK
if (job.type == TYPE_CHECK) {

if (job.type == TYPE_CHECK) { // fallthrough: job.type == TYPE_CHECK
mpz_mul_ui(z_ploop, _primorial, job.testWork.loop*_parameters.sieveSize);
mpz_add(z_ploop, z_ploop, _workData[job.workDataIndex].z_verifyRemainderPrimorial);
mpz_add(z_ploop, z_ploop, _workData[job.workDataIndex].z_verifyTarget);
Expand Down Expand Up @@ -713,7 +714,7 @@ void Miner::_processOneBlock(uint32_t workDataIndex) {
else n_modWorkers++;
}
while (n_lowModWorkers > 0) {
uint64_t i = _modDoneQueue.pop_front();
uint64_t i(_modDoneQueue.pop_front());
if (i < _startingPrimeIndex + _nDense + _nSparse) n_lowModWorkers--;
else n_modWorkers--;
}
Expand All @@ -735,7 +736,7 @@ void Miner::_processOneBlock(uint32_t workDataIndex) {

uint32_t minWorkOut = std::min(curWorkOut, _verifyWorkQueue.size());
while (n_sieveWorkers > 0) {
int workId = _workDoneQueue.pop_front();
int workId(_workDoneQueue.pop_front());
if (workId == -1) n_sieveWorkers--;
else _workData[workId].outstandingTests--;
minWorkOut = std::min(minWorkOut, _verifyWorkQueue.size());
Expand All @@ -751,26 +752,26 @@ void Miner::_processOneBlock(uint32_t workDataIndex) {
_maxWorkOut += 4*_parameters.threads*_parameters.sieveWorkers;
}
else {
// Adjust towards target of min work = 4 * threads
uint32_t targetMaxWork = (_maxWorkOut - minWorkOut) + 4*_parameters.threads;
_maxWorkOut = (_maxWorkOut + targetMaxWork) / 2;
// Adjust towards target of min work = 4*threads
uint32_t targetMaxWork((_maxWorkOut - minWorkOut) + 4*_parameters.threads);
_maxWorkOut = (_maxWorkOut + targetMaxWork)/2;
}
}
else if (minWorkOut > 4u*_parameters.threads) {
// Didn't make the target, but also didn't run out of work. Can still adjust target.
uint32_t targetMaxWork = (curWorkOut - minWorkOut) + 6*_parameters.threads;
_maxWorkOut = (_maxWorkOut + targetMaxWork) / 2;
uint32_t targetMaxWork((curWorkOut - minWorkOut) + 6*_parameters.threads);
_maxWorkOut = (_maxWorkOut + targetMaxWork)/2;
}
else if (minWorkOut == 0 && curWorkOut > 0) {
// Warn the user they may need to change their configuration
static int allowedFails = 5;
static bool first = true;
static int allowedFails(5);
static bool first(true);
if (--allowedFails == 0) {
allowedFails = 5;
std::cout << "WARNING: Unable to generate enough verification work to keep threads busy." << std::endl;
std::cout << "Unable to generate enough verification work to keep threads busy." << std::endl;
if (first) {
std::cout << "If you see the above message frequently consider reducing Sieve Max or increasing Sieve Workers" << std::endl;
std::cout << "Current Sieve max = " << _parameters.sieve << " Sieve Workers = " << _parameters.sieveWorkers << std::endl;
std::cout << "If you see this message frequently, consider reducing Sieve Max or increasing Sieve Workers via the configuration file. If it only appears once a while (at most 2-3 times a hour), it is fine." << std::endl;
std::cout << "Current values: Sieve = " << _parameters.sieve << ", SieveWorkers = " << _parameters.sieveWorkers << std::endl;
first = false;
}
}
Expand Down
60 changes: 39 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# rieMiner 0.9RC1
# rieMiner 0.9RC2

rieMiner is a Riecoin miner supporting both solo and pooled mining. It was originally adapted and refactored from gatra's cpuminer-rminerd (https://github.com/gatra/cpuminer-rminerd) and dave-andersen's fastrie (https://github.com/dave-andersen/fastrie), though there is no remaining code from rminerd anymore.

Solo mining is done using the GetBlockTemplate protocol, while pooled mining is via the Stratum protocol. A benchmark mode is also proposed to compare more easily the performance between different computers.

It is recommended to use a recent enough CPU with at least 4 cores and 8 GB of RAM to mine efficiently enough.

Direct link to the latest official [Windows x64 standalone executable](https://ric.pttn.me/file.php?d=rieMinerWin64).

This README also serves as manual for rieMiner. I hope that this program will be useful for you! Happy mining!
Expand All @@ -14,10 +12,24 @@ The Riecoin community thanks you for your participation, you will be a contribut

![rieMiner just found a block](https://ric.pttn.me/file.php?d=rieMiner)

## Compile this program
I provide a Profitability Calculator [here](https://ric.pttn.me/page.php?n=ProfitabilityCalculator).

## Minimum requirements

Only x64 systems with SSE are supported since version 0.9β2.4.

* Windows 7 or later, or recent enough Linux;
* x64 CPU with SSE instruction set;
* 1 GB of RAM (Sieve size must be manually set at a very low value in the options).

Recommended:

* Windows 10 or Debian 9;
* Intel Core i7 6700 or better, AMD Ryzen R5 1600 or better;
* 8 GB of RAM.

## Compile this program

### In Debian/Ubuntu x64

You can compile this C++ program with g++, as, m4 and make, install them if needed. Then, get if needed the following dependencies:
Expand Down Expand Up @@ -103,7 +115,7 @@ Alternatively, you can create or edit this "rieMiner.conf" file next to the exec
Option type = Option value
```

It is case sensitive, but spaces and invalid lines are ignored. **Do not put ; at the end or use other delimiters than =** for each line, and **do not confuse rieMiner.conf with riecoin.conf**! If an option is missing, the default value(s) will be used. If there are duplicate lines, the last one will be used. The available options are:
It is case sensitive, but spaces and invalid lines are ignored. **Do not put ; at the end or use other delimiters than =** for each line, and **do not confuse rieMiner.conf with riecoin.conf**! If an option is missing, the default value(s) will be used. If there are duplicate lines, the last one will be used. The main available options are:

* Host : IP of the Riecoin wallet/server or pool. Default: 127.0.0.1 (your computer);
* Port : port of the Riecoin wallet/server or pool. Default: 28332 (default port for Riecoin-Qt);
Expand All @@ -112,16 +124,9 @@ It is case sensitive, but spaces and invalid lines are ignored. **Do not put ; a
* Protocol : protocol to use: GetBlockTemplate for solo mining, Stratum for pooled mining, Benchmark for testing. Default: Benchmark;
* Address : custom payout address for solo mining (GetBlockTemplate only). Default: a donation address;
* Threads : number of threads used for mining. Default: 8;
* Sieve : size of the sieve table used for mining. Use a bigger number if you have more RAM, as you will obtain better results: this will usually reduce the ratio between the n-tuple and n+1-tuples counts. It can go up to 2^64 - 1, but setting this at more than a few billions will be too much and decrease performance. Default: 2^30;
* SieveWorkers : the number of threads to use for sieving. Default: 0, which means choose automatically based on number of threads. If you see warnings about not being able to generate enough work, try increasing it (though note that increasing it will use more memory).
* Tuples : for solo mining, submit not only blocks (6-tuples) but also k-tuples of at least the given length. Its use will be explained later. Default: 6;
* Refresh : refresh rate of the stats in seconds. 0 to disable them: will only notify when a k-tuple or share (k >= Tuples option value if solo mining) is found, or when the network finds a block. Default: 30;
* Sieve : size of the sieve table used for mining. Use a bigger number if you have 16 GiB of RAM or more, as you will obtain better results: this will usually reduce the ratio between the n-tuple and n+1-tuples counts. Reduce if you have less than 8 GiB of RAM. It can go up to 2^64 - 1, but setting this at more than a few billions will be too much and decrease performance. Default: 2^30;
* MaxMem : set an approximate limit on amount of memory to use in MiB. 0 for no limit. Default: 0;
* SieveBits : size of the segment sieve is 2^SieveBits bits, e.g. 25 means the segment sieve size is 4MiB. Choose this so that SieveWorkers&ast;SieveBits fits in your L3 cache. Default: 25
* TestDiff : only for Benchmark, sets the testing difficulty (must be from 265 to 32767). Default: 1600;
* TestTime : only for Benchmark, sets the testing duration in s. 0 for no time limit. Default: 0;
* Test2t : only for Benchmark, stops testing after finding this number of 2-tuples. 0 for no limit. Default: 50000;
* TCFile : Tuples Counts filename, in which rieMiner will save for each difficulty the number of tuples found. Note that there must never be more than one rieMiner instance using the same file. Default: None (special value that disables this feature).
* Tuples : for solo mining, submit not only blocks (6-tuples) but also k-tuples of at least the given length. Its use will be explained later. Default: 6.

It is also possible to use custom configuration file paths, examples:

Expand All @@ -131,15 +136,28 @@ It is also possible to use custom configuration file paths, examples:
./rieMiner /home/user/rieMiner/rieMiner.conf
```

### Advanced options
### Statistics and benchmarking options

* Refresh : refresh rate of the stats in seconds. 0 to disable them: will only notify when a k-tuple or share (k >= Tuples option value if solo mining) is found, or when the network finds a block. Default: 30;
* TestDiff : only for Benchmark, sets the testing difficulty (must be from 265 to 32767). Default: 1600;
* TestTime : only for Benchmark, sets the testing duration in s. 0 for no time limit. Default: 0;
* Test2t : only for Benchmark, stops testing after finding this number of 2-tuples. 0 for no limit. Default: 50000;
* TCFile : Tuples Counts filename, in which rieMiner will save for each difficulty the number of tuples found. Note that there must never be more than one rieMiner instance using the same file, and you should also use different files if you use different Sieve sizes to not skew the stats (ratios). Default: None (special value that disables this feature).

### Advanced/Tweaking options

They can be useful to get better performance depending on your computer.

* SieveBits : size of the segment sieve is 2^SieveBits bits, e.g. 25 means the segment sieve size is 4 MiB. Choose this so that SieveWorkers*SieveBits fits in your L3 cache. Default: 25;
* SieveWorkers : the number of threads to use for sieving. Default: 0, which means choose automatically based on number of threads. If you see warnings about not being able to generate enough work, try increasing it (though note that increasing it will use more memory).

Normally, you should never need to change them, but they can be useful for developing purposes, or maybe some further optimizations.
These ones should never be modified outside developing purposes and research for now.

* ConsType : set your Constellation Type, i. e. the primes tuple offsets, each separated by a comma. Default: 0, 4, 2, 4, 2, 4 (values for Riecoin mining);
* PN : Primorial Number for the Wheel Factorization. Default: 40;
* POff : List of offsets from the Primorial for the first number in the prime tuple. Default: 4209995887, 4209999247, 4210002607, 4210005967, 7452755407, 7452758767, 7452762127, 7452765487
* ConsType : set your Constellation Type, i. e. the primes tuple offsets, each separated by a comma. Default: 0, 4, 2, 4, 2, 4 (values for Riecoin mining).
* POff : list of Offsets from the Primorial for the first number in the prime tuple. Same syntax as ConsType. Default: 4209995887, 4209999247, 4210002607, 4210005967, 7452755407, 7452758767, 7452762127, 7452765487.

Some possible constellations types (format: (type) -> offsets to put in the config file ; 3 first constellations (n + 0) which can be used as offsets, though some might not work)
Some possible constellations types (format: (type) -> offsets to put for ConsType ; 3 first constellations (n + 0) which can be used for POff, though some might not work)

* 5-tuples
* (0, 2, 6, 8, 12) -> 0, 2, 4, 2, 4 ; 5, 11, 101,...
Expand All @@ -156,7 +174,7 @@ Some possible constellations types (format: (type) -> offsets to put in the conf

Also see the constellationsGen tool in my rieTools repository (https://github.com/Pttn/rieTools).

Note that you must use different tuples counts files if you use different constellations types, and you should also if you use different Sieve sizes, to not skew the stats.
Note that you must use different tuples counts files if you use different constellations types.

### Memory problems

Expand Down Expand Up @@ -253,7 +271,7 @@ The miner will disconnect if it did not receive anything during 3 minutes (time

## Benchmarking

rieMiner provides a way to test the performance of a computer, and compare with others. This feature can also be used to appreciate the improvements when trying to improve the miner algorithm. When sharing benchmark results, you must always communicate the difficulty, the sieve size, the test duration, the CPU model, the memory speeds (frequency and CL), the miner version, and the OS.
rieMiner provides a way to test the performance of a computer, and compare with others. This feature can also be used to appreciate the improvements when trying to improve the miner algorithm. When sharing benchmark results, you must always communicate the difficulty, the sieve size, the test duration, the CPU model, the memory speeds (frequency and CL), the miner version, and the OS. Also, do not forget to precise if you changed other options, like the SieveWorkers or Bits.

To compare two different platforms, you must absolutely test with the same difficulty, during enough time. The proposed parameters, conditions and interpretations for serious benchmarking are:

Expand Down
6 changes: 2 additions & 4 deletions WorkManager.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// (c) 2017-2018 Pttn (https://github.com/Pttn/rieMiner)

#ifndef HEADER_WorkManager_h
#define HEADER_WorkManager_h

#define minerVersionString "rieMiner 0.9-RC1"
#ifndef HEADER_WorkManager_hpp
#define HEADER_WorkManager_hpp

#include "main.hpp"
#include "Stats.hpp"
Expand Down
5 changes: 3 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ void Options::loadConf() {
else std::cout << "Will submit 4-shares" << std::endl;
std::cout << "Stats refresh rate = " << _refresh << " s" << std::endl;
if (_tcFile != "None") std::cout << "Tuple Count File = " << _tcFile << std::endl;
std::cout << "Primorial Number = " << _pn << std::endl;
std::cout << "Primorial Offset = " << "(";
std::cout << "Primorial Number = " << _pn << std::endl;
std::cout << "Primorial Offsets = " << "(";
for (std::vector<uint64_t>::size_type i(0) ; i < _pOff.size() ; i++) {
std::cout << _pOff[i];
if (i != _pOff.size() - 1) std::cout << ", ";
Expand All @@ -313,6 +313,7 @@ void Options::loadConf() {
if (i != _consType.size() - 1) std::cout << ", ";
}
std::cout << "), length " << _consType.size() << std::endl;
std::cout << "Sieve bits = " << _sieveBits << std::endl;
}

void signalHandler(int signum) {
Expand Down
5 changes: 2 additions & 3 deletions main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#ifndef HEADER_main_hpp
#define HEADER_main_hpp

#define minerVersionString "rieMiner 0.9-RC1"
#define minerVersionString "rieMiner 0.9RC2"

#include <unistd.h>
#include <string>
Expand All @@ -22,8 +22,7 @@

class Options {
std::string _host, _user, _pass, _protocol, _address, _tcFile;
uint8_t _tuples, _sieveBits;
uint16_t _port, _threads, _sieveWorkers;
uint16_t _tuples, _sieveBits, _port, _threads, _sieveWorkers;
uint32_t _refresh, _testDiff, _testTime, _test2t;
uint64_t _sieve, _pn;
uint64_t _maxMem;
Expand Down

0 comments on commit 21c1a1e

Please sign in to comment.