etherchain-org / qtminer

Stratum enabled Ethereum miner
MIT License
52 stars 38 forks source link

Blockchain Formation qtminer: Performance #1

Open efaysal opened 8 years ago

efaysal commented 8 years ago

I'm in processing reading your code ( more to come once I have more time to write all my observations).

As now Farm from C++ Ethereum is used throught QT Signal and Slot ( this needs more deep reading). Using them instead of while and loop in doFARM function in class MinerAux seems a very good alternative. Also the encapsulation of the solution process inside the Lambda function is very neat.

However a potential issue remains always: the current work-package will be updated while the solution is processed in the Lambda. The functor passed into f.onSolutionFound will use an argument sol which is indeed the right solution for the "current" ... The only big problem is in the mean-time the "current" have been updated by a new workplace and it's a "new current" not really associated to the founded argument sol ... Your emit solutionFound () has two data the sol for the old current mixed with the new updated current.

I will have more details about this once I finish my total review of the used alternatives ( QTimer and so on.). Qtimer's accuracy and sensitivity will certainly depend on the underlying operating system and hardware and also on the nature of the current update and the used mining process.

I got a long discussion with Go Ethereum about how eth_getwork is working, see https://gitter.im/ethereum/go-ethereum, spot efaysal oct 06 02:09.

JSON RPC eth_getWork returns the hash of the current block, the seedHash, and the boundary condition to be met ("target"). This function is used in C++ Ethereum to update the workpackage and it's only Go-implemented or coded. The "current block" is NOT necessarily the network’s current block.

The elimination of the while(true) and loop is a fact now, you can just suppress this

unsigned _recheckPeriod = 500;

Try to have a look into https://github.com/ethereum/cpp-ethereum/issues/2985

An analysis have been conducted to figure out the effect of _recheckPeriod. As now is not used any more that may be good for the performance.

Also:

In the function overrided function workLoop() in Class EthashCPUMiner, the nonce initialized randomly : uint64_t tryNonce = (uint64_t)(u64)Nonce::random(s_eng);

In the loop the nonce will be incremented till a solution is defined.

Why the trynonce is not again selected randomly inside the loop instead of just incrementing by one?

In Go Ethereum, the nonce is defined randomly as sha := uint64(r.Int63()) if verify(hash, diff, sha)

inside a loop incremented using a start i := rand.Int63(), starti := i, but the nonce is defined randomly!

Here, why Go and C++ used two ways to define the nonce, which one is providing worst performance or better performance?

It's better to override that function and make the nonce selected randomly. It's very important for the performance of the pool, as each miner is mining using a random nonce. If the nonce is just incremented, it may happen that many of the miners are overlapping their calculations in vain.

Let's give an example, 3 miners in your pool working on the same workpackage:

Miner_1 used nonce 1, and is incrementing it till a solution will be reach.

Miner_2 used nonce 2 =nonce 1 + some number, and is incrementing it till a solution will be reach.

Miner_3 used nonce 3 =nonce 2 + some number, and is incrementing it till a solution will be reach.

Assume that the right nonce is greater than nonce 3. Using incrementation, the miner's performance is mainly depending on the first random draw of the nonce and the incrementation is not necessary working for the best performance, Miners 1 and 2 have to overcome many incrementation to reach the right nonce which is greater than nonce 3 > nonce 2 > nonce 1.

Miner 3 is more lucky with the incrementation.

In general, if the nonce is randomly selected, the miner is not trapped in a narrow specific incrementation that only depend on the first draw ...

I will add more comments as soon as I have a holistic review of all the designed points.

etherchain-org commented 8 years ago

Thanks for your review.

_recheckPeriod is just a leftover from the original code, it is unused at the moment.

Regarding nonce selection, as the hash function should follow a uniform distribution it should not matter if you select a random nonce and increment onwards or select a random value after each increment, the chance of finding a solution should be the same.

efaysal commented 8 years ago

FYI, the Go Ethereum is using random selected nonce inside the loop. If you can collect the observed nonces in Go and C++ Ethereum , we can conduct a kind of statistical assessment for selecting the nonce. A file with the following: BlockNumber, Blocktime, Nonce, Softwareused, Size, any other features if possible.

Thanks.