Skip to content
This repository has been archived by the owner on Apr 24, 2022. It is now read-only.

Another huge batch #1751

Merged
merged 81 commits into from
Dec 6, 2018
Merged

Another huge batch #1751

merged 81 commits into from
Dec 6, 2018

Conversation

AndreaLanfranchi
Copy link
Collaborator

@AndreaLanfranchi AndreaLanfranchi commented Dec 5, 2018

A lot of rework

This PR is the result of voluntary rework on many parts of the code to deduplicate as much as possible and give common functions some more usability

Api Interface

I've managed to unify json socket api interface with http interface. This helps to keep only one listening endpoint and removes the dependency from MONGOOSE external project.
The implementation can be now easily extended to support all API methods with GET and POST http verbs. (original idea from #1163)

Due to the recently inserted device abstraction we're now able to expose PCI id in both API calls and Http stats output along with the mode the device has been subscribed (cuda/openCL). (see #1012)

image

Note in this sample the power drain is not displayed as Nvidia Gtx 1050 Ti does not allow this feature but for other GPUs the power drain is reported correctly if proper -HWMON value is set.

To get the Http info page you have to point to the very same endpoint of your API interface. The page auto-refreshes every 10 seconds.

The API call miner_getstatHr have been dropped (it was only ethminer's) and the new and extended miner_getstatdetail now produces this output

{
  "id": 0,
  "jsonrpc": "2.0",
  "result": {
    "connection": {                                     // Current active connection
      "connected": true,
      "switches": 1,
      "uri": "stratum1+tls12://<ethaddress>[email protected]:5555"
    },
    "devices": [                                        // Array subscribed of devices
      {
        "_index": 0,                                    // Miner ordinal 
        "_mode": "CUDA",                                // Miner mode : "OpenCL" / "CUDA"
        "hardware": {                                   // Device hardware info
          "name": "GeForce GTX 1050 Ti 3.95 GB",        // Name
          "pci": "01:00.0",                             // Pci Id
          "sensors": [                                  // An array made of ...
            47,                                         //  + Detected temp
            70,                                         //  + Fan percent
            0                                           //  + Power drain in watts
          ],
          "type": "GPU"                                 // Device Type : "CPU" / "GPU" / "ACCELERATOR"
        },
        "mining": {                                     // Mining info
          "hashrate": "0x0000000000e3fcbb",             // Current hashrate in hashes per second
          "pause_reason": null,                         // If the device is paused this contains the reason
          "paused": false,                              // Wheter or not the device is paused
          "segment": [                                  // The search segment of the device
            "0xbcf0a663bfe75dab",                       //  + Lower bound
            "0xbcf0a664bfe75dab"                        //  + Upper bound
          ],
          "shares": [                                   // Shares / Solutions stats
            1,                                          //  + Found shares
            0,                                          //  + Rejected (by pool) shares
            0,                                          //  + Failed shares (always 0 if --no-eval is set)
            15                                          //  + Time in seconds since last found share
          ]
        }
      },
      { ... }                                           // Another device
      { ... }                                           // And another ...
    ],
    "host": {
      "name": "miner01",                                // Host name of the computer running ethminer
      "runtime": 121,                                   // Duration time (in seconds)
      "version": "ethminer-0.18.0-alpha.1+commit.70c7cdbe.dirty"
    },
    "mining": {                                         // Mining info for the whole instance
      "difficulty": 3999938964,                         // Actual difficulty in hashes
      "epoch": 227,                                     // Current epoch
      "epoch_changes": 1,                               // How many epoch changes occurred during the run
      "hashrate": "0x00000000054a89c8",                 // Overall hashrate (sum of hashrate of all devices)
      "shares": [                                       // Shares / Solutions stats
        2,                                              //  + Found shares
        0,                                              //  + Rejected (by pool) shares
        0,                                              //  + Failed shares (always 0 if --no-eval is set)
        15                                              //  + Time in seconds since last found share
      ]
    },
    "monitors": {                                       // A nullable object which may contain some triggers
      "temperatures": [                                 // Monitor temperature
        60,                                             //  + Resume mining if device temp is <= this threshold
        75                                              //  + Suspend mining if device temp is >= this threshold
      ]
    }
  }
}

This PR contains also integration to documentation.

Solution submission

I've discovered that each miner having it's own strand in it's own thread could have lead to collisions while submitting. I managed to have each miner submit to Farm's strand so the solution submission to socket is guaranteed to be serialized with the benefit of an overhead reduction due to only one relevant strand instead of one per miner. (less work for the io_service).

Solution and stats data accounting

Until now all accounting operations were somewhat disorganized (technically there was one vector for each type of information to be collected (solutions and their conditions, hashrates, status of miners) which also implied there were several functions to call to pull data from farm. In addition all vectors where increased dynamically with a lot of checks like if (vector.size() < index).
I've reworked all accounting under a single structure TelemetryType which holds several members of TelemetryAccountType which is initialized with room for each miner thread.
Each structure type has it's own str() method which helps to remove a lot of definition for operator << while allowing to treat the output as strings.

Terminal logging

The output of the rework appears like this (with LOG_PER_GPU) enabled

 m 17:49:46 ethminer 0:25 A30 88.22 Mh { cu0 14.75 48C 70% A9 | cu1 14.75 46C 70% A0 | cu2 14.74 51C 70% A4 | cu3 14.66 55C 70% A5 | cu4 14.58 56C 70% A5 | cu5 14.74 55C 70% A7 }
 m 17:49:51 ethminer 0:25 A30 88.22 Mh { cu0 14.75 48C 70% A9 | cu1 14.75 45C 70% A0 | cu2 14.74 51C 70% A4 | cu3 14.66 55C 70% A5 | cu4 14.57 56C 70% A5 | cu5 14.74 55C 70% A7 }
 i 17:49:53 ethminer Job: #34597da8… block 6831664 eu1.ethermine.org  [172.65.207.106:5555]
 m 17:49:56 ethminer 0:25 A30 88.22 Mh { cu0 14.75 48C 70% A9 | cu1 14.75 46C 70% A0 | cu2 14.74 51C 70% A4 | cu3 14.66 55C 70% A5 | cu4 14.57 56C 70% A5 | cu5 14.74 55C 70% A7 }
 m 17:50:01 ethminer 0:26 A30 88.22 Mh { cu0 14.75 48C 70% A9 | cu1 14.75 45C 70% A0 | cu2 14.74 51C 70% A4 | cu3 14.66 55C 70% A5 | cu4 14.57 56C 70% A5 | cu5 14.74 55C 70% A7 }
 m 17:50:06 ethminer 0:26 A30 88.21 Mh { cu0 14.75 48C 70% A9 | cu1 14.75 46C 70% A0 | cu2 14.74 51C 70% A4 | cu3 14.66 55C 70% A5 | cu4 14.57 56C 70% A5 | cu5 14.74 55C 70% A7 }
 m 17:50:11 ethminer 0:26 A30 88.22 Mh { cu0 14.75 48C 70% A9 | cu1 14.75 46C 70% A0 | cu2 14.74 51C 70% A4 | cu3 14.66 55C 70% A5 | cu4 14.57 56C 70% A5 | cu5 14.74 55C 70% A7 }
cu 17:50:13 cuda-5   Job: #34597da8… Sol: 0x4a2728c28f4ddd83
 i 17:50:13 ethminer **Accepted  53 ms. eu1.ethermine.org  [172.65.207.106:5555]
 m 17:50:16 ethminer 0:26 A31 88.22 Mh { cu0 14.75 48C 70% A9 | cu1 14.75 45C 70% A0 | cu2 14.74 51C 70% A4 | cu3 14.66 55C 70% A5 | cu4 14.57 56C 70% A5 | cu5 14.74 55C 70% A8 }

The first 3 chunks of the log line are

  1. Run duration
  2. Overall solutions detail (same format Ax:Wx:Rx:Fx) where A means accepted, W means wasted (solutions produced when there is no connection available - eg. during a switch), R means rejected, F means failed (only if --no-eval is not set)
  3. Actual hashing speed

In curly braces (array) the detail for each miner which is now labelled by a more significant cu/cl prefix (cuda or opencl) instead of the previous generic "gpu"
Each miner reports it's hashing speed (with the same order of magnitude of the overall hashing speed -ie if the farm speed is in Mh then all miner's speeds are in Mh too), the sensors values (if --HWMON) and the detail of their solutions (if LOG_PER_GPU) : this latter removes the need for a double line printout. (see #1605)

AndreaLanfranchi and others added 30 commits November 29, 2018 12:00
When solution is found also output the job it refers.
List of devices is a space separated list.
Also enforce usage of diff in genesis block for benchmark
Also enforce usage of diff in genesis block for benchmark
Simulation and benchmark are de-facto the same thing.
User can test hashing speed using simulation.
It's assumed difficulty 1 (roughly 4.3 GH/s)

Note ! Data exposed by benchmark (now removed) were also wrong as the "min" and "max" values exposed were in reality the first and the last collected value.
This reverts commit 885d8e0.
Allocating the (current ~3GB) DAG needs 5 sec in my environment.
This patch reuses the already allocated memory if possible.
 * some optimization using lop3
 * use ROL8/ROR8 for some cases
Use single strand from farm instead of having multiple strands (one per miner) which may collide)
{
Guard l(m_activeConnectionMutex);
Copy link
Collaborator

@StefanOberhumer StefanOberhumer Dec 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why removed ? Preventing another API call modifying connections the same time or switching to next failoverpool while we change connections

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a test commit nevertheless all mutexes are not necessary as the API lives in the same thread. There is only one thread for all which is not a miner

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other words ethminer threads are (1 + device number)

Copy link
Collaborator

@StefanOberhumer StefanOberhumer Dec 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory (correct me if I'm wrong)

  • there could be more than one API connection
  • API could "half" added the connection (means: size of URI vectors increased but URI content not copied) while poolmanager tries to use next (not fully filled) connection

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All actions from any number of API connections are executed serialized by io_service.
There is no concurrency to worry about. There's to worry about asynchrony. What can happen is that a call (eg. Setactiveconnection) does not complete it's whole cycle before another call kicks in

@@ -247,10 +247,11 @@ void PoolManager::stop()
DEV_BUILD_LOG_PROGRAMFLOW(cnote, "PoolManager::stop() end");
}

void PoolManager::addConnection(URI& conn)
void PoolManager::addConnection(URI& _conn)
Copy link
Collaborator

@StefanOberhumer StefanOberhumer Dec 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be enough to change function to void PoolManager::addConnection(URI conn) { (just removed reference) ?

@StefanOberhumer
Copy link
Collaborator

Could we clang-format (now all sources - see #1712 ) before merge ?

@StefanOberhumer
Copy link
Collaborator

StefanOberhumer commented Dec 5, 2018

Counting solutions:
Not sure but I think with this commit we count per miner and also the totals of (eg rejected) solutions.
As the increments are not guarded it could be possible that the sum of all miners will not match the total sum.
I think in current version I tried to compute the totals "on the fly" by summing all miner stats to prevent such a difference and tried not using a lock.

@AndreaLanfranchi
Copy link
Collaborator Author

Again. No need to guard increments as they come from a single serialized strand.

@ghost
Copy link

ghost commented Dec 6, 2018

Can you rebase your commits with master branch?

@AndreaLanfranchi
Copy link
Collaborator Author

@naikmyeong this is master branch

Copy link
Collaborator

@StefanOberhumer StefanOberhumer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As consequence I'll remove adapted documentation from #1743

@MariusVanDerWijden MariusVanDerWijden merged commit 6e8252f into ethereum-mining:master Dec 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants