1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-07 07:55:04 -05:00

Compare commits

...

195 Commits

Author SHA1 Message Date
XMRig
4c5421b2bf v6.4.0 2020-10-19 03:21:04 +07:00
XMRig
6dd281b508 Merge branch 'dev' 2020-10-19 03:20:21 +07:00
xmrig
599958c982 Update CHANGELOG.md 2020-10-18 02:10:03 +07:00
XMRig
328f985e07 Added Benchmark class. 2020-10-17 04:03:42 +07:00
XMRig
7fc7b976bf Removed m_bench field from Job class. 2020-10-16 20:29:11 +07:00
XMRig
36b1523194 Code cleanup. 2020-10-16 19:35:36 +07:00
XMRig
5155139e9a Improve some benchmark log messages. 2020-10-16 04:11:50 +07:00
XMRig
a152d6be42 Added CMake option WITH_BENCHMARK. 2020-10-16 02:18:07 +07:00
xmrig
ccebf6bb20 Merge pull request #1901 from cohcho/fix_math1
WorkerJob: fix calls of add/nextRound
2020-10-15 22:29:20 +07:00
cohcho
5b4648339a WorkerJob: fix calls of add/nextRound
WorkerJob::nextRound() doesn't require roundSize to be power of 2
Use CudaWorker::intensity(), OclWorker::intensity() to get device batch size
Sync nonce and device iteration
2020-10-15 14:56:37 +00:00
xmrig
7727014eea Merge pull request #1900 from SChernykh/dev
Fixed roundSize() usage in OCL/CUDA
2020-10-15 19:44:03 +07:00
SChernykh
8c45e3226d Fixed roundSize() usage in OCL/CUDA 2020-10-15 14:39:54 +02:00
xmrig
75403ee275 Merge pull request #1899 from SChernykh/dev
Make round size power of 2
2020-10-15 19:33:32 +07:00
SChernykh
c4db1435b2 Make round size power of 2 2020-10-15 14:29:15 +02:00
xmrig
f3ea3c5227 Merge pull request #1897 from SChernykh/dev
Benchmark: added more check hashes and a progress indicator
2020-10-15 15:08:33 +07:00
SChernykh
722e468bd9 Benchmark: added more check hashes and a progress indicator 2020-10-15 08:23:47 +02:00
xmrig
9569772e7e Merge pull request #1895 from SChernykh/dev
Added benchmark and stress test
2020-10-15 02:16:37 +07:00
SChernykh
144f9c4409 Fixed compile errors in Linux 2020-10-14 21:03:21 +02:00
SChernykh
2ecece7b3d Added benchmark and stress test
Easy to use and zero configuration embedded benchmark/stress test.
2020-10-14 19:45:05 +02:00
xmrig
677d287135 Merge pull request #1893 from cohcho/fix_partial_read
LineReader: fix partial read
2020-10-14 14:47:51 +07:00
XMRig
62eb66486d Added copyright. 2020-10-13 23:27:47 +07:00
cohcho
da03d74ade LineReader: fix partial read 2020-10-13 16:11:39 +00:00
xmrig
9fcc542676 Merge pull request #1889 from cohcho/fix_uv_issue
uv: fix performance issue
2020-10-13 22:35:29 +07:00
xmrig
581d004568 Merge pull request #1890 from SChernykh/dev
Added argon2/chukwav2 algorithm
2020-10-13 14:54:34 +07:00
SChernykh
4f7186cb0e Added argon2/chukwav2 algorithm
New Turtlecoin algorithm. Source: https://github.com/turtlecoin/turtlecoin/blob/development/src/crypto/hash.h#L57
2020-10-12 08:26:57 +02:00
cohcho
65fa1d9bf3 uv: fix performance issue
unix implementation of uv_async_t has been wasting cpu cycles for nothing since 1.29.0 release
implement efficient callback scheduling for linux
2020-10-12 04:09:09 +00:00
xmrig
f85efd163c Merge pull request #1887 from SChernykh/dev
Fixed total hashrate update
2020-10-10 22:07:37 +07:00
xmrig
eb8cf3ee5a Merge pull request #1886 from cohcho/fix_cpu_stats
CPU: use raw counter
2020-10-10 22:07:23 +07:00
SChernykh
793a2454ad Fixed total hashrate update
Don't add data points where one of the threads doesn't have hashrate data yet.
2020-10-10 17:00:30 +02:00
cohcho
4a74ce3242 CPU: use raw counter 2020-10-10 13:28:14 +00:00
xmrig
87a54766eb Merge pull request #1885 from SChernykh/dev
More precise hashrate calculation
2020-10-10 16:35:14 +07:00
SChernykh
22a69f70da Fix HashrateInterpolator::addDataPoint 2020-10-10 11:22:19 +02:00
SChernykh
3fbf2ac3d4 More precise hashrate calculation
- Use only steady timestamp counters to guarantee correctness
- CPU backend: directly measure total hashrate using raw hash counters from each thread; update data more often on ARM CPUs because they're slower
- GPU backends: directly measure total hashrate too, but use interpolator with 4 second lag to fix variance from batches of hashes

Total hashrate is now measured directly (realtime for CPU, 4 seconds lag for GPU), so it might differ a bit from the sum of all thread hashrates because data points are taken at different moments in time.

Overhead is reduced a lot since it doesn't have to go through all threads to calculate max total hashrate on every timer tick (2 times a second).
2020-10-10 11:18:01 +02:00
xmrig
0a2fe5caa7 Merge pull request #1882 from cohcho/fix_atomic_init
Worker: specify default value
2020-10-09 21:35:34 +07:00
cohcho
17795e3d7b Worker: specify default value 2020-10-09 14:28:36 +00:00
xmrig
1fdc8631e3 Merge pull request #1881 from SChernykh/dev
Fix possible race condition in hashrate counting code
2020-10-09 19:47:36 +07:00
SChernykh
858463ceba Change to fetch_xor to make code simpler 2020-10-09 11:50:11 +02:00
SChernykh
a4550f55ea Fix possible race condition in hashrate counting code
Use single atomic operation to switch between data points.
2020-10-09 10:29:18 +02:00
xmrig
d9b6f46a6a Merge pull request #1879 from SChernykh/dev
Fix 32-bit compilation
2020-10-07 23:22:14 +07:00
SChernykh
4bac3e7695 Fix 32-bit compilation 2020-10-07 18:19:35 +02:00
xmrig
59bd6d4187 Merge pull request #1878 from SChernykh/dev
Fixed ARM compilation
2020-10-07 23:11:39 +07:00
SChernykh
166c011d37 Fixed ARM compilation 2020-10-07 18:09:42 +02:00
xmrig
1f55c6eb02 Merge pull request #1877 from SChernykh/dev
Fix FreeBSD compilation
2020-10-07 23:03:07 +07:00
SChernykh
c2bdae70fe Fix FreeBSD compilation 2020-10-07 18:00:36 +02:00
xmrig
1289942567 Merge pull request #1876 from SChernykh/dev
RandomX: added `huge-pages-jit` config parameter
2020-10-07 22:48:57 +07:00
SChernykh
44dcded866 RandomX: added huge-pages-jit config parameter
Set to false by default, gives 0.2% boost on Ryzen 7 3700X with 16 threads, but hashrate might be unstable on Ryzen between launches. Use with caution.
2020-10-07 17:42:55 +02:00
xmrig
8deb247b3e Merge pull request #1875 from cohcho/fix_alignment
RandomX: align args
2020-10-07 22:42:22 +07:00
cohcho
a705ab775b RandomX: align args
tempHash/output must be 16-byte aligned for randomx_calculate_hash{,_first,_next}
2020-10-07 14:47:18 +00:00
xmrig
bfd5a81937 Merge pull request #1874 from cohcho/fix_vm_create1
RxVM: fix compilation error
2020-10-07 18:16:59 +07:00
cohcho
c710ee5fb5 RxVM: fix compilation error 2020-10-07 09:27:25 +00:00
SChernykh
a8466a139c RandomX: allocate 2 MB pages for generated code, if possible
+0.2% boost on Ryzen 7 3700X
2020-10-07 10:35:10 +02:00
xmrig
ba47219185 Merge pull request #1870 from cohcho/fix_miner_state_machine
Miner: fix state machine
2020-10-07 12:25:17 +07:00
xmrig
cf54c85b76 Merge pull request #1872 from cohcho/fix_vm_create
RxVm: fix randomx_create_vm call
2020-10-07 12:22:54 +07:00
cohcho
fa5b872782 RxVm: fix randomx_create_vm call
randomx_create_vm requires either cache or dataset, but not both
2020-10-06 19:45:43 +00:00
cohcho
3ee0cd8c51 Miner: fix state machine
Remove unexpected resume due to disconnect during dataset init
2020-10-06 13:34:19 +00:00
cohcho
7bdeba4d08 Nonce: refactor static init 2020-10-06 13:34:19 +00:00
xmrig
116fb3d3f9 Merge pull request #1864 from cohcho/soft_aes_optimization2
soft_aes: fix previous optimization
2020-10-05 12:20:41 +07:00
xmrig
54a17a75ab Merge pull request #1862 from SChernykh/dev
RandomX: removed rx/loki
2020-10-05 12:19:43 +07:00
cohcho
5f0f2506e8 soft_aes: fix previous optimization
Previously removed unrolled variant is faster on some CPUs
Some CPUs are faster with added unrolled variant
The best variant depends on number of threads on some CPUs
2020-10-04 14:47:58 +00:00
XMRig
31e896feef v6.4.0-dev 2020-10-03 13:49:40 +07:00
XMRig
8bfd7bcf05 Merge branch 'master' into dev 2020-10-03 13:48:22 +07:00
XMRig
ec13337228 v6.3.5 2020-10-03 11:48:34 +07:00
XMRig
cfe2a098ce Merge branch 'dev' 2020-10-03 11:47:07 +07:00
xmrig
a89c2c8dd1 Update CHANGELOG.md 2020-10-02 22:39:26 +07:00
SChernykh
ebf259fa7c RandomX: removed rx/loki
Loki forks to PoS on October 9th.
2020-10-02 17:02:52 +02:00
XMRig
1b4a124bc5 Fix x86 build. 2020-10-01 17:46:05 +07:00
XMRig
4bb8be8a29 Merge branch 'ph4r05-pr/001-with-sse' into dev 2020-10-01 11:00:52 +07:00
XMRig
d45bb24a32 Renamed WITH_SSE to WITH_SSE4_1 and make it work on all platforms. 2020-10-01 11:00:08 +07:00
Dusan Klinec
5a7bcb2d03 fies #1844, adds WITH_SSE cmake option
now it is possible to disable sse for Blake2, which is not supported on ARMs
2020-09-30 20:09:54 +02:00
xmrig
f1ec8a18f6 Merge pull request #1859 from SChernykh/dev
RandomX: optimized soft AES code
2020-09-30 09:01:45 +07:00
SChernykh
7b4f768114 RandomX: optimized soft AES code
Unrolled loop was 5-10% slower depending on CPU.
2020-09-29 21:22:11 +02:00
xmrig
dfab81e9fa Merge pull request #1858 from SChernykh/dev
RandomX: removed duplicate constants in Blake2b
2020-09-27 16:51:03 +07:00
SChernykh
3025c265e8 RandomX: removed duplicate constatns in Blake2b 2020-09-27 11:50:08 +02:00
xmrig
ee603ab9e2 Merge pull request #1857 from SChernykh/dev
RandomX: isolate SSE4.1 code to fix crashes on old CPUs
2020-09-27 16:47:56 +07:00
SChernykh
84f8a0dc54 RandomX: isolate SSE4.1 code to fix crashes on old CPUs 2020-09-27 11:46:32 +02:00
xmrig
481deff163 Merge pull request #1856 from SChernykh/dev
Fixed SSE4.1 for old CPUs
2020-09-27 14:01:34 +07:00
SChernykh
0e9ed351a1 Fixed SSE4.1 for old CPUs
Enable SSE4.1 only where it's needed.
2020-09-27 08:55:57 +02:00
xmrig
8952f6892d Merge pull request #1852 from cohcho/fix_string
String: distinguish nullptr/empty str
2020-09-27 07:56:33 +07:00
xmrig
d51fe01273 Merge pull request #1849 from cohcho/soft_aes_optimization1
soft_aes: fix previous optimization
2020-09-27 07:56:03 +07:00
cohcho
f7d6348948 String: distinguish nullptr/empty str 2020-09-26 16:41:15 +00:00
xmrig
3a01ebe277 Merge pull request #1850 from cohcho/filter_invalid_algos
Miner: filter invalid algos
2020-09-26 15:15:23 +07:00
cohcho
189cc78d44 Miner: filter invalid algos 2020-09-25 17:52:13 +00:00
cohcho
9be3b69109 soft_aes: fix previous optimization
the best order of hash/fill/prefetch depends on hw/soft AES
only hw AES is faster after previous optimization
2020-09-25 15:26:19 +00:00
xmrig
7b38af703e Merge pull request #1846 from SChernykh/dev
KawPow: fixed OpenCL memory leak
2020-09-25 15:55:36 +07:00
SChernykh
bef9031b03 KawPow: fixed OpenCL memory leak 2020-09-25 10:53:24 +02:00
xmrig
e4929d7c06 Merge pull request #1845 from SChernykh/dev
Fix for ARM compilation
2020-09-23 16:48:08 +07:00
SChernykh
1e26e58660 Fix for ARM compilation 2020-09-23 11:44:08 +02:00
XMRig
8fe0577d60 v6.3.5-dev 2020-09-23 08:06:28 +07:00
XMRig
64f42feba9 Merge branch 'master' into dev 2020-09-23 08:05:58 +07:00
XMRig
36ed0b4309 v6.3.4 2020-09-23 06:00:07 +07:00
XMRig
cb0bba7e10 Merge branch 'dev' 2020-09-23 05:59:35 +07:00
xmrig
51a72afb0e Update CHANGELOG.md 2020-09-23 05:29:29 +07:00
xmrig
b1b0a3ba95 Merge pull request #1843 from SChernykh/dev
RandomX improved performance of GCC compiled binaries
2020-09-23 04:44:47 +07:00
SChernykh
9768bf65d1 RandomX improved performance of GCC compiled binaries
JIT compilator was slower compared to MSVC compiled binary. Up to +0.1% speedup on rx/wow in Linux.
2020-09-22 13:48:11 +02:00
xmrig
1584cca6d1 Merge pull request #1842 from SChernykh/dev
RandomX: AES improvements
2020-09-22 03:13:23 +07:00
SChernykh
891a46382e RandomX: AES improvements
- A bit faster hardware AES code when compiled with MSVC
- More reliable software AES benchmark
2020-09-21 17:51:08 +02:00
xmrig
db920e8006 Merge pull request #1841 from SChernykh/dev
Fixed Cryptonight OpenCL for AMD 20.7.2 drivers
2020-09-20 04:14:49 +07:00
SChernykh
768a4581e0 Fixed Cryptonight OpenCL for AMD 20.7.2 drivers
Vega 64 + Windows 10 + AMD 20.7.2 drivers were broken on Cryptonight algorithms.
2020-09-19 23:12:05 +02:00
xmrig
866245b525 Merge pull request #1840 from SChernykh/dev
RandomX refactoring, moved more stuff to compile time
2020-09-19 02:01:06 +07:00
SChernykh
c7476e076b RandomX refactoring, moved more stuff to compile time
Small x86 JIT compiler speedup.
2020-09-18 20:51:25 +02:00
xmrig
d11a313d88 Merge pull request #1835 from SChernykh/dev
RandomX: returned old soft AES impl and auto-select between the two
2020-09-16 01:54:40 +07:00
SChernykh
8d1168385a RandomX: returned old soft AES impl and auto-select between the two 2020-09-15 20:48:27 +02:00
xmrig
852fe14604 Merge pull request #1831 from cohcho/nonce_iteration_without_tests
reserve at most 1 bit for wrapping detection
2020-09-14 02:12:49 +07:00
cohcho
30be1cd102 reserve at most 1 bit for wrapping detection 2020-09-13 18:42:16 +00:00
xmrig
fa0bb0e1bf Merge pull request #1830 from SChernykh/dev
RandomX: added performance profiler (for developers)
2020-09-13 04:38:03 +07:00
SChernykh
a05393727c RandomX: added performance profiler (for developers)
Also optimized Blake2b SSE4.1 code size to avoid code cache pollution.
2020-09-12 23:07:52 +02:00
xmrig
adf833b60a Merge pull request #1827 from cohcho/nonce_iteration_without_tests
nonce iteration optimization
2020-09-10 19:33:23 +07:00
xmrig
23daceb4dc Merge pull request #1828 from SChernykh/dev
RandomX: added SSE4.1-optimized Blake2b
2020-09-10 19:31:51 +07:00
SChernykh
4a9db89527 RandomX: added SSE4.1-optimized Blake2b
+0.15% on `rx/0`
+0.3% on `rx/wow`
2020-09-10 14:28:40 +02:00
cohcho
060c1af4c4 fix nonce mask 2020-09-09 19:39:52 +00:00
cohcho
b826985d05 nonce iteration optimization
efficient and correct nonce iteration without duplicates
2020-09-09 10:03:37 +00:00
xmrig
0f09883429 Merge pull request #1823 from SChernykh/dev
RandomX: added parameter for scratchpad prefetch mode
2020-09-04 21:31:18 +07:00
SChernykh
a84b45b1bb RandomX: added parameter for scratchpad prefetch mode
`scratchpad_prefetch_mode` can have 4 values:
0: off
1: use `prefetcht0` instruction (default, same as previous XMRig versions)
2: use `prefetchnta` instruction (faster on Coffee Lake and a few other CPUs)
3: use `mov` instruction
2020-09-04 16:16:07 +02:00
XMRig
a5b6383f7b v6.3.4 2020-08-28 23:50:16 +07:00
XMRig
24f8f76714 Merge branch 'master' into dev 2020-08-28 23:49:47 +07:00
XMRig
ba336122c0 v6.3.3 2020-08-28 21:39:26 +07:00
XMRig
591744174c Merge branch 'dev' 2020-08-28 21:38:55 +07:00
xmrig
fc85017948 Update CHANGELOG.md 2020-08-28 21:25:26 +07:00
xmrig
24f541a0dd Update README.md 2020-08-26 23:09:05 +07:00
XMRig
f552577e71 Merge branch 'dev' of github.com:xmrig/xmrig into dev 2020-08-26 16:11:48 +07:00
XMRig
a06ec06e8b Fix colors on macOS. 2020-08-26 16:11:29 +07:00
xmrig
96833d4790 Merge pull request #1817 from SChernykh/dev
Fixed self-select login sequence
2020-08-25 21:23:19 +07:00
SChernykh
5611ae9a30 Fixed self-select login sequence
In self-select mode, we only have pool wallet right after login.
2020-08-25 16:17:48 +02:00
XMRig
72c8404d18 Fix compile warnings. 2020-08-24 10:04:46 +07:00
XMRig
bc128d11d9 Add strip for clang. 2020-08-23 23:48:05 +07:00
XMRig
ff13675d31 Improved CUDA loader error reporting and fixed plugin load on Linux. 2020-08-23 21:30:12 +07:00
XMRig
4b682b6633 Better scripts/build.*.sh compatibility. 2020-08-23 15:46:56 +07:00
XMRig
879e160ba3 Fix compile warning. 2020-08-23 14:22:08 +07:00
XMRig
9a6b8594f3 Removed bzip2 dependency for hwloc build. 2020-08-21 09:14:22 +07:00
XMRig
a354e9d217 Fixed tag in OclLib. 2020-08-21 08:21:51 +07:00
XMRig
950b5fa75e Disable GPU backends with static build on Linux. 2020-08-20 15:02:31 +07:00
XMRig
9f66d59c0a Merge branch 'master' of https://github.com/alxnegrila/xmrig into dev 2020-08-20 14:40:53 +07:00
XMRig
9d99fef52e v6.3.3-dev 2020-08-20 13:54:52 +07:00
XMRig
3b22f1704f Merge branch 'master' into dev 2020-08-20 13:54:24 +07:00
xmrig
c89ad6b36d Update README.md 2020-08-20 13:44:20 +07:00
xmrig
45300f1ff5 Update README.md 2020-08-20 13:43:20 +07:00
XMRig
847d08cdbc v6.3.2 2020-08-20 12:54:22 +07:00
XMRig
81af1e964d Merge branch 'dev' 2020-08-20 12:53:45 +07:00
xmrig
3662e45435 Update CHANGELOG.md 2020-08-20 12:49:31 +07:00
XMRig
f06e30e343 Merge branch 'battery-macos' of https://github.com/jtgrassie/xmrig into dev 2020-08-20 12:46:09 +07:00
xmrig
34d4aa4012 Update CHANGELOG.md 2020-08-19 07:42:10 +07:00
XMRig
3e4bf8cd6c Fix compile warning 2020-08-17 06:08:14 +07:00
XMRig
206b675892 Always use all available threads on ARM. 2020-08-16 17:36:38 +07:00
XMRig
00b4ae9c36 Fixed compile warning and updated build.uv.sh. 2020-08-16 16:03:27 +07:00
XMRig
8d5ea745bb Merge branch 'dev' of github.com:xmrig/xmrig into dev 2020-08-16 15:47:57 +07:00
XMRig
cac48cdd27 Added ARM CPU name detection based on lscpu code. 2020-08-16 15:47:29 +07:00
xmrig
c20010ed54 Merge pull request #1807 from SChernykh/dev
RandomX JIT: optimized address mask calculation
2020-08-12 21:48:20 +07:00
SChernykh
5926dee354 RandomX JIT: optimized address mask calculation 2020-08-12 16:45:16 +02:00
Jethro Grassie
b78b0b5c6b fix macos battery detection 2020-08-11 18:04:56 -04:00
XMRig
43afa437e4 Merge branch 'dev' of github.com:xmrig/xmrig into dev 2020-08-07 21:55:06 +07:00
XMRig
050568a4ab Fixed rare protocol error in HTTP client. 2020-08-07 21:54:22 +07:00
xmrig
8bf40cea36 Update CHANGELOG.md 2020-08-01 13:02:11 +07:00
XMRig
ae3ff0f570 Fixed RandomX cache initialization if 1GB pages fails to allocate on a first NUMA node. 2020-08-01 12:30:02 +07:00
xmrig
0addf91a70 Merge pull request #1794 from SChernykh/dev
More robust 1 GB pages handling
2020-07-31 20:45:27 +07:00
SChernykh
abb78302b8 Try to allocate scratchpad from dataset's 1 GB huge pages, if normal huge pages are not available 2020-07-31 13:37:22 +02:00
XMRig
e5579d8635 v6.3.2-dev 2020-07-31 16:50:23 +07:00
XMRig
3986c43fa5 Merge branch 'master' into dev 2020-07-31 16:48:54 +07:00
SChernykh
838cc08680 Force 2 MB pages size in allocateLargePagesMemory() on Linux 2020-07-31 09:55:49 +02:00
XMRig
a0fe49f946 v6.3.1 2020-07-31 13:20:56 +07:00
XMRig
70dbe8562c Merge branch 'dev' 2020-07-31 13:20:11 +07:00
xmrig
41fcd1e49a Update CHANGELOG.md 2020-07-31 13:16:58 +07:00
xmrig
90195caa1d Merge pull request #1792 from SChernykh/dev
Fixed crash in RelWithDbgInfo MSVC build
2020-07-29 15:42:09 +07:00
SChernykh
cdb6287d89 Fixed crash in RelWithDbgInfo MSVC build
Same problem as in https://github.com/xmrig/xmrig/pull/1784 , fixed with compiler flags this time.
2020-07-29 10:39:58 +02:00
XMRig
32e9b7e34a Added command line option --pause-on-battery and renamed config option. 2020-07-23 15:45:01 +07:00
XMRig
6484bbb716 Add tags 2020-07-23 10:26:56 +07:00
xmrig
e59806d6ae Merge pull request #1786 from SChernykh/dev
Added mining on battery setting
2020-07-23 09:20:06 +07:00
SChernykh
299b180b28 Added mining on battery setting 2020-07-22 20:21:42 +02:00
XMRig
1acd88ed39 Cleanup 2020-07-22 21:27:40 +07:00
XMRig
109c088e8a Cleanup usage output. 2020-07-22 19:58:08 +07:00
xmrig
bb18239642 Update README.md 2020-07-22 09:14:25 +07:00
xmrig
ccded7cc0a Merge pull request #1784 from SChernykh/dev
Fixed RandomX initialization for VS debug builds
2020-07-21 19:04:02 +07:00
SChernykh
5bc89fdc8b Fixed RandomX initialization for VS debug builds 2020-07-21 10:10:07 +02:00
XMRig
70c7f33a20 Added command line options --cache-qos (--randomx-cache-qos) and --argon2-impl (--cpu-argon2-impl). 2020-07-20 09:17:59 +07:00
XMRig
1ec185a3a0 v6.3.1-dev 2020-07-17 03:13:02 +07:00
XMRig
6aa4eeefbb Merge branch 'master' into dev 2020-07-17 03:12:36 +07:00
XMRig
10ea567084 v6.3.0 2020-07-17 00:17:55 +07:00
XMRig
028d6503aa Merge branch 'dev' 2020-07-17 00:17:24 +07:00
XMRig
51346c2b2b v6.3.0-dev 2020-07-17 00:04:31 +07:00
XMRig
ca535c7813 Sync changes with the proxy. 2020-07-16 23:29:21 +07:00
xmrig
ba80e27349 Merge pull request #1780 from SChernykh/dev
Cryptonight OpenCL: fix for long input data
2020-07-16 19:56:20 +07:00
SChernykh
bd8cf54a0b Cryptonight OpenCL: fix for long input data 2020-07-16 10:39:32 +02:00
XMRig
e0eed7d5d6 Fixed build without MSR support. 2020-07-16 05:15:35 +07:00
XMRig
8dff08f15f Merge branch 'haven-protocol-org-master' into dev 2020-07-15 23:33:53 +07:00
XMRig
47d68b068b Merge branch 'master' of https://github.com/haven-protocol-org/xmrig into haven-protocol-org-master 2020-07-15 23:33:17 +07:00
Neil Coggins
a648a8b9be Increased max blob size to support Haven offshore capability 2020-07-14 11:52:43 +01:00
xmrig
7eefccc6bc Merge pull request #1776 from SChernykh/dev
Removed cache QoS warning at exit on unsupported CPUs
2020-07-14 01:45:18 +07:00
SChernykh
1bf159d1e8 Removed cache QoS warning at exit on unsupported CPUs 2020-07-13 20:43:49 +02:00
xmrig
bf46cb8684 Merge pull request #1774 from SChernykh/dev
RandomX: added cache QoS support
2020-07-14 01:35:46 +07:00
SChernykh
72c385c870 Cache QoS: fix for seting MSR 2020-07-13 20:30:44 +02:00
SChernykh
c83429c55c RandomX: added cache QoS support
False by default. If set to true, all non-mining CPU cores will not have access to L3 cache.
2020-07-13 17:23:18 +02:00
xmrig
e5a2689052 Merge pull request #1771 from jserv/update-sse2neon
Adopt new SSE2NEON and reduce ARM-specific changes
2020-07-11 02:32:56 +07:00
Jim Huang
b665d2d865 Adopt new SSE2NEON and reduce ARM-specific changes
This patch updated SSE2NEON [1], which contains more functions
provided by Intel intrinsics, only implemented with NEON-based
counterparts to produce the exact semantics of the intrinsics.
Consequently, ARM-specific changes against CryptoNight_arm can
be reduced as well.

[1] https://github.com/DLTcollab/sse2neon/
2020-07-11 01:55:11 +08:00
XMRig
e06a76ef1c v6.2.4-dev 2020-07-10 03:12:00 +07:00
XMRig
f523fddbfd Merge branch 'master' into dev 2020-07-10 02:49:33 +07:00
Alexandru Negrila
89e6998054 Fix OpenSSL static link when BUILD_STATIC=ON is provided 2020-04-09 09:09:21 +03:00
188 changed files with 13799 additions and 8697 deletions

View File

@@ -1,3 +1,64 @@
# v6.4.0
- [#1862](https://github.com/xmrig/xmrig/pull/1862) **RandomX: removed `rx/loki` algorithm.**
- [#1890](https://github.com/xmrig/xmrig/pull/1890) **Added `argon2/chukwav2` algorithm.**
- [#1895](https://github.com/xmrig/xmrig/pull/1895) [#1897](https://github.com/xmrig/xmrig/pull/1897) **Added [benchmark and stress test](https://github.com/xmrig/xmrig/blob/dev/doc/BENCHMARK.md).**
- [#1864](https://github.com/xmrig/xmrig/pull/1864) RandomX: improved software AES performance.
- [#1870](https://github.com/xmrig/xmrig/pull/1870) RandomX: fixed unexpected resume due to disconnect during dataset init.
- [#1872](https://github.com/xmrig/xmrig/pull/1872) RandomX: fixed `randomx_create_vm` call.
- [#1875](https://github.com/xmrig/xmrig/pull/1875) RandomX: fixed crash on x86.
- [#1876](https://github.com/xmrig/xmrig/pull/1876) RandomX: added `huge-pages-jit` config parameter.
- [#1881](https://github.com/xmrig/xmrig/pull/1881) Fixed possible race condition in hashrate counting code.
- [#1882](https://github.com/xmrig/xmrig/pull/1882) [#1886](https://github.com/xmrig/xmrig/pull/1886) [#1887](https://github.com/xmrig/xmrig/pull/1887) [#1893](https://github.com/xmrig/xmrig/pull/1893) General code improvements.
- [#1885](https://github.com/xmrig/xmrig/pull/1885) Added more precise hashrate calculation.
- [#1889](https://github.com/xmrig/xmrig/pull/1889) Fixed libuv performance issue on Linux.
# v6.3.5
- [#1845](https://github.com/xmrig/xmrig/pull/1845) [#1861](https://github.com/xmrig/xmrig/pull/1861) Fixed ARM build and added CMake option `WITH_SSE4_1`.
- [#1846](https://github.com/xmrig/xmrig/pull/1846) KawPow: fixed OpenCL memory leak.
- [#1849](https://github.com/xmrig/xmrig/pull/1849) [#1859](https://github.com/xmrig/xmrig/pull/1859) RandomX: optimized soft AES code.
- [#1850](https://github.com/xmrig/xmrig/pull/1850) [#1852](https://github.com/xmrig/xmrig/pull/1852) General code improvements.
- [#1853](https://github.com/xmrig/xmrig/issues/1853) [#1856](https://github.com/xmrig/xmrig/pull/1856) [#1857](https://github.com/xmrig/xmrig/pull/1857) Fixed crash on old CPUs.
# v6.3.4
- [#1823](https://github.com/xmrig/xmrig/pull/1823) RandomX: added new option `scratchpad_prefetch_mode`.
- [#1827](https://github.com/xmrig/xmrig/pull/1827) [#1831](https://github.com/xmrig/xmrig/pull/1831) Improved nonce iteration performance.
- [#1828](https://github.com/xmrig/xmrig/pull/1828) RandomX: added SSE4.1-optimized Blake2b.
- [#1830](https://github.com/xmrig/xmrig/pull/1830) RandomX: added performance profiler (for developers).
- [#1835](https://github.com/xmrig/xmrig/pull/1835) RandomX: returned old soft AES implementation and added auto-select between the two.
- [#1840](https://github.com/xmrig/xmrig/pull/1840) RandomX: moved more stuff to compile time, small x86 JIT compiler speedup.
- [#1841](https://github.com/xmrig/xmrig/pull/1841) Fixed Cryptonight OpenCL for AMD 20.7.2 drivers.
- [#1842](https://github.com/xmrig/xmrig/pull/1842) RandomX: AES improvements, a bit faster hardware AES code when compiled with MSVC.
- [#1843](https://github.com/xmrig/xmrig/pull/1843) RandomX: improved performance of GCC compiled binaries.
# v6.3.3
- [#1817](https://github.com/xmrig/xmrig/pull/1817) Fixed self-select login sequence.
- Added brand new [build from source](https://xmrig.com/docs/miner/build) documentation.
- New binary downloads for macOS (`macos-x64`), FreeBSD (`freebsd-static-x64`), Linux (`linux-static-x64`), Ubuntu 18.04 (`bionic-x64`), Ubuntu 20.04 (`focal-x64`).
- Generic Linux download `xenial-x64` renamed to `linux-x64`.
- Builds without SSL/TLS support are no longer provided.
- Improved CUDA loader error reporting and fixed plugin load on Linux.
- Fixed build warnings with Clang compiler.
- Fixed colors on macOS.
# v6.3.2
- [#1794](https://github.com/xmrig/xmrig/pull/1794) More robust 1 GB pages handling.
- Don't allocate 1 GB per thread if 1 GB is the default huge page size.
- Try to allocate scratchpad from dataset's 1 GB huge pages, if normal huge pages are not available.
- Correctly initialize RandomX cache if 1 GB pages fail to allocate on a first NUMA node.
- [#1806](https://github.com/xmrig/xmrig/pull/1806) Fixed macOS battery detection.
- [#1809](https://github.com/xmrig/xmrig/issues/1809) Improved auto configuration on ARM CPUs.
- Added retrieving ARM CPU names, based on lscpu code and database.
# v6.3.1
- [#1786](https://github.com/xmrig/xmrig/pull/1786) Added `pause-on-battery` option, supported on Windows and Linux.
- Added command line options `--randomx-cache-qos` and `--argon2-impl`.
# v6.3.0
- [#1771](https://github.com/xmrig/xmrig/pull/1771) Adopted new SSE2NEON and reduced ARM-specific changes.
- [#1774](https://github.com/xmrig/xmrig/pull/1774) RandomX: Added new option `cache_qos` in `randomx` object for cache QoS support.
- [#1777](https://github.com/xmrig/xmrig/pull/1777) Added support for upcoming Haven offshore fork.
- [#1780](https://github.com/xmrig/xmrig/pull/1780) CryptoNight OpenCL: fix for long input data.
# v6.2.3
- [#1745](https://github.com/xmrig/xmrig/pull/1745) AstroBWT: fixed OpenCL compilation on some systems.
- [#1749](https://github.com/xmrig/xmrig/pull/1749) KawPow: optimized CPU share verification.

View File

@@ -23,6 +23,9 @@ option(WITH_NVML "Enable NVML (NVIDIA Management Library) support (on
option(WITH_ADL "Enable ADL (AMD Display Library) or sysfs support (only if OpenCL backend enabled)" ON)
option(WITH_STRICT_CACHE "Enable strict checks for OpenCL cache" ON)
option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF)
option(WITH_PROFILING "Enable profiling for developers" OFF)
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
option(BUILD_STATIC "Build static binary" OFF)
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
@@ -143,6 +146,8 @@ elseif (XMRIG_OS_APPLE)
src/App_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)
find_library(IOKIT_LIBRARY IOKit)
set(EXTRA_LIBS ${IOKIT_LIBRARY})
else()
list(APPEND SOURCES_OS
src/App_unix.cpp
@@ -196,10 +201,6 @@ include_directories(src)
include_directories(src/3rdparty)
include_directories(${UV_INCLUDE_DIR})
if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS " -static")
endif()
if (WITH_DEBUG_LOG)
add_definitions(/DAPP_DEBUG)
endif()
@@ -211,3 +212,7 @@ if (WIN32)
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/bin/WinRing0/WinRing0x64.sys" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_BUILD_TYPE STREQUAL Release)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} ${CMAKE_PROJECT_NAME})
endif()

121
README.md
View File

@@ -2,130 +2,35 @@
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date-pre/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub license](https://img.shields.io/github/license/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/blob/master/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/network)
XMRig High performance, open source, cross platform RandomX, KawPow, CryptoNight, AstroBWT and Argon2 CPU/GPU miner, with official support for Windows.
XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight and AstroBWT unified CPU/GPU miner. Official binaries are available for Windows, Linux, macOS and FreeBSD.
## Mining backends
- **CPU** (x64/x86/ARM)
- **CPU** (x64/ARMv8)
- **OpenCL** for AMD GPUs.
- **CUDA** for NVIDIA GPUs via external [CUDA plugin](https://github.com/xmrig/xmrig-cuda).
<img src="doc/screenshot_v5_2_0.png" width="833" >
## Download
* Binary releases: https://github.com/xmrig/xmrig/releases
* Git tree: https://github.com/xmrig/xmrig.git
* Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build).
* **[Binary releases](https://github.com/xmrig/xmrig/releases)**
* **[Build from source](https://xmrig.com/docs/miner/build)**
## Usage
The preferred way to configure the miner is the [JSON config file](src/config.json) as it is more flexible and human friendly. The command line interface does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing API calls.
The preferred way to configure the miner is the [JSON config file](src/config.json) as it is more flexible and human friendly. The [command line interface](https://xmrig.com/docs/miner/command-line-options) does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing API calls.
* **[xmrig.com/wizard](https://xmrig.com/wizard)** helps you create initial configuration for the miner.
* **[workers.xmrig.info](http://workers.xmrig.info)** helps manage your miners via HTTP API.
### Command line options
```
Network:
-o, --url=URL URL of mining server
-a, --algo=ALGO mining algorithm https://xmrig.com/docs/algorithms
--coin=COIN specify coin instead of algorithm
-u, --user=USERNAME username for mining server
-p, --pass=PASSWORD password for mining server
-O, --userpass=U:P username:password pair for mining server
-x, --proxy=HOST:PORT connect through a SOCKS5 proxy
-k, --keepalive send keepalive packet for prevent timeout (needs pool support)
--nicehash enable nicehash.com support
--rig-id=ID rig identifier for pool-side statistics (needs pool support)
--tls enable SSL/TLS support (needs pool support)
--tls-fingerprint=HEX pool TLS certificate fingerprint for strict certificate pinning
--daemon use daemon RPC instead of pool for solo mining
--daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)
-r, --retries=N number of times to retry before switch to backup server (default: 5)
-R, --retry-pause=N time to pause between retries (default: 5)
--user-agent set custom user-agent string for pool
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)
--donate-over-proxy=N control donate over xmrig-proxy feature
CPU backend:
--no-cpu disable CPU mining backend
-t, --threads=N number of CPU threads
-v, --av=N algorithm variation, 0 auto select
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)
--cpu-max-threads-hint=N maximum CPU threads count (in percentage) hint for autoconfig
--cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)
--cpu-no-yield prefer maximum hashrate rather than system response/stability
--no-huge-pages disable huge pages support
--asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer
--randomx-init=N thread count to initialize RandomX dataset
--randomx-no-numa disable NUMA support for RandomX
--randomx-mode=MODE RandomX mode: auto, fast, light
--randomx-1gb-pages use 1GB hugepages for dataset (Linux only)
--randomx-wrmsr=N write custom value (0-15) to Intel MSR register 0x1a4 or disable MSR mod (-1)
--randomx-no-rdmsr disable reverting initial MSR values on exit
--astrobwt-max-size=N skip hashes with large stage 2 size, default: 550, min: 400, max: 1200
--astrobwt-avx2 enable AVX2 optimizations for AstroBWT algorithm
API:
--api-worker-id=ID custom worker-id for API
--api-id=ID custom instance ID for API
--http-host=HOST bind host for HTTP API (default: 127.0.0.1)
--http-port=N bind port for HTTP API
--http-access-token=T access token for HTTP API
--http-no-restricted enable full remote access to HTTP API (only if access token set)
OpenCL backend:
--opencl enable OpenCL mining backend
--opencl-devices=N comma separated list of OpenCL devices to use
--opencl-platform=N OpenCL platform index or name
--opencl-loader=PATH path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so)
--opencl-no-cache disable OpenCL cache
--print-platforms print available OpenCL platforms and exit
CUDA backend:
--cuda enable CUDA mining backend
--cuda-loader=PATH path to CUDA plugin (xmrig-cuda.dll or libxmrig-cuda.so)
--cuda-devices=N comma separated list of CUDA devices to use
--cuda-bfactor-hint=N bfactor hint for autoconfig (0-12)
--cuda-bsleep-hint=N bsleep hint for autoconfig
--no-nvml disable NVML (NVIDIA Management Library) support
TLS:
--tls-gen=HOSTNAME generate TLS certificate for specific hostname
--tls-cert=FILE load TLS certificate chain from a file in the PEM format
--tls-cert-key=FILE load TLS certificate private key from a file in the PEM format
--tls-dhparam=FILE load DH parameters for DHE ciphers from a file in the PEM format
--tls-protocols=N enable specified TLS protocols, example: "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3"
--tls-ciphers=S set list of available ciphers (TLSv1.2 and below)
--tls-ciphersuites=S set list of available TLSv1.3 ciphersuites
Logging:
-S, --syslog use system log for output messages
-l, --log-file=FILE log all output to a file
--print-time=N print hashrate report every N seconds
--health-print-time=N print health report every N seconds
--no-color disable colored output
--verbose verbose output
Misc:
-c, --config=FILE load a JSON-format configuration file
-B, --background run the miner in the background
-V, --version output version information and exit
-h, --help display this help and exit
--dry-run test configuration and exit
--export-topology export hwloc topology to a XML file and exit
--title set custom console window title
--no-title disable setting console window title
```
* **[Wizard](https://xmrig.com/wizard)** helps you create initial configuration for the miner.
* **[Workers](http://workers.xmrig.info)** helps manage your miners via HTTP API.
## Donations
* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via option `donate-level` or disabled in source code.
* Default donation 1% (1 minute in 100 minutes) can be increased via option `donate-level` or disabled in source code.
* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
## Developers
* **[xmrig](https://github.com/xmrig)**
* **[sech1](https://github.com/SChernykh)**
## Contacts
* support@xmrig.com

View File

@@ -10,6 +10,11 @@ if (WITH_TLS)
set(OPENSSL_USE_STATIC_LIBS TRUE)
endif()
if (BUILD_STATIC)
set(OPENSSL_USE_STATIC_LIBS TRUE)
endif()
find_package(OpenSSL)
if (OPENSSL_FOUND)

View File

@@ -2,9 +2,10 @@ if (NOT CMAKE_SYSTEM_PROCESSOR)
message(WARNING "CMAKE_SYSTEM_PROCESSOR not defined")
endif()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(/DRAPIDJSON_SSE2)
else()
set(WITH_SSE4_1 OFF)
endif()
if (NOT ARM_TARGET)
@@ -41,3 +42,7 @@ if (ARM_TARGET AND ARM_TARGET GREATER 6)
add_definitions(/DXMRIG_ARMv7)
endif()
endif()
if (WITH_SSE4_1)
add_definitions(/DXMRIG_FEATURE_SSE4_1)
endif()

View File

@@ -45,6 +45,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif()
if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
add_definitions(/D_GNU_SOURCE)
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
@@ -60,6 +64,9 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_C_FLAGS_RELEASE "/MT /O2 /Oi /DNDEBUG /GL")
set(CMAKE_CXX_FLAGS_RELEASE "/MT /O2 /Oi /DNDEBUG /GL")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ob1 /Zi")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/Ob1 /Zi")
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(/DNOMINMAX)
@@ -89,6 +96,10 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
endif()
endif()
if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
endif()
if (NOT WIN32)

View File

@@ -62,6 +62,18 @@ if (WITH_RANDOMX)
)
# cheat because cmake and ccache hate each other
set_property(SOURCE src/crypto/randomx/jit_compiler_a64_static.S PROPERTY LANGUAGE C)
else()
list(APPEND SOURCES_CRYPTO
src/crypto/randomx/jit_compiler_fallback.cpp
)
endif()
if (WITH_SSE4_1)
list(APPEND SOURCES_CRYPTO src/crypto/randomx/blake2/blake2b_sse41.c)
if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/randomx/blake2/blake2b_sse41.c PROPERTIES COMPILE_FLAGS -msse4.1)
endif()
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES Clang)

29
doc/BENCHMARK.md Normal file
View File

@@ -0,0 +1,29 @@
# Embedded benchmark
You can run with XMRig with the following commands:
```
xmrig --bench=1M
xmrig --bench=10M
xmrig --bench=1M -a rx/wow
xmrig --bench=10M -a rx/wow
```
This will run between 1 and 10 million RandomX hashes, depending on `bench` parameter, and print the time it took. First two commands use Monero variant (2 MB per thread, best for Zen2/Zen3 CPUs), second two commands use Wownero variant (1 MB per thread, useful for Intel and 1st gen Zen/Zen+ CPUs).
Checksum of all the hashes will be also printed to check stability of your hardware: if it's green then it's correct, if it's red then there was hardware error during computation. No Internet connection is required for the benchmark.
Double check that you see `Huge pages 100%` both for dataset and for all threads, and also check for `msr register values ... has been set successfully` - without this result will be far from the best. Running as administrator is required for MSR and huge pages to be set up properly.
![Benchmark example](https://i.imgur.com/PST3BYc.png)
### Benchmark with custom config
You can run benchmark with any configuration you want. Just start without command line parameteres, use regular config.json and add `"benchmark":"1M",` on the next line after pool url.
# Stress test
You can also run continuous stress-test that is as close to the real RandomX mining as possible and doesn't require any configuration:
```
xmrig --stress
xmrig --stress -a rx/wow
```
This will require Internet connection and will run indefinitely.

View File

@@ -22,6 +22,7 @@ This feature add external dependency to libhwloc (1.10.0+) (except MSVC builds).
* **`-DWITH_EMBEDDED_CONFIG=ON`** Enable [embedded](https://github.com/xmrig/xmrig/issues/957) config support.
* **`-DWITH_OPENCL=OFF`** Disable OpenCL backend.
* **`-DWITH_CUDA=OFF`** Disable CUDA backend.
* **`-DWITH_SSE4_1=OFF`** Disable SSE 4.1 for Blake2 (useful for arm builds).
## Debug options

View File

@@ -8,12 +8,12 @@ mkdir -p deps/lib
mkdir -p build && cd build
wget https://download.open-mpi.org/release/hwloc/v2.2/hwloc-${HWLOC_VERSION}.tar.bz2 -O hwloc-${HWLOC_VERSION}.tar.bz2
tar -xjf hwloc-${HWLOC_VERSION}.tar.bz2
wget https://download.open-mpi.org/release/hwloc/v2.2/hwloc-${HWLOC_VERSION}.tar.gz -O hwloc-${HWLOC_VERSION}.tar.gz
tar -xzf hwloc-${HWLOC_VERSION}.tar.gz
cd hwloc-${HWLOC_VERSION}
./configure --disable-shared --enable-static --disable-io --disable-libudev --disable-libxml2
make -j$(nproc)
cp -fr include/ ../../deps
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
cp -fr include ../../deps
cp hwloc/.libs/libhwloc.a ../../deps/lib
cd ..

19
scripts/build.hwloc1.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash -e
HWLOC_VERSION="1.11.13"
mkdir -p deps
mkdir -p deps/include
mkdir -p deps/lib
mkdir -p build && cd build
wget https://download.open-mpi.org/release/hwloc/v1.11/hwloc-${HWLOC_VERSION}.tar.gz -O hwloc-${HWLOC_VERSION}.tar.gz
tar -xzf hwloc-${HWLOC_VERSION}.tar.gz
cd hwloc-${HWLOC_VERSION}
./configure --disable-shared --enable-static --disable-io --disable-libudev --disable-libxml2
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
cp -fr include ../../deps
cp src/.libs/libhwloc.a ../../deps/lib
cd ..

View File

@@ -13,8 +13,8 @@ tar -xzf libressl-${LIBRESSL_VERSION}.tar.gz
cd libressl-${LIBRESSL_VERSION}
./configure --disable-shared
make -j$(nproc)
cp -fr include/ ../../deps
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
cp -fr include ../../deps
cp crypto/.libs/libcrypto.a ../../deps/lib
cp ssl/.libs/libssl.a ../../deps/lib
cd ..

View File

@@ -13,8 +13,8 @@ tar -xzf openssl-${OPENSSL_VERSION}.tar.gz
cd openssl-${OPENSSL_VERSION}
./config -no-shared -no-asm -no-zlib -no-comp -no-dgram -no-filenames -no-cms
make -j$(nproc)
cp -fr include/ ../../deps
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
cp -fr include ../../deps
cp libcrypto.a ../../deps/lib
cp libssl.a ../../deps/lib
cd ..

View File

@@ -1,6 +1,6 @@
#!/bin/bash -e
UV_VERSION="1.38.0"
UV_VERSION="1.38.1"
mkdir -p deps
mkdir -p deps/include
@@ -14,7 +14,7 @@ tar -xzf v${UV_VERSION}.tar.gz
cd libuv-${UV_VERSION}
sh autogen.sh
./configure --disable-shared
make -j$(nproc)
cp -fr include/ ../../deps
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
cp -fr include ../../deps
cp .libs/libuv.a ../../deps/lib
cd ..

View File

@@ -49,7 +49,6 @@ function rx()
'../cn/algorithm.cl',
'randomx_constants_monero.h',
'randomx_constants_wow.h',
'randomx_constants_loki.h',
'randomx_constants_arqma.h',
'randomx_constants_keva.h',
'aes.cl',

View File

@@ -0,0 +1,103 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/common/Benchmark.h"
#include "backend/common/interfaces/IWorker.h"
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/tools/Chrono.h"
#include <algorithm>
namespace xmrig {
static uint64_t hashCheck[2][10] = {
{ 0x898B6E0431C28A6BULL, 0xEE9468F8B40926BCULL, 0xC2BC5D11724813C0ULL, 0x3A2C7B285B87F941ULL, 0x3B5BD2C3A16B450EULL, 0x5CD0602F20C5C7C4ULL, 0x101DE939474B6812ULL, 0x52B765A1B156C6ECULL, 0x323935102AB6B45CULL, 0xB5231262E2792B26ULL },
{ 0x0F3E5400B39EA96AULL, 0x85944CCFA2752D1FULL, 0x64AFFCAE991811BAULL, 0x3E4D0B836D3B13BAULL, 0xEB7417D621271166ULL, 0x97FFE10C0949FFA5ULL, 0x84CAC0F8879A4BA1ULL, 0xA1B79F031DA2459FULL, 0x9B65226DA873E65DULL, 0x0F9E00C5A511C200ULL },
};
} // namespace xmrig
bool xmrig::Benchmark::finish(uint64_t totalHashCount)
{
m_reset = true;
m_current = totalHashCount;
if (m_done < m_workers) {
return false;
}
const double dt = (m_doneTime - m_startTime) / 1000.0;
uint64_t checkData = 0;
const uint32_t N = (m_end / 1000000) - 1;
if (((m_algo == Algorithm::RX_0) || (m_algo == Algorithm::RX_WOW)) && ((m_end % 1000000) == 0) && (N < 10)) {
checkData = hashCheck[(m_algo == Algorithm::RX_0) ? 0 : 1][N];
}
const char *color = checkData ? ((m_data == checkData) ? GREEN_BOLD_S : RED_BOLD_S) : BLACK_BOLD_S;
LOG_NOTICE("%s " WHITE_BOLD("benchmark finished in ") CYAN_BOLD("%.3f seconds") WHITE_BOLD_S " hash sum = " CLEAR "%s%016" PRIX64 CLEAR, Tags::bench(), dt, color, m_data);
LOG_INFO("%s " WHITE_BOLD("press ") MAGENTA_BOLD("Ctrl+C") WHITE_BOLD(" to exit"), Tags::bench());
return true;
}
void xmrig::Benchmark::start()
{
m_startTime = Chrono::steadyMSecs();
}
void xmrig::Benchmark::printProgress() const
{
if (!m_startTime || !m_current) {
return;
}
const double dt = (Chrono::steadyMSecs() - m_startTime) / 1000.0;
const double percent = static_cast<double>(m_current) / m_end * 100.0;
LOG_NOTICE("%s " MAGENTA_BOLD("%5.2f%% ") CYAN_BOLD("%" PRIu64) CYAN("/%" PRIu64) BLACK_BOLD(" (%.3fs)"), Tags::bench(), percent, m_current, m_end, dt);
}
void xmrig::Benchmark::tick(IWorker *worker)
{
if (m_reset) {
m_data = 0;
m_done = 0;
m_reset = false;
}
const uint64_t doneTime = worker->benchDoneTime();
if (!doneTime) {
return;
}
++m_done;
m_data ^= worker->benchData();
m_doneTime = std::max(doneTime, m_doneTime);
}

View File

@@ -0,0 +1,62 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_BENCHMARK_H
#define XMRIG_BENCHMARK_H
#include "base/tools/Object.h"
#include "base/crypto/Algorithm.h"
namespace xmrig {
class IWorker;
class Benchmark
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Benchmark)
Benchmark(uint32_t end, const Algorithm &algo, size_t workers) : m_algo(algo), m_workers(workers), m_end(end) {}
~Benchmark() = default;
bool finish(uint64_t totalHashCount);
void printProgress() const;
void start();
void tick(IWorker *worker);
private:
bool m_reset = false;
const Algorithm m_algo = Algorithm::RX_0;
const size_t m_workers = 0;
const uint64_t m_end = 0;
uint32_t m_done = 0;
uint64_t m_current = 0;
uint64_t m_data = 0;
uint64_t m_doneTime = 0;
uint64_t m_startTime = 0;
};
} // namespace xmrig
#endif /* XMRIG_BENCHMARK_H */

View File

@@ -48,13 +48,13 @@ inline static const char *format(double h, char *buf, size_t size)
xmrig::Hashrate::Hashrate(size_t threads) :
m_threads(threads)
m_threads(threads + 1)
{
m_counts = new uint64_t*[threads];
m_timestamps = new uint64_t*[threads];
m_top = new uint32_t[threads];
m_counts = new uint64_t*[m_threads];
m_timestamps = new uint64_t*[m_threads];
m_top = new uint32_t[m_threads];
for (size_t i = 0; i < threads; i++) {
for (size_t i = 0; i < m_threads; i++) {
m_counts[i] = new uint64_t[kBucketSize]();
m_timestamps[i] = new uint64_t[kBucketSize]();
m_top[i] = 0;
@@ -77,17 +77,8 @@ xmrig::Hashrate::~Hashrate()
double xmrig::Hashrate::calc(size_t ms) const
{
double result = 0.0;
double data;
for (size_t i = 0; i < m_threads; ++i) {
data = calc(i, ms);
if (std::isnormal(data)) {
result += data;
}
}
return result;
const double data = calc(0, ms);
return std::isnormal(data) ? data : 0.0;
}
@@ -102,7 +93,7 @@ double xmrig::Hashrate::calc(size_t threadId, size_t ms) const
uint64_t earliestStamp = 0;
bool haveFullSet = false;
const uint64_t timeStampLimit = xmrig::Chrono::highResolutionMSecs() - ms;
const uint64_t timeStampLimit = xmrig::Chrono::steadyMSecs() - ms;
uint64_t* timestamps = m_timestamps[threadId];
uint64_t* counts = m_counts[threadId];
@@ -183,9 +174,9 @@ rapidjson::Value xmrig::Hashrate::toJSON(size_t threadId, rapidjson::Document &d
auto &allocator = doc.GetAllocator();
Value out(kArrayType);
out.PushBack(normalize(calc(threadId, ShortInterval)), allocator);
out.PushBack(normalize(calc(threadId, MediumInterval)), allocator);
out.PushBack(normalize(calc(threadId, LargeInterval)), allocator);
out.PushBack(normalize(calc(threadId + 1, ShortInterval)), allocator);
out.PushBack(normalize(calc(threadId + 1, MediumInterval)), allocator);
out.PushBack(normalize(calc(threadId + 1, LargeInterval)), allocator);
return out;
}

View File

@@ -0,0 +1,63 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/common/HashrateInterpolator.h"
uint64_t xmrig::HashrateInterpolator::interpolate(uint64_t timeStamp) const
{
timeStamp -= LagMS;
std::lock_guard<std::mutex> l(m_lock);
const size_t N = m_data.size();
if (N < 2) {
return 0;
}
for (size_t i = 0; i < N - 1; ++i) {
const auto& a = m_data[i];
const auto& b = m_data[i + 1];
if (a.second <= timeStamp && timeStamp <= b.second) {
return a.first + static_cast<int64_t>(b.first - a.first) * (timeStamp - a.second) / (b.second - a.second);
}
}
return 0;
}
void xmrig::HashrateInterpolator::addDataPoint(uint64_t count, uint64_t timeStamp)
{
std::lock_guard<std::mutex> l(m_lock);
// Clean up old data
while (!m_data.empty() && (timeStamp - m_data.front().second > LagMS * 2)) {
m_data.pop_front();
}
m_data.emplace_back(count, timeStamp);
}

View File

@@ -0,0 +1,57 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HASHRATE_INTERPOLATOR_H
#define XMRIG_HASHRATE_INTERPOLATOR_H
#include <mutex>
#include <deque>
#include <utility>
namespace xmrig {
class HashrateInterpolator
{
public:
enum {
LagMS = 4000,
};
uint64_t interpolate(uint64_t timeStamp) const;
void addDataPoint(uint64_t count, uint64_t timeStamp);
private:
// Buffer of hashrate counters, used for linear interpolation of past data
mutable std::mutex m_lock;
std::deque<std::pair<uint64_t, uint64_t>> m_data;
};
} // namespace xmrig
#endif /* XMRIG_HASHRATE_INTERPOLATOR_H */

View File

@@ -47,11 +47,6 @@ const char *cuda_tag();
#endif
#ifdef XMRIG_ALGO_RANDOMX
const char *rx_tag();
#endif
} // namespace xmrig

View File

@@ -32,9 +32,7 @@
xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) :
m_affinity(affinity),
m_id(id),
m_hashCount(0),
m_timestamp(0)
m_id(id)
{
m_node = VirtualMemory::bindToNUMANode(affinity);
@@ -45,6 +43,23 @@ xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) :
void xmrig::Worker::storeStats()
{
m_hashCount.store(m_count, std::memory_order_relaxed);
m_timestamp.store(Chrono::highResolutionMSecs(), std::memory_order_relaxed);
// Get index which is unused now
const uint32_t index = m_index.load(std::memory_order_relaxed) ^ 1;
// Fill in the data for that index
m_hashCount[index] = m_count;
m_timestamp[index] = Chrono::steadyMSecs();
// Switch to that index
// All data will be in memory by the time it completes thanks to std::memory_order_seq_cst
m_index.fetch_xor(1, std::memory_order_seq_cst);
}
void xmrig::Worker::getHashrateData(uint64_t& hashCount, uint64_t& timeStamp) const
{
const uint32_t index = m_index.load(std::memory_order_relaxed);
hashCount = m_hashCount[index];
timeStamp = m_timestamp[index];
}

View File

@@ -44,19 +44,31 @@ public:
inline const VirtualMemory *memory() const override { return nullptr; }
inline size_t id() const override { return m_id; }
inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); }
inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); }
inline uint64_t rawHashes() const override { return m_count; }
inline void jobEarlyNotification(const Job&) override {}
void getHashrateData(uint64_t& hashCount, uint64_t& timeStamp) const override;
# ifdef XMRIG_FEATURE_BENCHMARK
inline uint64_t benchData() const override { return m_benchData; }
inline uint64_t benchDoneTime() const override { return m_benchDoneTime; }
# endif
protected:
void storeStats();
const int64_t m_affinity;
const size_t m_id;
std::atomic<uint64_t> m_hashCount;
std::atomic<uint64_t> m_timestamp;
uint32_t m_node = 0;
uint64_t m_count = 0;
std::atomic<uint32_t> m_index = {};
uint32_t m_node = 0;
uint64_t m_count = 0;
uint64_t m_hashCount[2] = {};
uint64_t m_timestamp[2] = {};
# ifdef XMRIG_FEATURE_BENCHMARK
uint64_t m_benchData = 0;
uint64_t m_benchDoneTime = 0;
# endif
};

View File

@@ -66,14 +66,12 @@ public:
inline bool nextRound(uint32_t rounds, uint32_t roundSize)
{
bool ok = true;
m_rounds[index()]++;
if ((m_rounds[index()] % rounds) == 0) {
if ((m_rounds[index()] & (rounds - 1)) == 0) {
for (size_t i = 0; i < N; ++i) {
*nonce(i) = Nonce::next(index(), *nonce(i), rounds * roundSize, currentJob().isNicehash(), &ok);
if (!ok) {
break;
if (!Nonce::next(index(), nonce(i), rounds * roundSize, nonceMask())) {
return false;
}
}
}
@@ -83,13 +81,14 @@ public:
}
}
return ok;
return true;
}
private:
inline int32_t nonceOffset() const { return currentJob().nonceOffset(); }
inline size_t nonceSize() const { return currentJob().nonceSize(); }
inline uint64_t nonceMask() const { return m_nonce_mask[index()]; }
inline void save(const Job &job, uint32_t reserveCount, Nonce::Backend backend)
{
@@ -97,12 +96,13 @@ private:
const size_t size = job.size();
m_jobs[index()] = job;
m_rounds[index()] = 0;
m_nonce_mask[index()] = job.nonceMask();
m_jobs[index()].setBackend(backend);
for (size_t i = 0; i < N; ++i) {
memcpy(m_blobs[index()] + (i * size), job.blob(), size);
*nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, job.isNicehash());
Nonce::next(index(), nonce(i), reserveCount, nonceMask());
}
}
@@ -110,6 +110,7 @@ private:
alignas(16) uint8_t m_blobs[2][Job::kMaxBlobSize * N]{};
Job m_jobs[2];
uint32_t m_rounds[2] = { 0, 0 };
uint64_t m_nonce_mask[2];
uint64_t m_sequence = 0;
uint8_t m_index = 0;
};
@@ -125,41 +126,23 @@ inline uint32_t *xmrig::WorkerJob<1>::nonce(size_t)
template<>
inline bool xmrig::WorkerJob<1>::nextRound(uint32_t rounds, uint32_t roundSize)
{
bool ok = true;
m_rounds[index()]++;
uint32_t* n = nonce();
const uint32_t prev_nonce = *n;
if ((m_rounds[index()] % rounds) == 0) {
*n = Nonce::next(index(), *n, rounds * roundSize, currentJob().isNicehash(), &ok);
if ((m_rounds[index()] & (rounds - 1)) == 0) {
if (!Nonce::next(index(), n, rounds * roundSize, nonceMask())) {
return false;
}
if (nonceSize() == sizeof(uint64_t)) {
m_jobs[index()].nonce()[1] = n[1];
}
}
else {
*n += roundSize;
}
// Increment higher 32 bits of a 64-bit nonce when lower 32 bits overflow
if (!currentJob().isNicehash() && (nonceSize() == sizeof(uint64_t))) {
const bool wrapped = (*n < prev_nonce);
const bool wraps_this_round = (static_cast<uint64_t>(*n) + roundSize > (1ULL << 32));
// Account for the case when starting nonce hasn't wrapped yet, but some nonces in the current round will wrap
if (wrapped || wraps_this_round) {
// Set lower 32 bits to 0 when higher 32 bits change
Nonce::reset(index());
// Sets *n to 0 and Nonce::m_nonce[index] to the correct next value
*n = 0;
Nonce::next(index(), *n, rounds * roundSize, currentJob().isNicehash(), &ok);
++n[1];
Job& job = m_jobs[index()];
memcpy(job.blob(), blob(), job.size());
}
}
return ok;
return true;
}
@@ -169,11 +152,12 @@ inline void xmrig::WorkerJob<1>::save(const Job &job, uint32_t reserveCount, Non
m_index = job.index();
m_jobs[index()] = job;
m_rounds[index()] = 0;
m_nonce_mask[index()] = job.nonceMask();
m_jobs[index()].setBackend(backend);
memcpy(blob(), job.blob(), job.size());
*nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash());
Nonce::next(index(), nonce(), reserveCount, nonceMask());
}

View File

@@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +29,11 @@
#include "backend/common/Workers.h"
#include "backend/cpu/CpuWorker.h"
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/net/stratum/Pool.h"
#include "base/tools/Chrono.h"
#include "base/tools/Object.h"
#include "core/Miner.h"
#ifdef XMRIG_FEATURE_OPENCL
@@ -42,6 +46,11 @@
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
# include "backend/common/Benchmark.h"
#endif
namespace xmrig {
@@ -51,17 +60,12 @@ public:
XMRIG_DISABLE_COPY_MOVE(WorkersPrivate)
WorkersPrivate() = default;
WorkersPrivate() = default;
~WorkersPrivate() = default;
inline ~WorkersPrivate()
{
delete hashrate;
}
Hashrate *hashrate = nullptr;
IBackend *backend = nullptr;
IBackend *backend = nullptr;
std::shared_ptr<Benchmark> benchmark;
std::shared_ptr<Hashrate> hashrate;
};
@@ -83,10 +87,77 @@ xmrig::Workers<T>::~Workers()
}
template<class T>
xmrig::Benchmark *xmrig::Workers<T>::benchmark() const
{
return d_ptr->benchmark.get();
}
template<class T>
static void getHashrateData(xmrig::IWorker* worker, uint64_t& hashCount, uint64_t& timeStamp)
{
worker->getHashrateData(hashCount, timeStamp);
}
template<>
void getHashrateData<xmrig::CpuLaunchData>(xmrig::IWorker* worker, uint64_t& hashCount, uint64_t&)
{
hashCount = worker->rawHashes();
}
template<class T>
bool xmrig::Workers<T>::tick(uint64_t)
{
if (!d_ptr->hashrate) {
return true;
}
uint64_t ts = Chrono::steadyMSecs();
bool totalAvailable = true;
uint64_t totalHashCount = 0;
for (Thread<T> *handle : m_workers) {
IWorker *worker = handle->worker();
if (worker) {
uint64_t hashCount;
getHashrateData<T>(worker, hashCount, ts);
d_ptr->hashrate->add(handle->id() + 1, hashCount, ts);
const uint64_t n = worker->rawHashes();
if (n == 0) {
totalAvailable = false;
}
totalHashCount += n;
# ifdef XMRIG_FEATURE_BENCHMARK
if (d_ptr->benchmark) {
d_ptr->benchmark->tick(worker);
}
# endif
}
}
if (totalAvailable) {
d_ptr->hashrate->add(0, totalHashCount, Chrono::steadyMSecs());
}
# ifdef XMRIG_FEATURE_BENCHMARK
if (d_ptr->benchmark && d_ptr->benchmark->finish(totalHashCount)) {
return false;
}
# endif
return true;
}
template<class T>
const xmrig::Hashrate *xmrig::Workers<T>::hashrate() const
{
return d_ptr->hashrate;
return d_ptr->hashrate.get();
}
@@ -100,21 +171,35 @@ void xmrig::Workers<T>::setBackend(IBackend *backend)
template<class T>
void xmrig::Workers<T>::start(const std::vector<T> &data)
{
# ifdef XMRIG_FEATURE_BENCHMARK
if (!data.empty() && data.front().benchSize) {
d_ptr->benchmark = std::make_shared<Benchmark>(data.front().benchSize, data.front().algorithm, data.size());
}
# endif
for (const T &item : data) {
m_workers.push_back(new Thread<T>(d_ptr->backend, m_workers.size(), item));
}
d_ptr->hashrate = new Hashrate(m_workers.size());
d_ptr->hashrate = std::make_shared<Hashrate>(m_workers.size());
Nonce::touch(T::backend());
for (Thread<T> *worker : m_workers) {
worker->start(Workers<T>::onReady);
// This sleep is important for optimal caching!
// Threads must allocate scratchpads in order so that adjacent cores will use adjacent scratchpads
// Sub-optimal caching can result in up to 0.5% hashrate penalty
std::this_thread::sleep_for(std::chrono::milliseconds(20));
# ifdef XMRIG_FEATURE_BENCHMARK
if (!d_ptr->benchmark)
# endif
{
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}
# ifdef XMRIG_FEATURE_BENCHMARK
if (d_ptr->benchmark) {
d_ptr->benchmark->start();
}
# endif
}
@@ -130,25 +215,7 @@ void xmrig::Workers<T>::stop()
m_workers.clear();
Nonce::touch(T::backend());
delete d_ptr->hashrate;
d_ptr->hashrate = nullptr;
}
template<class T>
void xmrig::Workers<T>::tick(uint64_t)
{
if (!d_ptr->hashrate) {
return;
}
for (Thread<T> *handle : m_workers) {
if (!handle->worker()) {
continue;
}
d_ptr->hashrate->add(handle->id(), handle->worker()->hashCount(), handle->worker()->timestamp());
}
d_ptr->hashrate.reset();
}

View File

@@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@
#include "backend/common/Thread.h"
#include "backend/cpu/CpuLaunchData.h"
#include "base/tools/Object.h"
#ifdef XMRIG_FEATURE_OPENCL
@@ -48,6 +47,7 @@ namespace xmrig {
class Hashrate;
class WorkersPrivate;
class Job;
class Benchmark;
template<class T>
@@ -59,12 +59,13 @@ public:
Workers();
~Workers();
Benchmark *benchmark() const;
bool tick(uint64_t ticks);
const Hashrate *hashrate() const;
void jobEarlyNotification(const Job&);
void setBackend(IBackend *backend);
void start(const std::vector<T> &data);
void stop();
void tick(uint64_t ticks);
void jobEarlyNotification(const Job&);
private:
static IWorker *create(Thread<T> *handle);

View File

@@ -1,5 +1,6 @@
set(HEADERS_BACKEND_COMMON
src/backend/common/Hashrate.h
src/backend/common/HashrateInterpolator.h
src/backend/common/Tags.h
src/backend/common/interfaces/IBackend.h
src/backend/common/interfaces/IRxListener.h
@@ -15,7 +16,13 @@ set(HEADERS_BACKEND_COMMON
set(SOURCES_BACKEND_COMMON
src/backend/common/Hashrate.cpp
src/backend/common/HashrateInterpolator.cpp
src/backend/common/Threads.cpp
src/backend/common/Worker.cpp
src/backend/common/Workers.cpp
)
if (WITH_RANDOMX AND WITH_BENCHMARK)
list(APPEND HEADERS_BACKEND_COMMON src/backend/common/Benchmark.h)
list(APPEND SOURCES_BACKEND_COMMON src/backend/common/Benchmark.cpp)
endif()

View File

@@ -36,6 +36,7 @@ namespace xmrig {
class Algorithm;
class Benchmark;
class Hashrate;
class IApiRequest;
class IWorker;
@@ -60,12 +61,17 @@ public:
virtual void setJob(const Job &job) = 0;
virtual void start(IWorker *worker, bool ready) = 0;
virtual void stop() = 0;
virtual void tick(uint64_t ticks) = 0;
virtual bool tick(uint64_t ticks) = 0;
# ifdef XMRIG_FEATURE_API
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
virtual void handleRequest(IApiRequest &request) = 0;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
virtual Benchmark *benchmark() const = 0;
virtual void printBenchProgress() const = 0;
# endif
};

View File

@@ -42,14 +42,19 @@ class IWorker
public:
virtual ~IWorker() = default;
virtual bool selfTest() = 0;
virtual const VirtualMemory *memory() const = 0;
virtual size_t id() const = 0;
virtual size_t intensity() const = 0;
virtual uint64_t hashCount() const = 0;
virtual uint64_t timestamp() const = 0;
virtual void start() = 0;
virtual void jobEarlyNotification(const Job&) = 0;
virtual bool selfTest() = 0;
virtual const VirtualMemory *memory() const = 0;
virtual size_t id() const = 0;
virtual size_t intensity() const = 0;
virtual uint64_t rawHashes() const = 0;
virtual void getHashrateData(uint64_t&, uint64_t&) const = 0;
virtual void start() = 0;
virtual void jobEarlyNotification(const Job&) = 0;
# ifdef XMRIG_FEATURE_BENCHMARK
virtual uint64_t benchData() const = 0;
virtual uint64_t benchDoneTime() const = 0;
# endif
};

View File

@@ -55,6 +55,11 @@
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
# include "backend/common/Benchmark.h"
#endif
namespace xmrig {
@@ -304,9 +309,9 @@ void xmrig::CpuBackend::printHashrate(bool details)
Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |",
i,
data.affinity,
Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
Hashrate::format(hashrate()->calc(i + 1, Hashrate::ShortInterval), num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::MediumInterval), num + 8, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
);
i++;
@@ -335,7 +340,7 @@ void xmrig::CpuBackend::setJob(const Job &job)
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm());
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->controller->config()->pools().benchSize());
if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
return;
}
@@ -387,9 +392,9 @@ void xmrig::CpuBackend::stop()
}
void xmrig::CpuBackend::tick(uint64_t ticks)
bool xmrig::CpuBackend::tick(uint64_t ticks)
{
d_ptr->workers.tick(ticks);
return d_ptr->workers.tick(ticks);
}
@@ -459,3 +464,20 @@ void xmrig::CpuBackend::handleRequest(IApiRequest &request)
}
}
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
xmrig::Benchmark *xmrig::CpuBackend::benchmark() const
{
return d_ptr->workers.benchmark();
}
void xmrig::CpuBackend::printBenchProgress() const
{
auto benchmark = d_ptr->workers.benchmark();
if (benchmark) {
benchmark->printProgress();
}
}
#endif

View File

@@ -63,13 +63,18 @@ protected:
void setJob(const Job &job) override;
void start(IWorker *worker, bool ready) override;
void stop() override;
void tick(uint64_t ticks) override;
bool tick(uint64_t ticks) override;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
void handleRequest(IApiRequest &request) override;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
Benchmark *benchmark() const override;
void printBenchProgress() const override;
# endif
private:
CpuBackendPrivate *d_ptr;
};

View File

@@ -34,25 +34,27 @@
namespace xmrig {
static const char *kEnabled = "enabled";
static const char *kHugePages = "huge-pages";
static const char *kHwAes = "hw-aes";
static const char *kMaxThreadsHint = "max-threads-hint";
static const char *kMemoryPool = "memory-pool";
static const char *kPriority = "priority";
static const char *kYield = "yield";
const char *CpuConfig::kEnabled = "enabled";
const char *CpuConfig::kField = "cpu";
const char *CpuConfig::kHugePages = "huge-pages";
const char *CpuConfig::kHugePagesJit = "huge-pages-jit";
const char *CpuConfig::kHwAes = "hw-aes";
const char *CpuConfig::kMaxThreadsHint = "max-threads-hint";
const char *CpuConfig::kMemoryPool = "memory-pool";
const char *CpuConfig::kPriority = "priority";
const char *CpuConfig::kYield = "yield";
#ifdef XMRIG_FEATURE_ASM
static const char *kAsm = "asm";
const char *CpuConfig::kAsm = "asm";
#endif
#ifdef XMRIG_ALGO_ARGON2
static const char *kArgon2Impl = "argon2-impl";
const char *CpuConfig::kArgon2Impl = "argon2-impl";
#endif
#ifdef XMRIG_ALGO_ASTROBWT
static const char* kAstroBWTMaxSize = "astrobwt-max-size";
static const char* kAstroBWTAVX2 = "astrobwt-avx2";
const char *CpuConfig::kAstroBWTMaxSize = "astrobwt-max-size";
const char *CpuConfig::kAstroBWTAVX2 = "astrobwt-avx2";
#endif
@@ -76,6 +78,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator);
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
obj.AddMember(StringRef(kMemoryPool), m_memoryPool < 1 ? Value(m_memoryPool < 0) : Value(m_memoryPool), allocator);
@@ -110,7 +113,7 @@ size_t xmrig::CpuConfig::memPoolSize() const
}
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const
{
std::vector<CpuLaunchData> out;
const CpuThreads &threads = m_threads.get(algorithm);
@@ -122,7 +125,7 @@ std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, cons
out.reserve(threads.count());
for (const CpuThread &thread : threads.data()) {
out.emplace_back(miner, algorithm, *this, thread);
out.emplace_back(miner, algorithm, *this, thread, benchSize);
}
return out;
@@ -132,10 +135,11 @@ std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, cons
void xmrig::CpuConfig::read(const rapidjson::Value &value)
{
if (value.IsObject()) {
m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
m_yield = Json::getBool(value, kYield, m_yield);
m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
m_yield = Json::getBool(value, kYield, m_yield);
setAesMode(Json::getValue(value, kHwAes));
setPriority(Json::getInt(value, kPriority, -1));

View File

@@ -44,16 +44,40 @@ public:
AES_SOFT
};
static const char *kEnabled;
static const char *kField;
static const char *kHugePages;
static const char *kHugePagesJit;
static const char *kHwAes;
static const char *kMaxThreadsHint;
static const char *kMemoryPool;
static const char *kPriority;
static const char *kYield;
# ifdef XMRIG_FEATURE_ASM
static const char *kAsm;
# endif
# ifdef XMRIG_ALGO_ARGON2
static const char *kArgon2Impl;
# endif
# ifdef XMRIG_ALGO_ASTROBWT
static const char *kAstroBWTMaxSize;
static const char *kAstroBWTAVX2;
# endif
CpuConfig() = default;
bool isHwAES() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
size_t memPoolSize() const;
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const;
void read(const rapidjson::Value &value);
inline bool isEnabled() const { return m_enabled; }
inline bool isHugePages() const { return m_hugePages; }
inline bool isHugePagesJit() const { return m_hugePagesJit; }
inline bool isShouldSave() const { return m_shouldSave; }
inline bool isYield() const { return m_yield; }
inline const Assembly &assembly() const { return m_assembly; }
@@ -76,6 +100,7 @@ private:
bool m_astrobwtAVX2 = false;
bool m_enabled = true;
bool m_hugePages = true;
bool m_hugePagesJit = false;
bool m_shouldSave = false;
bool m_yield = true;
int m_astrobwtMaxSize = 550;

View File

@@ -145,7 +145,7 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<CpuThreads> &threads, uint32
template<>
size_t inline generate<Algorithm::ARGON2>(Threads<CpuThreads> &threads, uint32_t limit)
{
return generate("argon2", threads, Algorithm::AR2_CHUKWA, limit);
return generate("argon2", threads, Algorithm::AR2_CHUKWA_V2, limit);
}
#endif

View File

@@ -32,7 +32,7 @@
#include <algorithm>
xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread) :
xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, uint32_t benchSize) :
algorithm(algorithm),
assembly(config.assembly()),
astrobwtAVX2(config.astrobwtAVX2()),
@@ -43,6 +43,7 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit
priority(config.priority()),
affinity(thread.affinity()),
miner(miner),
benchSize(benchSize),
intensity(std::min<uint32_t>(thread.intensity(), algorithm.maxIntensity()))
{
}

View File

@@ -44,12 +44,12 @@ class Miner;
class CpuLaunchData
{
public:
CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread);
CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, uint32_t benchSize);
bool isEqual(const CpuLaunchData &other) const;
CnHash::AlgoVariant av() const;
inline constexpr static Nonce::Backend backend() { return Nonce::CPU; }
inline constexpr static Nonce::Backend backend() { return Nonce::CPU; }
inline bool operator!=(const CpuLaunchData &other) const { return !isEqual(other); }
inline bool operator==(const CpuLaunchData &other) const { return isEqual(other); }
@@ -66,6 +66,7 @@ public:
const int priority;
const int64_t affinity;
const Miner *miner;
const uint32_t benchSize;
const uint32_t intensity;
};

View File

@@ -29,6 +29,7 @@
#include "backend/cpu/CpuWorker.h"
#include "base/tools/Chrono.h"
#include "core/Miner.h"
#include "crypto/cn/CnCtx.h"
#include "crypto/cn/CryptoNight_test.h"
@@ -36,6 +37,7 @@
#include "crypto/common/Nonce.h"
#include "crypto/common/VirtualMemory.h"
#include "crypto/rx/Rx.h"
#include "crypto/rx/RxDataset.h"
#include "crypto/rx/RxVm.h"
#include "net/JobResults.h"
@@ -56,9 +58,9 @@ static constexpr uint32_t kReserveCount = 32768;
template<size_t N>
inline bool nextRound(WorkerJob<N> &job)
inline bool nextRound(WorkerJob<N> &job, uint32_t benchSize)
{
if (!job.nextRound(kReserveCount, 1)) {
if (!job.nextRound(benchSize ? 1 : kReserveCount, 1)) {
JobResults::done(job.currentJob());
return false;
@@ -83,6 +85,7 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
m_av(data.av()),
m_astrobwtMaxSize(data.astrobwtMaxSize * 1000),
m_miner(data.miner),
m_benchSize(data.benchSize),
m_ctx()
{
m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages, false, true, m_node);
@@ -118,7 +121,9 @@ void xmrig::CpuWorker<N>::allocateRandomX_VM()
}
if (!m_vm) {
m_vm = RxVm::create(dataset, m_memory->scratchpad(), !m_hwAES, m_assembly, m_node);
// Try to allocate scratchpad from dataset's 1 GB huge pages, if normal huge pages are not available
uint8_t* scratchpad = m_memory->isHugePages() ? m_memory->scratchpad() : dataset->tryAllocateScrathpad();
m_vm = RxVm::create(dataset, scratchpad ? scratchpad : m_memory->scratchpad(), !m_hwAES, m_assembly, m_node);
}
}
#endif
@@ -177,6 +182,7 @@ bool xmrig::CpuWorker<N>::selfTest()
# ifdef XMRIG_ALGO_ARGON2
if (m_algorithm.family() == Algorithm::ARGON2) {
return verify(Algorithm::AR2_CHUKWA, argon2_chukwa_test_out) &&
verify(Algorithm::AR2_CHUKWA_V2, argon2_chukwa_v2_test_out) &&
verify(Algorithm::AR2_WRKZ, argon2_wrkz_test_out);
}
# endif
@@ -208,23 +214,12 @@ void xmrig::CpuWorker<N>::start()
consumeJob();
}
uint64_t storeStatsMask = 7;
# ifdef XMRIG_ALGO_RANDOMX
bool first = true;
uint64_t tempHash[8] = {};
// RandomX is faster, we don't need to store stats so often
if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) {
storeStatsMask = 63;
}
alignas(16) uint64_t tempHash[8] = {};
# endif
while (!Nonce::isOutdated(Nonce::CPU, m_job.sequence())) {
if ((m_count & storeStatsMask) == 0) {
storeStats();
}
const Job &job = m_job.currentJob();
if (job.algorithm().l3() != m_algorithm.l3()) {
@@ -245,7 +240,7 @@ void xmrig::CpuWorker<N>::start()
randomx_calculate_hash_first(m_vm, tempHash, m_job.blob(), job.size());
}
if (!nextRound(m_job)) {
if (!nextRound(m_job, m_benchSize)) {
break;
}
@@ -265,14 +260,28 @@ void xmrig::CpuWorker<N>::start()
fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height());
}
if (!nextRound(m_job)) {
if (!nextRound(m_job, m_benchSize)) {
break;
};
}
if (valid) {
for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < job.target()) {
const uint64_t value = *reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24);
# ifdef XMRIG_FEATURE_BENCHMARK
if (m_benchSize) {
if (current_job_nonces[i] < m_benchSize) {
m_benchData ^= value;
}
else {
m_benchDoneTime = Chrono::steadyMSecs();
return;
}
}
else
# endif
if (value < job.target()) {
JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32));
}
}
@@ -369,7 +378,7 @@ void xmrig::CpuWorker<N>::consumeJob()
return;
}
m_job.add(m_miner->job(), kReserveCount, Nonce::CPU);
m_job.add(m_miner->job(), m_benchSize ? 1 : kReserveCount, Nonce::CPU);
# ifdef XMRIG_ALGO_RANDOMX
if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) {

View File

@@ -73,6 +73,7 @@ private:
void allocateCnCtx();
void consumeJob();
alignas(16) uint8_t m_hash[N * 32]{ 0 };
const Algorithm m_algorithm;
const Assembly m_assembly;
const bool m_astrobwtAVX2;
@@ -81,8 +82,8 @@ private:
const CnHash::AlgoVariant m_av;
const int m_astrobwtMaxSize;
const Miner *m_miner;
const uint32_t m_benchSize;
cryptonight_ctx *m_ctx[N];
uint8_t m_hash[N * 32]{ 0 };
VirtualMemory *m_memory = nullptr;
WorkerJob<N> m_job;

View File

@@ -72,6 +72,10 @@ endif()
if (XMRIG_ARM)
list(APPEND SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo_arm.cpp)
if (XMRIG_OS_UNIX)
list(APPEND SOURCES_CPUID src/backend/cpu/platform/lscpu_arm.cpp)
endif()
else()
list(APPEND SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo.cpp)
endif()

View File

@@ -28,6 +28,7 @@
#include "backend/cpu/CpuThreads.h"
#include "base/crypto/Algorithm.h"
#include "base/tools/Object.h"
#include "crypto/common/Assembly.h"
@@ -37,6 +38,8 @@ namespace xmrig {
class ICpuInfo
{
public:
XMRIG_DISABLE_COPY_MOVE(ICpuInfo)
enum Vendor : uint32_t {
VENDOR_UNKNOWN,
VENDOR_INTEL,
@@ -60,11 +63,14 @@ public:
FLAG_PDPE1GB,
FLAG_SSE2,
FLAG_SSSE3,
FLAG_SSE41,
FLAG_XOP,
FLAG_POPCNT,
FLAG_CAT_L3,
FLAG_MAX
};
ICpuInfo() = default;
virtual ~ICpuInfo() = default;
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
@@ -79,6 +85,7 @@ public:
virtual bool hasAVX2() const = 0;
virtual bool hasBMI2() const = 0;
virtual bool hasOneGbPages() const = 0;
virtual bool hasCatL3() const = 0;
virtual const char *backend() const = 0;
virtual const char *brand() const = 0;
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
@@ -91,6 +98,7 @@ public:
virtual size_t packages() const = 0;
virtual size_t threads() const = 0;
virtual Vendor vendor() const = 0;
virtual bool jccErratum() const = 0;
};

View File

@@ -57,7 +57,7 @@
namespace xmrig {
static const std::array<const char *, ICpuInfo::FLAG_MAX> flagNames = { "aes", "avx2", "avx512f", "bmi2", "osxsave", "pdpe1gb", "sse2", "ssse3", "xop", "popcnt" };
static const std::array<const char *, ICpuInfo::FLAG_MAX> flagNames = { "aes", "avx2", "avx512f", "bmi2", "osxsave", "pdpe1gb", "sse2", "ssse3", "sse4.1", "xop", "popcnt", "cat_l3" };
static const std::array<const char *, ICpuInfo::MSR_MOD_MAX> msrNames = { "none", "ryzen", "intel", "custom" };
@@ -66,7 +66,7 @@ static inline void cpuid(uint32_t level, int32_t output[4])
memset(output, 0, sizeof(int32_t) * 4);
# ifdef _MSC_VER
__cpuid(output, static_cast<int>(level));
__cpuidex(output, static_cast<int>(level), 0);
# else
__cpuid_count(level, 0, output[0], output[1], output[2], output[3]);
# endif
@@ -141,8 +141,10 @@ static inline bool has_bmi2() { return has_feature(EXTENDED_FEATURES,
static inline bool has_pdpe1gb() { return has_feature(PROCESSOR_EXT_INFO, EDX_Reg, 1 << 26); }
static inline bool has_sse2() { return has_feature(PROCESSOR_INFO, EDX_Reg, 1 << 26); }
static inline bool has_ssse3() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 9); }
static inline bool has_sse41() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 19); }
static inline bool has_xop() { return has_feature(0x80000001, ECX_Reg, 1 << 11); }
static inline bool has_popcnt() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 23); }
static inline bool has_cat_l3() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 15) && has_feature(0x10, EBX_Reg, 1 << 1); }
} // namespace xmrig
@@ -176,8 +178,10 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
m_flags.set(FLAG_PDPE1GB, has_pdpe1gb());
m_flags.set(FLAG_SSE2, has_sse2());
m_flags.set(FLAG_SSSE3, has_ssse3());
m_flags.set(FLAG_SSE41, has_sse41());
m_flags.set(FLAG_XOP, has_xop());
m_flags.set(FLAG_POPCNT, has_popcnt());
m_flags.set(FLAG_CAT_L3, has_cat_l3());
# ifdef XMRIG_FEATURE_ASM
if (hasAES()) {
@@ -208,6 +212,37 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
m_vendor = VENDOR_INTEL;
m_assembly = Assembly::INTEL;
m_msrMod = MSR_MOD_INTEL;
struct
{
unsigned int stepping : 4;
unsigned int model : 4;
unsigned int family : 4;
unsigned int processor_type : 2;
unsigned int reserved1 : 2;
unsigned int ext_model : 4;
unsigned int ext_family : 8;
unsigned int reserved2 : 4;
} processor_info;
cpuid(1, data);
memcpy(&processor_info, data, sizeof(processor_info));
// Intel JCC erratum mitigation
if (processor_info.family == 6) {
const uint32_t model = processor_info.model | (processor_info.ext_model << 4);
const uint32_t stepping = processor_info.stepping;
// Affected CPU models and stepping numbers are taken from https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf
m_jccErratum =
((model == 0x4E) && (stepping == 0x3)) ||
((model == 0x55) && (stepping == 0x4)) ||
((model == 0x5E) && (stepping == 0x3)) ||
((model == 0x8E) && (stepping >= 0x9) && (stepping <= 0xC)) ||
((model == 0x9E) && (stepping >= 0x9) && (stepping <= 0xD)) ||
((model == 0xA6) && (stepping == 0x0)) ||
((model == 0xAE) && (stepping == 0xA));
}
}
}
# endif

View File

@@ -51,6 +51,7 @@ protected:
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); }
inline bool hasCatL3() const override { return has(FLAG_CAT_L3); }
inline const char *brand() const override { return m_brand; }
inline MsrMod msrMod() const override { return m_msrMod; }
inline size_t cores() const override { return 0; }
@@ -60,11 +61,13 @@ protected:
inline size_t packages() const override { return 1; }
inline size_t threads() const override { return m_threads; }
inline Vendor vendor() const override { return m_vendor; }
inline bool jccErratum() const override { return m_jccErratum; }
protected:
char m_brand[64 + 6]{};
size_t m_threads;
Vendor m_vendor = VENDOR_UNKNOWN;
bool m_jccErratum = false;
private:
Assembly m_assembly = Assembly::NONE;

View File

@@ -1,10 +1,4 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <support@xmrig.com>
*
@@ -22,6 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/tools/String.h"
#include <array>
#include <cstring>
#include <thread>
@@ -37,6 +35,15 @@
#include "3rdparty/rapidjson/document.h"
#ifdef XMRIG_OS_UNIX
namespace xmrig {
extern String cpu_name_arm();
} // namespace xmrig
#endif
xmrig::BasicCpuInfo::BasicCpuInfo() :
m_threads(std::thread::hardware_concurrency())
{
@@ -53,6 +60,13 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
m_flags.set(FLAG_AES, true);
# endif
# endif
# ifdef XMRIG_OS_UNIX
auto name = cpu_name_arm();
if (!name.isNull()) {
strncpy(m_brand, name, sizeof(m_brand) - 1);
}
# endif
}

View File

@@ -218,10 +218,11 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm, uint3
{
# ifdef XMRIG_ALGO_ASTROBWT
if (algorithm == Algorithm::ASTROBWT_DERO) {
return BasicCpuInfo::threads(algorithm, limit);
return allThreads(algorithm, limit);
}
# endif
# ifndef XMRIG_ARM
if (L2() == 0 && L3() == 0) {
return BasicCpuInfo::threads(algorithm, limit);
}
@@ -263,11 +264,35 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm, uint3
}
return threads;
# else
return allThreads(algorithm, limit);
# endif
}
xmrig::CpuThreads xmrig::HwlocCpuInfo::allThreads(const Algorithm &algorithm, uint32_t limit) const
{
CpuThreads threads;
threads.reserve(m_threads);
hwloc_obj_t pu = nullptr;
while ((pu = hwloc_get_next_obj_by_type(m_topology, HWLOC_OBJ_PU, pu)) != nullptr) {
threads.add(pu->os_index, 0);
}
if (threads.isEmpty()) {
return BasicCpuInfo::threads(algorithm, limit);
}
return threads;
}
void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const
{
# ifndef XMRIG_ARM
constexpr size_t oneMiB = 1024U * 1024U;
size_t PUs = countByType(cache, HWLOC_OBJ_PU);
@@ -366,4 +391,5 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
pu_id++;
}
# endif
}

View File

@@ -70,6 +70,7 @@ protected:
inline size_t packages() const override { return m_packages; }
private:
CpuThreads allThreads(const Algorithm &algorithm, uint32_t limit) const;
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;

View File

@@ -0,0 +1,314 @@
/* XMRig
* Copyright 2018 Riku Voipio <riku.voipio@iki.fi>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/tools/String.h"
#include <cstdio>
#include <cctype>
namespace xmrig {
struct lscpu_desc
{
String vendor;
String model;
inline bool isReady() const { return !vendor.isNull() && !model.isNull(); }
};
struct id_part {
const int id;
const char *name;
};
struct hw_impl {
const int id;
const id_part *parts;
const char *name;
};
static const id_part arm_part[] = {
{ 0x810, "ARM810" },
{ 0x920, "ARM920" },
{ 0x922, "ARM922" },
{ 0x926, "ARM926" },
{ 0x940, "ARM940" },
{ 0x946, "ARM946" },
{ 0x966, "ARM966" },
{ 0xa20, "ARM1020" },
{ 0xa22, "ARM1022" },
{ 0xa26, "ARM1026" },
{ 0xb02, "ARM11 MPCore" },
{ 0xb36, "ARM1136" },
{ 0xb56, "ARM1156" },
{ 0xb76, "ARM1176" },
{ 0xc05, "Cortex-A5" },
{ 0xc07, "Cortex-A7" },
{ 0xc08, "Cortex-A8" },
{ 0xc09, "Cortex-A9" },
{ 0xc0d, "Cortex-A17" }, /* Originally A12 */
{ 0xc0f, "Cortex-A15" },
{ 0xc0e, "Cortex-A17" },
{ 0xc14, "Cortex-R4" },
{ 0xc15, "Cortex-R5" },
{ 0xc17, "Cortex-R7" },
{ 0xc18, "Cortex-R8" },
{ 0xc20, "Cortex-M0" },
{ 0xc21, "Cortex-M1" },
{ 0xc23, "Cortex-M3" },
{ 0xc24, "Cortex-M4" },
{ 0xc27, "Cortex-M7" },
{ 0xc60, "Cortex-M0+" },
{ 0xd01, "Cortex-A32" },
{ 0xd03, "Cortex-A53" },
{ 0xd04, "Cortex-A35" },
{ 0xd05, "Cortex-A55" },
{ 0xd07, "Cortex-A57" },
{ 0xd08, "Cortex-A72" },
{ 0xd09, "Cortex-A73" },
{ 0xd0a, "Cortex-A75" },
{ 0xd0b, "Cortex-A76" },
{ 0xd0c, "Neoverse-N1" },
{ 0xd13, "Cortex-R52" },
{ 0xd20, "Cortex-M23" },
{ 0xd21, "Cortex-M33" },
{ 0xd4a, "Neoverse-E1" },
{ -1, nullptr },
};
static const id_part brcm_part[] = {
{ 0x0f, "Brahma B15" },
{ 0x100, "Brahma B53" },
{ 0x516, "ThunderX2" },
{ -1, nullptr },
};
static const id_part dec_part[] = {
{ 0xa10, "SA110" },
{ 0xa11, "SA1100" },
{ -1, nullptr },
};
static const id_part cavium_part[] = {
{ 0x0a0, "ThunderX" },
{ 0x0a1, "ThunderX 88XX" },
{ 0x0a2, "ThunderX 81XX" },
{ 0x0a3, "ThunderX 83XX" },
{ 0x0af, "ThunderX2 99xx" },
{ -1, nullptr },
};
static const id_part apm_part[] = {
{ 0x000, "X-Gene" },
{ -1, nullptr },
};
static const id_part qcom_part[] = {
{ 0x00f, "Scorpion" },
{ 0x02d, "Scorpion" },
{ 0x04d, "Krait" },
{ 0x06f, "Krait" },
{ 0x201, "Kryo" },
{ 0x205, "Kryo" },
{ 0x211, "Kryo" },
{ 0x800, "Falkor V1/Kryo" },
{ 0x801, "Kryo V2" },
{ 0xc00, "Falkor" },
{ 0xc01, "Saphira" },
{ -1, nullptr },
};
static const id_part samsung_part[] = {
{ 0x001, "exynos-m1" },
{ -1, nullptr },
};
static const id_part nvidia_part[] = {
{ 0x000, "Denver" },
{ 0x003, "Denver 2" },
{ -1, nullptr },
};
static const id_part marvell_part[] = {
{ 0x131, "Feroceon 88FR131" },
{ 0x581, "PJ4/PJ4b" },
{ 0x584, "PJ4B-MP" },
{ -1, nullptr },
};
static const id_part faraday_part[] = {
{ 0x526, "FA526" },
{ 0x626, "FA626" },
{ -1, nullptr },
};
static const id_part intel_part[] = {
{ 0x200, "i80200" },
{ 0x210, "PXA250A" },
{ 0x212, "PXA210A" },
{ 0x242, "i80321-400" },
{ 0x243, "i80321-600" },
{ 0x290, "PXA250B/PXA26x" },
{ 0x292, "PXA210B" },
{ 0x2c2, "i80321-400-B0" },
{ 0x2c3, "i80321-600-B0" },
{ 0x2d0, "PXA250C/PXA255/PXA26x" },
{ 0x2d2, "PXA210C" },
{ 0x411, "PXA27x" },
{ 0x41c, "IPX425-533" },
{ 0x41d, "IPX425-400" },
{ 0x41f, "IPX425-266" },
{ 0x682, "PXA32x" },
{ 0x683, "PXA930/PXA935" },
{ 0x688, "PXA30x" },
{ 0x689, "PXA31x" },
{ 0xb11, "SA1110" },
{ 0xc12, "IPX1200" },
{ -1, nullptr },
};
static const id_part hisi_part[] = {
{ 0xd01, "Kunpeng-920" }, /* aka tsv110 */
{ -1, nullptr },
};
static const hw_impl hw_implementer[] = {
{ 0x41, arm_part, "ARM" },
{ 0x42, brcm_part, "Broadcom" },
{ 0x43, cavium_part, "Cavium" },
{ 0x44, dec_part, "DEC" },
{ 0x48, hisi_part, "HiSilicon" },
{ 0x4e, nvidia_part, "Nvidia" },
{ 0x50, apm_part, "APM" },
{ 0x51, qcom_part, "Qualcomm" },
{ 0x53, samsung_part, "Samsung" },
{ 0x56, marvell_part, "Marvell" },
{ 0x66, faraday_part, "Faraday" },
{ 0x69, intel_part, "Intel" }
};
static bool lookup(char *line, const char *pattern, String &value)
{
if (!*line || !value.isNull()) {
return false;
}
char *p;
int len = strlen(pattern);
if (strncmp(line, pattern, len) != 0) {
return false;
}
for (p = line + len; isspace(*p); p++);
if (*p != ':') {
return false;
}
for (++p; isspace(*p); p++);
if (!*p) {
return false;
}
const char *v = p;
len = strlen(line) - 1;
for (p = line + len; isspace(*(p-1)); p--);
*p = '\0';
value = v;
return true;
}
static bool read_basicinfo(lscpu_desc *desc)
{
auto fp = fopen("/proc/cpuinfo", "r");
if (!fp) {
return false;
}
char buf[BUFSIZ];
while (fgets(buf, sizeof(buf), fp) != nullptr) {
if (!lookup(buf, "CPU implementer", desc->vendor)) {
lookup(buf, "CPU part", desc->model);
}
if (desc->isReady()) {
break;
}
}
fclose(fp);
return desc->isReady();
}
static bool arm_cpu_decode(lscpu_desc *desc)
{
if ((strncmp(desc->vendor, "0x", 2) != 0 || strncmp(desc->model, "0x", 2) != 0)) {
return false;
}
const int vendor = strtol(desc->vendor, nullptr, 0);
const int model = strtol(desc->model, nullptr, 0);
for (const auto &impl : hw_implementer) {
if (impl.id != vendor) {
continue;
}
for (size_t i = 0; impl.parts[i].id != -1; ++i) {
if (impl.parts[i].id == model) {
desc->model = impl.parts[i].name;
return true;
}
}
}
return false;
}
String cpu_name_arm()
{
lscpu_desc desc;
if (read_basicinfo(&desc) && arm_cpu_decode(&desc)) {
return desc.model;
}
return {};
}
} // namespace xmrig

View File

@@ -152,7 +152,9 @@ public:
}
if (!CudaLib::init(cuda.loader())) {
return printDisabled(kLabel, RED_S " (failed to load CUDA plugin)");
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") RED_BOLD("disabled ") RED("(%s)"), kLabel, CudaLib::lastError());
return;
}
runtimeVersion = CudaLib::runtimeVersion();
@@ -407,9 +409,9 @@ void xmrig::CudaBackend::printHashrate(bool details)
Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") GREEN(" %s"),
i,
data.thread.affinity(),
Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
data.device.index(),
data.device.topology().toString().data(),
data.device.name().data()
@@ -419,9 +421,9 @@ void xmrig::CudaBackend::printHashrate(bool details)
}
Log::print(WHITE_BOLD_S "| - | - | %8s | %8s | %8s |",
Hashrate::format(hashrate()->calc(Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3)
Hashrate::format(hashrate_short * scale, num, sizeof num / 3),
Hashrate::format(hashrate_medium * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate_large * scale, num + 16 * 2, sizeof num / 3)
);
}
@@ -499,9 +501,9 @@ void xmrig::CudaBackend::stop()
}
void xmrig::CudaBackend::tick(uint64_t ticks)
bool xmrig::CudaBackend::tick(uint64_t ticks)
{
d_ptr->workers.tick(ticks);
return d_ptr->workers.tick(ticks);
}

View File

@@ -63,13 +63,18 @@ protected:
void setJob(const Job &job) override;
void start(IWorker *worker, bool ready) override;
void stop() override;
void tick(uint64_t ticks) override;
bool tick(uint64_t ticks) override;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
void handleRequest(IApiRequest &request) override;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
inline Benchmark *benchmark() const override { return nullptr; }
inline void printBenchProgress() const override {}
# endif
private:
CudaBackendPrivate *d_ptr;
};

View File

@@ -30,9 +30,9 @@
xmrig::CudaLaunchData::CudaLaunchData(const Miner *miner, const Algorithm &algorithm, const CudaThread &thread, const CudaDevice &device) :
algorithm(algorithm),
miner(miner),
device(device),
thread(thread)
thread(thread),
miner(miner)
{
}

View File

@@ -54,9 +54,10 @@ public:
static const char *tag();
const Algorithm algorithm;
const Miner *miner;
const CudaDevice &device;
const CudaThread thread;
const Miner *miner;
const uint32_t benchSize = 0;
};

View File

@@ -62,7 +62,6 @@ std::atomic<bool> CudaWorker::ready;
static inline bool isReady() { return !Nonce::isPaused() && CudaWorker::ready; }
static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / intensity + 1; }
} // namespace xmrig
@@ -120,6 +119,12 @@ xmrig::CudaWorker::~CudaWorker()
}
uint64_t xmrig::CudaWorker::rawHashes() const
{
return m_hashrateData.interpolate(Chrono::steadyMSecs());
}
void xmrig::CudaWorker::jobEarlyNotification(const Job& job)
{
if (m_runner) {
@@ -170,8 +175,7 @@ void xmrig::CudaWorker::start()
JobResults::submit(m_job.currentJob(), foundNonce, foundCount, m_deviceIndex);
}
const size_t batch_size = intensity();
if (!Nonce::isOutdated(Nonce::CUDA, m_job.sequence()) && !m_job.nextRound(roundSize(batch_size), batch_size)) {
if (!Nonce::isOutdated(Nonce::CUDA, m_job.sequence()) && !m_job.nextRound(1, intensity())) {
JobResults::done(m_job.currentJob());
}
@@ -192,8 +196,7 @@ bool xmrig::CudaWorker::consumeJob()
return false;
}
const size_t batch_size = intensity();
m_job.add(m_miner->job(), roundSize(batch_size) * batch_size, Nonce::CUDA);
m_job.add(m_miner->job(), intensity(), Nonce::CUDA);
return m_runner->set(m_job.currentJob(), m_job.blob());
}
@@ -207,5 +210,8 @@ void xmrig::CudaWorker::storeStats()
m_count += m_runner ? m_runner->processedHashes() : 0;
const uint64_t timeStamp = Chrono::steadyMSecs();
m_hashrateData.addDataPoint(m_count, timeStamp);
Worker::storeStats();
}

View File

@@ -27,6 +27,7 @@
#define XMRIG_CUDAWORKER_H
#include "backend/common/HashrateInterpolator.h"
#include "backend/common/Worker.h"
#include "backend/common/WorkerJob.h"
#include "backend/cuda/CudaLaunchData.h"
@@ -49,6 +50,7 @@ public:
~CudaWorker() override;
uint64_t rawHashes() const override;
void jobEarlyNotification(const Job&) override;
static std::atomic<bool> ready;
@@ -67,6 +69,8 @@ private:
ICudaRunner *m_runner = nullptr;
WorkerJob<1> m_job;
uint32_t m_deviceIndex;
HashrateInterpolator m_hashrateData;
};

View File

@@ -1,3 +1,9 @@
if (BUILD_STATIC AND XMRIG_OS_UNIX AND WITH_CUDA)
message(WARNING "CUDA backend is not compatible with static build, use -DWITH_CUDA=OFF to suppress this warning")
set(WITH_CUDA OFF)
endif()
if (WITH_CUDA)
add_definitions(/DXMRIG_FEATURE_CUDA)

View File

@@ -30,6 +30,7 @@
#include "backend/cuda/wrappers/CudaLib.h"
#include "base/io/Env.h"
#include "base/io/log/Log.h"
#include "base/kernel/Process.h"
#include "crypto/rx/RxAlgo.h"
@@ -46,6 +47,14 @@ enum Version : uint32_t
static uv_lib_t cudaLib;
#if defined(__APPLE__)
static String defaultLoader = "/System/Library/Frameworks/OpenCL.framework/OpenCL";
#elif defined(_WIN32)
static String defaultLoader = "xmrig-cuda.dll";
#else
static String defaultLoader = "libxmrig-cuda.so";
#endif
static const char *kAlloc = "alloc";
static const char *kAstroBWTHash = "astroBWTHash";
@@ -125,11 +134,12 @@ static setJob_v2_t pSetJob_v2 = nullptr;
static version_t pVersion = nullptr;
#define DLSYM(x) if (uv_dlsym(&cudaLib, k##x, reinterpret_cast<void**>(&p##x)) == -1) { throw std::runtime_error("symbol not found (" #x ")"); }
#define DLSYM(x) if (uv_dlsym(&cudaLib, k##x, reinterpret_cast<void**>(&p##x)) == -1) { throw std::runtime_error(std::string("symbol not found: ") + k##x); }
bool CudaLib::m_initialized = false;
bool CudaLib::m_ready = false;
String CudaLib::m_error;
String CudaLib::m_loader;
@@ -139,9 +149,22 @@ String CudaLib::m_loader;
bool xmrig::CudaLib::init(const char *fileName)
{
if (!m_initialized) {
m_loader = fileName == nullptr ? defaultLoader() : Env::expand(fileName);
m_ready = uv_dlopen(m_loader, &cudaLib) == 0 && load();
m_initialized = true;
m_loader = fileName == nullptr ? defaultLoader : Env::expand(fileName);
if (!open()) {
return false;
}
try {
load();
} catch (std::exception &ex) {
m_error = (std::string(m_loader) + ": " + ex.what()).c_str();
return false;
}
m_ready = true;
}
return m_ready;
@@ -150,7 +173,7 @@ bool xmrig::CudaLib::init(const char *fileName)
const char *xmrig::CudaLib::lastError() noexcept
{
return uv_dlerror(&cudaLib);
return m_error;
}
@@ -344,66 +367,70 @@ void xmrig::CudaLib::release(nvid_ctx *ctx) noexcept
}
bool xmrig::CudaLib::load()
bool xmrig::CudaLib::open()
{
if (uv_dlsym(&cudaLib, kVersion, reinterpret_cast<void**>(&pVersion)) == -1) {
m_error = nullptr;
if (uv_dlopen(m_loader, &cudaLib) == 0) {
return true;
}
# ifdef XMRIG_OS_LINUX
if (m_loader == defaultLoader) {
m_loader = Process::location(Process::ExeLocation, m_loader);
}
else {
return false;
}
if (uv_dlopen(m_loader, &cudaLib) == 0) {
return true;
}
# endif
m_error = uv_dlerror(&cudaLib);
return false;
}
void xmrig::CudaLib::load()
{
DLSYM(Version);
if (pVersion(ApiVersion) != 3U) {
return false;
throw std::runtime_error("API version mismatch");
}
uv_dlsym(&cudaLib, kDeviceInfo_v2, reinterpret_cast<void**>(&pDeviceInfo_v2));
uv_dlsym(&cudaLib, kSetJob_v2, reinterpret_cast<void**>(&pSetJob_v2));
DLSYM(Alloc);
DLSYM(CnHash);
DLSYM(DeviceCount);
DLSYM(DeviceInit);
DLSYM(DeviceInt);
DLSYM(DeviceName);
DLSYM(DeviceUint);
DLSYM(DeviceUlong);
DLSYM(Init);
DLSYM(LastError);
DLSYM(PluginVersion);
DLSYM(Release);
DLSYM(RxHash);
DLSYM(RxPrepare);
DLSYM(AstroBWTHash);
DLSYM(AstroBWTPrepare);
DLSYM(KawPowHash);
DLSYM(KawPowPrepare_v2);
DLSYM(KawPowStopHash);
try {
DLSYM(Alloc);
DLSYM(CnHash);
DLSYM(DeviceCount);
DLSYM(DeviceInit);
DLSYM(DeviceInt);
DLSYM(DeviceName);
DLSYM(DeviceUint);
DLSYM(DeviceUlong);
DLSYM(Init);
DLSYM(LastError);
DLSYM(PluginVersion);
DLSYM(Release);
DLSYM(RxHash);
DLSYM(RxPrepare);
DLSYM(AstroBWTHash);
DLSYM(AstroBWTPrepare);
DLSYM(KawPowHash);
DLSYM(KawPowPrepare_v2);
DLSYM(KawPowStopHash);
DLSYM(Version);
uv_dlsym(&cudaLib, kDeviceInfo_v2, reinterpret_cast<void**>(&pDeviceInfo_v2));
if (!pDeviceInfo_v2) {
DLSYM(DeviceInfo);
}
if (!pDeviceInfo_v2) {
DLSYM(DeviceInfo);
}
if (!pSetJob_v2) {
DLSYM(SetJob);
}
} catch (std::exception &ex) {
LOG_ERR("Error loading CUDA library: %s", ex.what());
return false;
uv_dlsym(&cudaLib, kSetJob_v2, reinterpret_cast<void**>(&pSetJob_v2));
if (!pSetJob_v2) {
DLSYM(SetJob);
}
pInit();
return true;
}
xmrig::String xmrig::CudaLib::defaultLoader()
{
# if defined(__APPLE__)
return "/System/Library/Frameworks/OpenCL.framework/OpenCL"; // FIXME
# elif defined(_WIN32)
return "xmrig-cuda.dll";
# else
return "libxmrig-cuda.so";
# endif
}

View File

@@ -99,11 +99,12 @@ public:
static void release(nvid_ctx *ctx) noexcept;
private:
static bool load();
static String defaultLoader();
static bool open();
static void load();
static bool m_initialized;
static bool m_ready;
static String m_error;
static String m_loader;
};

View File

@@ -385,9 +385,9 @@ void xmrig::OclBackend::printHashrate(bool details)
Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s",
i,
data.affinity,
Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
data.device.index(),
data.device.topology().toString().data(),
data.device.printableName().data()
@@ -397,9 +397,9 @@ void xmrig::OclBackend::printHashrate(bool details)
}
Log::print(WHITE_BOLD_S "| - | - | %8s | %8s | %8s |",
Hashrate::format(hashrate()->calc(Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3)
Hashrate::format(hashrate_short * scale, num, sizeof num / 3),
Hashrate::format(hashrate_medium * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate_large * scale, num + 16 * 2, sizeof num / 3)
);
}
@@ -485,9 +485,9 @@ void xmrig::OclBackend::stop()
}
void xmrig::OclBackend::tick(uint64_t ticks)
bool xmrig::OclBackend::tick(uint64_t ticks)
{
d_ptr->workers.tick(ticks);
return d_ptr->workers.tick(ticks);
}

View File

@@ -63,13 +63,18 @@ protected:
void setJob(const Job &job) override;
void start(IWorker *worker, bool ready) override;
void stop() override;
void tick(uint64_t ticks) override;
bool tick(uint64_t ticks) override;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
void handleRequest(IApiRequest &request) override;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
inline Benchmark *benchmark() const override { return nullptr; }
inline void printBenchProgress() const override {}
# endif
private:
OclBackendPrivate *d_ptr;
};

View File

@@ -67,6 +67,7 @@ public:
const OclDevice device;
const OclPlatform platform;
const OclThread thread;
const uint32_t benchSize = 0;
};

View File

@@ -56,12 +56,10 @@
namespace xmrig {
static constexpr uint32_t kReserveCount = 32768;
std::atomic<bool> OclWorker::ready;
static inline bool isReady() { return !Nonce::isPaused() && OclWorker::ready; }
static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / intensity + 1; }
static inline void printError(size_t id, const char *error)
@@ -78,7 +76,6 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) :
Worker(id, data.affinity, -1),
m_algorithm(data.algorithm),
m_miner(data.miner),
m_intensity(data.thread.intensity()),
m_sharedData(OclSharedState::get(data.device.index())),
m_deviceIndex(data.device.index())
{
@@ -140,6 +137,12 @@ xmrig::OclWorker::~OclWorker()
}
uint64_t xmrig::OclWorker::rawHashes() const
{
return m_hashrateData.interpolate(Chrono::steadyMSecs());
}
void xmrig::OclWorker::jobEarlyNotification(const Job& job)
{
if (m_runner) {
@@ -164,8 +167,6 @@ void xmrig::OclWorker::start()
{
cl_uint results[0x100];
const uint32_t runnerRoundSize = m_runner->roundSize();
while (Nonce::sequence(Nonce::OPENCL) > 0) {
if (!isReady()) {
m_sharedData.setResumeCounter(0);
@@ -204,7 +205,7 @@ void xmrig::OclWorker::start()
JobResults::submit(m_job.currentJob(), results, results[0xFF], m_deviceIndex);
}
if (!Nonce::isOutdated(Nonce::OPENCL, m_job.sequence()) && !m_job.nextRound(roundSize(runnerRoundSize), runnerRoundSize)) {
if (!Nonce::isOutdated(Nonce::OPENCL, m_job.sequence()) && !m_job.nextRound(1, intensity())) {
JobResults::done(m_job.currentJob());
}
@@ -225,7 +226,7 @@ bool xmrig::OclWorker::consumeJob()
return false;
}
m_job.add(m_miner->job(), roundSize(m_intensity) * m_intensity, Nonce::OPENCL);
m_job.add(m_miner->job(), intensity(), Nonce::OPENCL);
try {
m_runner->set(m_job.currentJob(), m_job.blob());
@@ -247,8 +248,11 @@ void xmrig::OclWorker::storeStats(uint64_t t)
}
m_count += m_runner->processedHashes();
const uint64_t timeStamp = Chrono::steadyMSecs();
m_sharedData.setRunTime(Chrono::steadyMSecs() - t);
m_hashrateData.addDataPoint(m_count, timeStamp);
m_sharedData.setRunTime(timeStamp - t);
Worker::storeStats();
}

View File

@@ -27,6 +27,7 @@
#define XMRIG_OCLWORKER_H
#include "backend/common/HashrateInterpolator.h"
#include "backend/common/Worker.h"
#include "backend/common/WorkerJob.h"
#include "backend/opencl/OclLaunchData.h"
@@ -50,6 +51,7 @@ public:
~OclWorker() override;
uint64_t rawHashes() const override;
void jobEarlyNotification(const Job&) override;
static std::atomic<bool> ready;
@@ -65,11 +67,12 @@ private:
const Algorithm m_algorithm;
const Miner *m_miner;
const uint32_t m_intensity;
IOclRunner *m_runner = nullptr;
OclSharedData &m_sharedData;
WorkerJob<1> m_job;
uint32_t m_deviceIndex;
HashrateInterpolator m_hashrateData;
};

View File

@@ -19,11 +19,11 @@
#define ALGO_CN_CCX 18
#define ALGO_RX_0 19
#define ALGO_RX_WOW 20
#define ALGO_RX_LOKI 21
#define ALGO_RX_ARQMA 22
#define ALGO_RX_SFX 23
#define ALGO_RX_KEVA 24
#define ALGO_AR2_CHUKWA 25
#define ALGO_RX_ARQMA 21
#define ALGO_RX_SFX 22
#define ALGO_RX_KEVA 23
#define ALGO_AR2_CHUKWA 24
#define ALGO_AR2_CHUKWA_V2 25
#define ALGO_AR2_WRKZ 26
#define ALGO_ASTROBWT_DERO 27
#define ALGO_KAWPOW_RVN 28

View File

@@ -71,7 +71,7 @@ inline ulong getIdx()
__attribute__((reqd_work_group_size(8, 8, 1)))
__kernel void cn0(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states, uint Threads)
__kernel void cn0(__global ulong *input, int inlen, __global uint4 *Scratchpad, __global ulong *states, uint Threads)
{
uint ExpandedKey1[40];
__local uint AES0[256], AES1[256], AES2[256], AES3[256];
@@ -109,34 +109,25 @@ __kernel void cn0(__global ulong *input, __global uint4 *Scratchpad, __global ul
if (get_local_id(1) == 0) {
__local ulong* State = State_buf + get_local_id(0) * 25;
((__local ulong8 *)State)[0] = vload8(0, input);
State[8] = input[8];
State[9] = input[9];
State[10] = input[10];
State[11] = input[11];
State[12] = input[12];
State[13] = input[13];
State[14] = input[14];
State[15] = input[15];
((__local uint *)State)[9] &= 0x00FFFFFFU;
((__local uint *)State)[9] |= (((uint)get_global_id(0)) & 0xFF) << 24;
((__local uint *)State)[10] &= 0xFF000000U;
/* explicit cast to `uint` is required because some OpenCL implementations (e.g. NVIDIA)
* handle get_global_id and get_global_offset as signed long long int and add
* 0xFFFFFFFF... to `get_global_id` if we set on host side a 32bit offset where the first bit is `1`
* (even if it is correct casted to unsigned on the host)
*/
((__local uint *)State)[10] |= (((uint)get_global_id(0) >> 8));
// Last bit of padding
State[16] = 0x8000000000000000UL;
for (int i = 17; i < 25; ++i) {
State[i] = 0x00UL;
#pragma unroll
for (int i = 0; i < 25; ++i) {
State[i] = 0;
}
keccakf1600_2(State);
// Input length must be a multiple of 136 and padded on the host side
for (int i = 0; inlen > 0; i += 17, inlen -= 136) {
#pragma unroll
for (int j = 0; j < 17; ++j) {
State[j] ^= input[i + j];
}
if (i == 0) {
((__local uint *)State)[9] &= 0x00FFFFFFU;
((__local uint *)State)[9] |= (((uint)get_global_id(0)) & 0xFF) << 24;
((__local uint *)State)[10] &= 0xFF000000U;
((__local uint *)State)[10] |= (((uint)get_global_id(0) >> 8));
}
keccakf1600_2(State);
}
#pragma unroll 1
for (int i = 0; i < 25; ++i) {
@@ -908,7 +899,7 @@ __kernel void Blake(__global ulong *states, __global uint *BranchBuf, __global u
((uint8 *)h)[0] = vload8(0U, c_IV256);
for (uint i = 0; i < 3; ++i) {
for (volatile uint i = 0; i < 3; ++i) {
((uint16 *)m)[0] = vload16(i, (__global uint *)states);
for (uint x = 0; x < 16; ++x) {
m[x] = SWAP4(m[x]);

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,6 @@
#include "randomx_constants_monero.h"
#elif (ALGO == ALGO_RX_WOW)
#include "randomx_constants_wow.h"
#elif (ALGO == ALGO_RX_LOKI)
#include "randomx_constants_loki.h"
#elif (ALGO == ALGO_RX_ARQMA)
#include "randomx_constants_arqma.h"
#elif (ALGO == ALGO_RX_KEVA)

File diff suppressed because it is too large Load Diff

View File

@@ -1,96 +0,0 @@
/*
Copyright (c) 2019 SChernykh
This file is part of RandomX OpenCL.
RandomX OpenCL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RandomX OpenCL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RandomX OpenCL. If not, see <http://www.gnu.org/licenses/>.
*/
//Dataset base size in bytes. Must be a power of 2.
#define RANDOMX_DATASET_BASE_SIZE 2147483648
//Dataset extra size. Must be divisible by 64.
#define RANDOMX_DATASET_EXTRA_SIZE 33554368
//Scratchpad L3 size in bytes. Must be a power of 2.
#define RANDOMX_SCRATCHPAD_L3 2097152
//Scratchpad L2 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L3.
#define RANDOMX_SCRATCHPAD_L2 262144
//Scratchpad L1 size in bytes. Must be a power of two (minimum 64) and less than or equal to RANDOMX_SCRATCHPAD_L2.
#define RANDOMX_SCRATCHPAD_L1 16384
//Jump condition mask size in bits.
#define RANDOMX_JUMP_BITS 8
//Jump condition mask offset in bits. The sum of RANDOMX_JUMP_BITS and RANDOMX_JUMP_OFFSET must not exceed 16.
#define RANDOMX_JUMP_OFFSET 8
//Integer instructions
#define RANDOMX_FREQ_IADD_RS 25
#define RANDOMX_FREQ_IADD_M 7
#define RANDOMX_FREQ_ISUB_R 16
#define RANDOMX_FREQ_ISUB_M 7
#define RANDOMX_FREQ_IMUL_R 16
#define RANDOMX_FREQ_IMUL_M 4
#define RANDOMX_FREQ_IMULH_R 4
#define RANDOMX_FREQ_IMULH_M 1
#define RANDOMX_FREQ_ISMULH_R 4
#define RANDOMX_FREQ_ISMULH_M 1
#define RANDOMX_FREQ_IMUL_RCP 8
#define RANDOMX_FREQ_INEG_R 2
#define RANDOMX_FREQ_IXOR_R 15
#define RANDOMX_FREQ_IXOR_M 5
#define RANDOMX_FREQ_IROR_R 8
#define RANDOMX_FREQ_IROL_R 2
#define RANDOMX_FREQ_ISWAP_R 4
//Floating point instructions
#define RANDOMX_FREQ_FSWAP_R 4
#define RANDOMX_FREQ_FADD_R 16
#define RANDOMX_FREQ_FADD_M 5
#define RANDOMX_FREQ_FSUB_R 16
#define RANDOMX_FREQ_FSUB_M 5
#define RANDOMX_FREQ_FSCAL_R 6
#define RANDOMX_FREQ_FMUL_R 32
#define RANDOMX_FREQ_FDIV_M 4
#define RANDOMX_FREQ_FSQRT_R 6
//Control instructions
#define RANDOMX_FREQ_CBRANCH 16
#define RANDOMX_FREQ_CFROUND 1
//Store instruction
#define RANDOMX_FREQ_ISTORE 16
//No-op instruction
#define RANDOMX_FREQ_NOP 0
#define RANDOMX_DATASET_ITEM_SIZE 64
#define RANDOMX_PROGRAM_SIZE 320
#define HASH_SIZE 64
#define ENTROPY_SIZE (128 + RANDOMX_PROGRAM_SIZE * 8)
#define REGISTERS_SIZE 256
#define IMM_BUF_SIZE (RANDOMX_PROGRAM_SIZE * 4 - REGISTERS_SIZE)
#define IMM_INDEX_COUNT ((IMM_BUF_SIZE / 4) - 2)
#define VM_STATE_SIZE (REGISTERS_SIZE + IMM_BUF_SIZE + RANDOMX_PROGRAM_SIZE * 4)
#define ROUNDING_MODE (RANDOMX_FREQ_CFROUND ? -1 : 0)
// Scratchpad L1/L2/L3 bits
#define LOC_L1 (32 - 14)
#define LOC_L2 (32 - 18)
#define LOC_L3 (32 - 21)

View File

@@ -38,10 +38,11 @@ void xmrig::Cn0Kernel::enqueue(cl_command_queue queue, uint32_t nonce, size_t th
// __kernel void cn0(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states, uint Threads)
void xmrig::Cn0Kernel::setArgs(cl_mem input, cl_mem scratchpads, cl_mem states, uint32_t threads)
void xmrig::Cn0Kernel::setArgs(cl_mem input, int inlen, cl_mem scratchpads, cl_mem states, uint32_t threads)
{
setArg(0, sizeof(cl_mem), &input);
setArg(1, sizeof(cl_mem), &scratchpads);
setArg(2, sizeof(cl_mem), &states);
setArg(3, sizeof(uint32_t), &threads);
setArg(1, sizeof(int), &inlen);
setArg(2, sizeof(cl_mem), &scratchpads);
setArg(3, sizeof(cl_mem), &states);
setArg(4, sizeof(uint32_t), &threads);
}

View File

@@ -38,7 +38,7 @@ public:
inline Cn0Kernel(cl_program program) : OclKernel(program, "cn0") {}
void enqueue(cl_command_queue queue, uint32_t nonce, size_t threads);
void setArgs(cl_mem input, cl_mem scratchpads, cl_mem states, uint32_t threads);
void setArgs(cl_mem input, int inlen, cl_mem scratchpads, cl_mem states, uint32_t threads);
};

View File

@@ -1,3 +1,9 @@
if (BUILD_STATIC AND XMRIG_OS_UNIX AND WITH_OPENCL)
message(WARNING "OpenCL backend is not compatible with static build, use -DWITH_OPENCL=OFF to suppress this warning")
set(WITH_OPENCL OFF)
endif()
if (WITH_OPENCL)
add_definitions(/DCL_TARGET_OPENCL_VERSION=200)
add_definitions(/DCL_USE_DEPRECATED_OPENCL_1_2_APIS)

View File

@@ -122,10 +122,16 @@ void xmrig::OclCnRunner::set(const Job &job, uint8_t *blob)
throw std::length_error("job size too big");
}
blob[job.size()] = 0x01;
memset(blob + job.size() + 1, 0, Job::kMaxBlobSize - job.size() - 1);
const int inlen = static_cast<int>(job.size() + 136 - (job.size() % 136));
enqueueWriteBuffer(m_input, CL_TRUE, 0, Job::kMaxBlobSize, blob);
blob[job.size()] = 0x01;
memset(blob + job.size() + 1, 0, inlen - job.size() - 1);
blob[inlen - 1] |= 0x80;
enqueueWriteBuffer(m_input, CL_TRUE, 0, inlen, blob);
m_cn0->setArg(1, sizeof(int), &inlen);
if (m_algorithm == Algorithm::CN_R && m_height != job.height()) {
delete m_cn1;
@@ -152,7 +158,7 @@ void xmrig::OclCnRunner::build()
OclBaseRunner::build();
m_cn0 = new Cn0Kernel(m_program);
m_cn0->setArgs(m_input, m_scratchpads, m_states, m_intensity);
m_cn0->setArgs(m_input, 0, m_scratchpads, m_states, m_intensity);
m_cn2 = new Cn2Kernel(m_program);
m_cn2->setArgs(m_scratchpads, m_states, m_branches, m_intensity);

View File

@@ -69,8 +69,6 @@ OclKawPowRunner::~OclKawPowRunner()
delete m_calculateDagKernel;
OclLib::release(m_searchKernel);
OclLib::release(m_controlQueue);
OclLib::release(m_stop);
@@ -120,8 +118,7 @@ void OclKawPowRunner::run(uint32_t nonce, uint32_t *hashOutput)
void OclKawPowRunner::set(const Job &job, uint8_t *blob)
{
m_blockHeight = static_cast<uint32_t>(job.height());
m_searchProgram = OclKawPow::get(*this, m_blockHeight, m_workGroupSize);
m_searchKernel = OclLib::createKernel(m_searchProgram, "progpow_search");
m_searchKernel = OclKawPow::get(*this, m_blockHeight, m_workGroupSize);
const uint32_t epoch = m_blockHeight / KPHash::EPOCH_LENGTH;

View File

@@ -69,7 +69,6 @@ private:
KawPow_CalculateDAGKernel* m_calculateDagKernel = nullptr;
cl_program m_searchProgram = nullptr;
cl_kernel m_searchKernel = nullptr;
size_t m_workGroupSize = 256;

View File

@@ -54,8 +54,9 @@ namespace xmrig {
class KawPowCacheEntry
{
public:
inline KawPowCacheEntry(const Algorithm &algo, uint64_t period, uint32_t worksize, uint32_t index, cl_program program) :
inline KawPowCacheEntry(const Algorithm &algo, uint64_t period, uint32_t worksize, uint32_t index, cl_program program, cl_kernel kernel) :
program(program),
kernel(kernel),
m_algo(algo),
m_index(index),
m_period(period),
@@ -65,9 +66,10 @@ public:
inline bool isExpired(uint64_t period) const { return m_period + 1 < period; }
inline bool match(const Algorithm &algo, uint64_t period, uint32_t worksize, uint32_t index) const { return m_algo == algo && m_period == period && m_worksize == worksize && m_index == index; }
inline bool match(const IOclRunner &runner, uint64_t period, uint32_t worksize) const { return match(runner.algorithm(), period, worksize, runner.deviceIndex()); }
inline void release() { OclLib::release(program); }
inline void release() { OclLib::release(kernel); OclLib::release(program); }
cl_program program;
cl_kernel kernel;
private:
Algorithm m_algo;
@@ -82,16 +84,16 @@ class KawPowCache
public:
KawPowCache() = default;
inline cl_program search(const IOclRunner &runner, uint64_t period, uint32_t worksize) { return search(runner.algorithm(), period, worksize, runner.deviceIndex()); }
inline cl_kernel search(const IOclRunner &runner, uint64_t period, uint32_t worksize) { return search(runner.algorithm(), period, worksize, runner.deviceIndex()); }
inline cl_program search(const Algorithm &algo, uint64_t period, uint32_t worksize, uint32_t index)
inline cl_kernel search(const Algorithm &algo, uint64_t period, uint32_t worksize, uint32_t index)
{
std::lock_guard<std::mutex> lock(m_mutex);
for (const auto &entry : m_data) {
if (entry.match(algo, period, worksize, index)) {
return entry.program;
return entry.kernel;
}
}
@@ -99,9 +101,10 @@ public:
}
void add(const Algorithm &algo, uint64_t period, uint32_t worksize, uint32_t index, cl_program program)
void add(const Algorithm &algo, uint64_t period, uint32_t worksize, uint32_t index, cl_program program, cl_kernel kernel)
{
if (search(algo, period, worksize, index)) {
OclLib::release(kernel);
OclLib::release(program);
return;
}
@@ -109,7 +112,7 @@ public:
std::lock_guard<std::mutex> lock(m_mutex);
gc(period);
m_data.emplace_back(algo, period, worksize, index, program);
m_data.emplace_back(algo, period, worksize, index, program, kernel);
}
@@ -159,15 +162,15 @@ static KawPowCache cache;
class KawPowBuilder
{
public:
cl_program build(const IOclRunner &runner, uint64_t period, uint32_t worksize)
cl_kernel build(const IOclRunner &runner, uint64_t period, uint32_t worksize)
{
std::lock_guard<std::mutex> lock(m_mutex);
const uint64_t ts = Chrono::steadyMSecs();
cl_program program = cache.search(runner, period, worksize);
if (program) {
return program;
cl_kernel kernel = cache.search(runner, period, worksize);
if (kernel) {
return kernel;
}
cl_int ret;
@@ -175,7 +178,7 @@ public:
cl_device_id device = runner.data().device.id();
const char *s = source.c_str();
program = OclLib::createProgramWithSource(runner.ctx(), 1, &s, nullptr, &ret);
cl_program program = OclLib::createProgramWithSource(runner.ctx(), 1, &s, nullptr, &ret);
if (ret != CL_SUCCESS) {
return nullptr;
}
@@ -199,11 +202,17 @@ public:
return nullptr;
}
kernel = OclLib::createKernel(program, "progpow_search", &ret);
if (ret != CL_SUCCESS) {
OclLib::release(program);
return nullptr;
}
LOG_INFO("%s " YELLOW("KawPow") " program for period " WHITE_BOLD("%" PRIu64) " compiled " BLACK_BOLD("(%" PRIu64 "ms)"), Tags::opencl(), period, Chrono::steadyMSecs() - ts);
cache.add(runner.algorithm(), period, worksize, runner.deviceIndex(), program);
cache.add(runner.algorithm(), period, worksize, runner.deviceIndex(), program, kernel);
return program;
return kernel;
}
@@ -382,7 +391,7 @@ public:
static KawPowBuilder builder;
cl_program OclKawPow::get(const IOclRunner &runner, uint64_t height, uint32_t worksize)
cl_kernel OclKawPow::get(const IOclRunner &runner, uint64_t height, uint32_t worksize)
{
const uint64_t period = height / KPHash::PERIOD_LENGTH;
@@ -396,9 +405,9 @@ cl_program OclKawPow::get(const IOclRunner &runner, uint64_t height, uint32_t wo
[](uv_work_t *req, int) { delete static_cast<KawPowBaton*>(req->data); }
);
cl_program program = cache.search(runner, period, worksize);
if (program) {
return program;
cl_kernel kernel = cache.search(runner, period, worksize);
if (kernel) {
return kernel;
}
return builder.build(runner, period, worksize);

View File

@@ -30,7 +30,7 @@
#include <cstdint>
using cl_program = struct _cl_program *;
using cl_kernel = struct _cl_kernel *;
namespace xmrig {
@@ -42,7 +42,7 @@ class IOclRunner;
class OclKawPow
{
public:
static cl_program get(const IOclRunner &runner, uint64_t height, uint32_t worksize);
static cl_kernel get(const IOclRunner &runner, uint64_t height, uint32_t worksize);
static void clear();
};

View File

@@ -44,7 +44,7 @@
static uv_lib_t oclLib;
static const char *kErrorTemplate = MAGENTA_BG_BOLD(WHITE_BOLD_S " ocl ") RED(" error ") RED_BOLD("%s") RED(" when calling ") RED_BOLD("%s");
static const char *kErrorTemplate = MAGENTA_BG_BOLD(WHITE_BOLD_S " opencl ") RED(" error ") RED_BOLD("%s") RED(" when calling ") RED_BOLD("%s");
static const char *kBuildProgram = "clBuildProgram";
static const char *kCreateBuffer = "clCreateBuffer";

View File

@@ -127,6 +127,7 @@ elseif (APPLE)
)
else()
set(SOURCES_OS
src/base/io/Async.cpp
src/base/io/json/Json_unix.cpp
src/base/kernel/Platform_unix.cpp
)
@@ -222,3 +223,20 @@ if (WITH_KAWPOW)
src/base/net/stratum/EthStratumClient.cpp
)
endif()
if (WITH_PROFILING)
add_definitions(/DXMRIG_FEATURE_PROFILING)
list(APPEND HEADERS_BASE src/base/tools/Profiler.h)
list(APPEND SOURCES_BASE src/base/tools/Profiler.cpp)
endif()
if (WITH_RANDOMX AND WITH_BENCHMARK)
add_definitions(/DXMRIG_FEATURE_BENCHMARK)
list(APPEND HEADERS_BASE src/base/net/stratum/NullClient.h)
list(APPEND SOURCES_BASE src/base/net/stratum/NullClient.cpp)
else()
remove_definitions(/DXMRIG_FEATURE_BENCHMARK)
endif()

View File

@@ -105,8 +105,6 @@ static AlgoName const algorithm_names[] = {
{ "RandomX", "rx", Algorithm::RX_0 },
{ "randomx/wow", "rx/wow", Algorithm::RX_WOW },
{ "RandomWOW", nullptr, Algorithm::RX_WOW },
{ "randomx/loki", "rx/loki", Algorithm::RX_LOKI },
{ "RandomXL", nullptr, Algorithm::RX_LOKI },
{ "randomx/arq", "rx/arq", Algorithm::RX_ARQ },
{ "RandomARQ", nullptr, Algorithm::RX_ARQ },
{ "randomx/sfx", "rx/sfx", Algorithm::RX_SFX },
@@ -117,6 +115,8 @@ static AlgoName const algorithm_names[] = {
# ifdef XMRIG_ALGO_ARGON2
{ "argon2/chukwa", nullptr, Algorithm::AR2_CHUKWA },
{ "chukwa", nullptr, Algorithm::AR2_CHUKWA },
{ "argon2/chukwav2", nullptr, Algorithm::AR2_CHUKWA_V2 },
{ "chukwav2", nullptr, Algorithm::AR2_CHUKWA_V2 },
{ "argon2/wrkz", nullptr, Algorithm::AR2_WRKZ },
# endif
# ifdef XMRIG_ALGO_ASTROBWT
@@ -135,6 +135,12 @@ static AlgoName const algorithm_names[] = {
} /* namespace xmrig */
xmrig::Algorithm::Algorithm(const rapidjson::Value &value) :
m_id(parse(value.GetString()))
{
}
rapidjson::Value xmrig::Algorithm::toJSON() const
{
using namespace rapidjson;
@@ -143,12 +149,17 @@ rapidjson::Value xmrig::Algorithm::toJSON() const
}
rapidjson::Value xmrig::Algorithm::toJSON(rapidjson::Document &) const
{
return toJSON();
}
size_t xmrig::Algorithm::l2() const
{
# ifdef XMRIG_ALGO_RANDOMX
switch (m_id) {
case RX_0:
case RX_LOKI:
case RX_SFX:
return 0x40000;
@@ -196,7 +207,6 @@ size_t xmrig::Algorithm::l3() const
if (f == RANDOM_X) {
switch (m_id) {
case RX_0:
case RX_LOKI:
case RX_SFX:
return oneMiB * 2;
@@ -219,6 +229,9 @@ size_t xmrig::Algorithm::l3() const
case AR2_CHUKWA:
return oneMiB / 2;
case AR2_CHUKWA_V2:
return oneMiB;
case AR2_WRKZ:
return oneMiB / 4;
@@ -319,7 +332,6 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
# ifdef XMRIG_ALGO_RANDOMX
case RX_0:
case RX_WOW:
case RX_LOKI:
case RX_ARQ:
case RX_SFX:
case RX_KEVA:
@@ -328,6 +340,7 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
# ifdef XMRIG_ALGO_ARGON2
case AR2_CHUKWA:
case AR2_CHUKWA_V2:
case AR2_WRKZ:
return ARGON2;
# endif

View File

@@ -66,11 +66,11 @@ public:
CN_CCX, // "cn/ccx" Conceal (CCX)
RX_0, // "rx/0" RandomX (reference configuration).
RX_WOW, // "rx/wow" RandomWOW (Wownero).
RX_LOKI, // "rx/loki" RandomXL (Loki).
RX_ARQ, // "rx/arq" RandomARQ (Arqma).
RX_SFX, // "rx/sfx" RandomSFX (Safex Cash).
RX_KEVA, // "rx/keva" RandomKEVA (Keva).
AR2_CHUKWA, // "argon2/chukwa" Argon2id (Chukwa).
AR2_CHUKWA_V2, // "argon2/chukwav2" Argon2id (Chukwa v2).
AR2_WRKZ, // "argon2/wrkz" Argon2id (WRKZ)
ASTROBWT_DERO, // "astrobwt" AstroBWT (Dero)
KAWPOW_RVN, // "kawpow/rvn" KawPow (RVN)
@@ -92,10 +92,11 @@ public:
inline Algorithm() = default;
inline Algorithm(const char *algo) : m_id(parse(algo)) {}
inline Algorithm(Id id) : m_id(id) {}
Algorithm(const rapidjson::Value &value);
inline bool isCN() const { auto f = family(); return f == CN || f == CN_LITE || f == CN_HEAVY || f == CN_PICO; }
inline bool isEqual(const Algorithm &other) const { return m_id == other.m_id; }
inline bool isValid() const { return m_id != INVALID; }
inline bool isValid() const { return m_id != INVALID && family() != UNKNOWN; }
inline const char *name() const { return name(false); }
inline const char *shortName() const { return name(true); }
inline Family family() const { return family(m_id); }
@@ -108,6 +109,7 @@ public:
inline operator Algorithm::Id() const { return m_id; }
rapidjson::Value toJSON() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
size_t l2() const;
size_t l3() const;
uint32_t maxIntensity() const;

98
src/base/io/Async.cpp Normal file
View File

@@ -0,0 +1,98 @@
/* XMRig
* Copyright (c) 2015-2020 libuv project contributors.
* Copyright (c) 2020 cohcho <https://github.com/cohcho>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/io/Async.h"
#if defined(XMRIG_UV_PERFORMANCE_BUG)
#include <sys/eventfd.h>
#include <sys/poll.h>
#include <unistd.h>
#include <cstdlib>
namespace xmrig {
uv_async_t::~uv_async_t()
{
close(m_fd);
}
static void on_schedule(uv_poll_t *handle, int status, int events)
{
static uint64_t val;
uv_async_t *async = reinterpret_cast<uv_async_t *>(handle);
for (;;) {
int r = read(async->m_fd, &val, sizeof(val));
if (r == sizeof(val))
continue;
if (r != -1)
break;
if (errno == EAGAIN || errno == EWOULDBLOCK)
break;
if (errno == EINTR)
continue;
abort();
}
if (async->m_cb) {
(*async->m_cb)(async);
}
}
int uv_async_init(uv_loop_t *loop, uv_async_t *async, uv_async_cb cb)
{
int fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (fd < 0) {
return uv_translate_sys_error(errno);
}
uv_poll_init(loop, (uv_poll_t *)async, fd);
uv_poll_start((uv_poll_t *)async, POLLIN, on_schedule);
async->m_cb = cb;
async->m_fd = fd;
return 0;
}
int uv_async_send(uv_async_t *async)
{
static const uint64_t val = 1;
int r;
do {
r = write(async->m_fd, &val, sizeof(val));
}
while (r == -1 && errno == EINTR);
if (r == sizeof(val) || (r == 1 && (errno == EAGAIN || errno == EWOULDBLOCK))) {
return 0;
}
abort();
}
} // namespace xmrig
#endif

52
src/base/io/Async.h Normal file
View File

@@ -0,0 +1,52 @@
/* XMRig
* Copyright (c) 2015-2020 libuv project contributors.
* Copyright (c) 2020 cohcho <https://github.com/cohcho>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASYNC_H
#define XMRIG_ASYNC_H
#include <uv.h>
// since 2019.05.16, Version 1.29.0 (Stable)
#if (UV_VERSION_MAJOR >= 1) && (UV_VERSION_MINOR >= 29) && defined(__linux__)
#define XMRIG_UV_PERFORMANCE_BUG
namespace xmrig {
struct uv_async_t: uv_poll_t
{
typedef void (*uv_async_cb)(uv_async_t* handle);
~uv_async_t();
int m_fd = -1;
uv_async_cb m_cb = nullptr;
};
using uv_async_cb = uv_async_t::uv_async_cb;
extern int uv_async_init(uv_loop_t *loop, uv_async_t *async, uv_async_cb cb);
extern int uv_async_send(uv_async_t *async);
} // namespace xmrig
#endif
#endif /* XMRIG_ASYNC_H */

View File

@@ -36,9 +36,7 @@ static const rapidjson::Value kNullValue;
}
xmrig::JsonChain::JsonChain()
{
}
xmrig::JsonChain::JsonChain() = default;
bool xmrig::JsonChain::add(rapidjson::Document &&doc)
@@ -66,8 +64,10 @@ bool xmrig::JsonChain::addFile(const char *fileName)
if (doc.HasParseError()) {
const size_t offset = doc.GetErrorOffset();
size_t line, pos;
size_t line;
size_t pos;
std::vector<std::string> s;
if (Json::convertOffset(fileName, offset, line, pos, s)) {
for (const auto& t : s) {
LOG_ERR("%s", t.c_str());

View File

@@ -81,7 +81,13 @@ private:
#define CLEAR CSI "0m" // all attributes off
#define BRIGHT_BLACK_S CSI "0;90m" // somewhat MD.GRAY
#define BLACK_S CSI "0;30m"
#define BLACK_BOLD_S CSI "1;30m" // another name for GRAY
#ifdef XMRIG_OS_APPLE
# define BLACK_BOLD_S CSI "0;37m"
#else
# define BLACK_BOLD_S CSI "1;30m" // another name for GRAY
#endif
#define RED_S CSI "0;31m"
#define RED_BOLD_S CSI "1;31m"
#define GREEN_S CSI "0;32m"
@@ -97,6 +103,7 @@ private:
#define WHITE_S CSI "0;37m" // another name for LT.GRAY
#define WHITE_BOLD_S CSI "1;37m" // actually white
#define RED_BG_BOLD_S CSI "41;1m"
#define GREEN_BG_BOLD_S CSI "42;1m"
#define YELLOW_BG_BOLD_S CSI "43;1m"
#define BLUE_BG_S CSI "44m"
@@ -124,6 +131,7 @@ private:
#define WHITE(x) WHITE_S x CLEAR
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
#define RED_BG_BOLD(x) RED_BG_BOLD_S x CLEAR
#define GREEN_BG_BOLD(x) GREEN_BG_BOLD_S x CLEAR
#define YELLOW_BG_BOLD(x) YELLOW_BG_BOLD_S x CLEAR
#define BLUE_BG(x) BLUE_BG_S x CLEAR

View File

@@ -70,6 +70,26 @@ const char *xmrig::Tags::randomx()
return tag;
}
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
const char *xmrig::Tags::bench()
{
static const char *tag = GREEN_BG_BOLD(WHITE_BOLD_S " bench ");
return tag;
}
#endif
#endif
#ifdef XMRIG_PROXY_PROJECT
const char *xmrig::Tags::proxy()
{
static const char *tag = MAGENTA_BG_BOLD(WHITE_BOLD_S " proxy ");
return tag;
}
#endif
@@ -91,3 +111,13 @@ const char *xmrig::Tags::opencl()
return tag;
}
#endif
#ifdef XMRIG_FEATURE_PROFILING
const char* xmrig::Tags::profiler()
{
static const char* tag = CYAN_BG_BOLD(WHITE_BOLD_S " profile ");
return tag;
}
#endif

View File

@@ -40,6 +40,13 @@ public:
# ifdef XMRIG_ALGO_RANDOMX
static const char *randomx();
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
static const char *bench();
# endif
# endif
# ifdef XMRIG_PROXY_PROJECT
static const char *proxy();
# endif
# ifdef XMRIG_FEATURE_CUDA
@@ -49,6 +56,10 @@ public:
# ifdef XMRIG_FEATURE_OPENCL
static const char *opencl();
# endif
# ifdef XMRIG_FEATURE_PROFILING
static const char* profiler();
# endif
};

View File

@@ -84,7 +84,7 @@ static int showVersion()
# if defined(LIBRESSL_VERSION_TEXT)
printf("LibreSSL/%s\n", LIBRESSL_VERSION_TEXT + 9);
# elif defined(OPENSSL_VERSION_TEXT)
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
constexpr const char *v = &OPENSSL_VERSION_TEXT[8];
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);
# endif
}

View File

@@ -54,6 +54,8 @@ public:
static inline const char *userAgent() { return m_userAgent; }
static bool isOnBatteryPower();
private:
static char *createUserAgent();

View File

@@ -22,6 +22,8 @@
*/
#include <IOKit/IOKitLib.h>
#include <IOKit/ps/IOPowerSources.h>
#include <mach/thread_act.h>
#include <mach/thread_policy.h>
#include <stdio.h>
@@ -29,6 +31,7 @@
#include <sys/resource.h>
#include <uv.h>
#include <thread>
#include <fstream>
#include "base/kernel/Platform.h"
@@ -107,3 +110,8 @@ void xmrig::Platform::setThreadPriority(int priority)
setpriority(PRIO_PROCESS, 0, prio);
}
bool xmrig::Platform::isOnBatteryPower()
{
return IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited;
}

View File

@@ -38,6 +38,7 @@
#include <unistd.h>
#include <uv.h>
#include <thread>
#include <fstream>
#include "base/kernel/Platform.h"
@@ -146,3 +147,19 @@ void xmrig::Platform::setThreadPriority(int priority)
}
# endif
}
bool xmrig::Platform::isOnBatteryPower()
{
for (int i = 0; i <= 1; ++i) {
char buf[64];
snprintf(buf, 64, "/sys/class/power_supply/BAT%d/status", i);
std::ifstream f(buf);
if (f.is_open()) {
std::string status;
f >> status;
return (status == "Discharging");
}
}
return false;
}

View File

@@ -157,3 +157,12 @@ void xmrig::Platform::setThreadPriority(int priority)
SetThreadPriority(GetCurrentThread(), prio);
}
bool xmrig::Platform::isOnBatteryPower()
{
SYSTEM_POWER_STATUS st;
if (GetSystemPowerStatus(&st)) {
return (st.ACLineStatus == 0);
}
return false;
}

View File

@@ -61,6 +61,7 @@ const char *BaseConfig::kColors = "colors";
const char *BaseConfig::kDryRun = "dry-run";
const char *BaseConfig::kHttp = "http";
const char *BaseConfig::kLogFile = "log-file";
const char *BaseConfig::kPauseOnBattery = "pause-on-battery";
const char *BaseConfig::kPrintTime = "print-time";
const char *BaseConfig::kSyslog = "syslog";
const char *BaseConfig::kTitle = "title";
@@ -85,15 +86,16 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
return false;
}
m_autoSave = reader.getBool(kAutosave, m_autoSave);
m_background = reader.getBool(kBackground, m_background);
m_dryRun = reader.getBool(kDryRun, m_dryRun);
m_syslog = reader.getBool(kSyslog, m_syslog);
m_watch = reader.getBool(kWatch, m_watch);
m_logFile = reader.getString(kLogFile);
m_userAgent = reader.getString(kUserAgent);
m_printTime = std::min(reader.getUint(kPrintTime, m_printTime), 3600U);
m_title = reader.getValue(kTitle);
m_autoSave = reader.getBool(kAutosave, m_autoSave);
m_background = reader.getBool(kBackground, m_background);
m_dryRun = reader.getBool(kDryRun, m_dryRun);
m_syslog = reader.getBool(kSyslog, m_syslog);
m_watch = reader.getBool(kWatch, m_watch);
m_pauseOnBattery = reader.getBool(kPauseOnBattery, m_pauseOnBattery);
m_logFile = reader.getString(kLogFile);
m_userAgent = reader.getString(kUserAgent);
m_printTime = std::min(reader.getUint(kPrintTime, m_printTime), 3600U);
m_title = reader.getValue(kTitle);
# ifdef XMRIG_FEATURE_TLS
m_tls = reader.getValue(kTls);
@@ -155,7 +157,7 @@ void xmrig::BaseConfig::printVersions()
snprintf(buf, sizeof buf, "LibreSSL/%s ", LIBRESSL_VERSION_TEXT + 9);
libs += buf;
# elif defined(OPENSSL_VERSION_TEXT)
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
constexpr const char *v = &OPENSSL_VERSION_TEXT[8];
snprintf(buf, sizeof buf, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
libs += buf;
# endif

View File

@@ -55,6 +55,7 @@ public:
static const char *kDryRun;
static const char *kHttp;
static const char *kLogFile;
static const char *kPauseOnBattery;
static const char *kPrintTime;
static const char *kSyslog;
static const char *kTitle;
@@ -71,6 +72,7 @@ public:
inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; }
inline bool isDryRun() const { return m_dryRun; }
inline bool isPauseOnBattery() const { return m_pauseOnBattery; }
inline bool isSyslog() const { return m_syslog; }
inline const char *logFile() const { return m_logFile.data(); }
inline const char *userAgent() const { return m_userAgent.data(); }
@@ -95,12 +97,13 @@ public:
void printVersions();
protected:
bool m_autoSave = true;
bool m_background = false;
bool m_dryRun = false;
bool m_syslog = false;
bool m_upgrade = false;
bool m_watch = true;
bool m_autoSave = true;
bool m_background = false;
bool m_dryRun = false;
bool m_pauseOnBattery = false;
bool m_syslog = false;
bool m_upgrade = false;
bool m_watch = true;
Http m_http;
Pools m_pools;
String m_apiId;

View File

@@ -151,7 +151,9 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
}
break;
case IConfig::UrlKey: /* --url */
case IConfig::UrlKey: /* --url */
case IConfig::StressKey: /* --stress */
case IConfig::BenchKey: /* --bench */
{
if (!doc.HasMember(Pools::kPools)) {
doc.AddMember(rapidjson::StringRef(Pools::kPools), rapidjson::kArrayType, doc.GetAllocator());
@@ -162,7 +164,20 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
array.PushBack(rapidjson::kObjectType, doc.GetAllocator());
}
set(doc, array[array.Size() - 1], Pool::kUrl, arg);
# ifdef XMRIG_FEATURE_BENCHMARK
if (key != IConfig::UrlKey) {
set(doc, array[array.Size() - 1], Pool::kUrl, (key == IConfig::BenchKey) ? "benchmark" :
# ifdef XMRIG_FEATURE_TLS
"stratum+ssl://randomx.xmrig.com:443"
# else
"randomx.xmrig.com:3333"
# endif
);
} else
# endif
{
set(doc, array[array.Size() - 1], Pool::kUrl, arg);
}
break;
}
@@ -247,6 +262,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::HttpEnabledKey: /* --http-enabled */
case IConfig::DaemonKey: /* --daemon */
case IConfig::VerboseKey: /* --verbose */
case IConfig::PauseOnBatteryKey: /* --pause-on-battery */
return transformBoolean(doc, key, true);
case IConfig::ColorKey: /* --no-color */
@@ -305,6 +321,9 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
case IConfig::NoTitleKey: /* --no-title */
return set(doc, BaseConfig::kTitle, enable);
case IConfig::PauseOnBatteryKey: /* --pause-on-battery */
return set(doc, BaseConfig::kPauseOnBattery, enable);
default:
break;
}

View File

@@ -76,6 +76,9 @@ public:
DataDirKey = 1035,
TitleKey = 1037,
NoTitleKey = 1038,
PauseOnBatteryKey = 1041,
StressKey = 1042,
BenchKey = 1043,
// xmrig common
CPUPriorityKey = 1021,
@@ -101,6 +104,8 @@ public:
YieldKey = 1030,
AstroBWTMaxSizeKey = 1034,
AstroBWTAVX2Key = 1036,
Argon2ImplKey = 1039,
RandomXCacheQoSKey = 1040,
// xmrig amd
OclPlatformKey = 1400,

View File

@@ -126,6 +126,10 @@ bool xmrig::HttpContext::isRequest() const
size_t xmrig::HttpContext::parse(const char *data, size_t size)
{
if (size == 0) {
return size;
}
return http_parser_execute(m_parser, &http_settings, data, size);
}

View File

@@ -29,13 +29,20 @@ namespace xmrig {
class HttpListener : public IHttpListener
{
public:
inline HttpListener(IHttpListener *listener, const char *tag = nullptr) : m_tag(tag), m_listener(listener) {}
inline HttpListener(IHttpListener *listener, const char *tag = nullptr) :
# ifdef APP_DEBUG
m_tag(tag),
# endif
m_listener(listener)
{}
protected:
void onHttpData(const HttpData &data) override;
private:
# ifdef APP_DEBUG
const char *m_tag;
# endif
IHttpListener *m_listener;
};

View File

@@ -6,9 +6,9 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2019 Howard Chu <https://github.com/hyc>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -45,7 +45,9 @@ class Job
public:
// Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
// SECOR increase requirements for blob size: https://github.com/xmrig/xmrig/issues/913
static constexpr const size_t kMaxBlobSize = 128;
// Haven (XHV) offshore increases requirements by adding pricing_record struct (192 bytes) to block_header.
// Round it up to 408 (136*3) for a convenient keccak calculation in OpenCL
static constexpr const size_t kMaxBlobSize = 408;
static constexpr const size_t kMaxSeedSize = 32;
Job() = default;
@@ -63,7 +65,7 @@ public:
void setDiff(uint64_t diff);
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
inline bool isValid() const { return (m_size > 0 && m_diff > 0) || !m_poolWallet.isEmpty(); }
inline bool setId(const char *id) { return m_id = id; }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const Buffer &seed() const { return m_seed; }
@@ -80,6 +82,7 @@ public:
inline uint32_t backend() const { return m_backend; }
inline uint64_t diff() const { return m_diff; }
inline uint64_t height() const { return m_height; }
inline uint64_t nonceMask() const { return isNicehash() ? 0xFFFFFFULL : (nonceSize() == sizeof(uint64_t) ? (-1ull >> (extraNonce().size() * 4)): 0xFFFFFFFFULL); }
inline uint64_t target() const { return m_target; }
inline uint8_t *blob() { return m_blob; }
inline uint8_t fixedByte() const { return *(m_blob + 42); }

View File

@@ -0,0 +1,62 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/net/stratum/NullClient.h"
#include "3rdparty/rapidjson/document.h"
#include "base/kernel/interfaces/IClientListener.h"
xmrig::NullClient::NullClient(IClientListener* listener) :
m_listener(listener)
{
m_job.setAlgorithm(Algorithm::RX_0);
std::vector<char> blob(112 * 2 + 1, '0');
blob.back() = '\0';
m_job.setBlob(blob.data());
blob[Job::kMaxSeedSize * 2] = '\0';
m_job.setSeedHash(blob.data());
m_job.setDiff(uint64_t(-1));
m_job.setHeight(1);
m_job.setId("00000000");
}
void xmrig::NullClient::connect()
{
m_listener->onLoginSuccess(this);
rapidjson::Value params;
m_listener->onJobReceived(this, m_job, params);
}
void xmrig::NullClient::setPool(const Pool& pool)
{
m_pool = pool;
if (!m_pool.algorithm().isValid()) {
m_pool.setAlgo(Algorithm::RX_0);
}
m_job.setAlgorithm(m_pool.algorithm().id());
}

View File

@@ -0,0 +1,77 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_NULLCLIENT_H
#define XMRIG_NULLCLIENT_H
#include "base/net/stratum/Client.h"
namespace xmrig {
class NullClient : public IClient
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(NullClient)
NullClient(IClientListener* listener);
~NullClient() override = default;
inline bool disconnect() override { return true; }
inline bool hasExtension(Extension extension) const noexcept override { return false; }
inline bool isEnabled() const override { return true; }
inline bool isTLS() const override { return false; }
inline const char *mode() const override { return "benchmark"; }
inline const char *tag() const override { return "null"; }
inline const char *tlsFingerprint() const override { return nullptr; }
inline const char *tlsVersion() const override { return nullptr; }
inline const Job &job() const override { return m_job; }
inline const Pool &pool() const override { return m_pool; }
inline const String &ip() const override { return m_ip; }
inline int id() const override { return 0; }
inline int64_t send(const rapidjson::Value& obj, Callback callback) override { return 0; }
inline int64_t send(const rapidjson::Value& obj) override { return 0; }
inline int64_t sequence() const override { return 0; }
inline int64_t submit(const JobResult& result) override { return 0; }
inline void connect(const Pool& pool) override { setPool(pool); }
inline void deleteLater() override {}
inline void setAlgo(const Algorithm& algo) override {}
inline void setEnabled(bool enabled) override {}
inline void setProxy(const ProxyUrl& proxy) override {}
inline void setQuiet(bool quiet) override {}
inline void setRetries(int retries) override {}
inline void setRetryPause(uint64_t ms) override {}
inline void tick(uint64_t now) override {}
void connect() override;
void setPool(const Pool& pool) override;
private:
IClientListener* m_listener;
Job m_job;
Pool m_pool;
String m_ip;
};
} /* namespace xmrig */
#endif /* XMRIG_NULLCLIENT_H */

View File

@@ -50,6 +50,16 @@
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
# include "base/net/stratum/NullClient.h"
#endif
#ifdef _MSC_VER
# define strcasecmp _stricmp
#endif
namespace xmrig {
@@ -72,9 +82,11 @@ const char *Pool::kSOCKS5 = "socks5";
const char *Pool::kTls = "tls";
const char *Pool::kUrl = "url";
const char *Pool::kUser = "user";
const char *Pool::kNicehashHost = "nicehash.com";
const char *Pool::kNicehashHost = "nicehash.com";
#ifdef XMRIG_FEATURE_BENCHMARK
const char *Pool::kBenchmark = "benchmark";
#endif
}
@@ -125,20 +137,22 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash) || m_url.host().contains(kNicehashHost));
m_flags.set(FLAG_TLS, Json::getBool(object, kTls) || m_url.isTLS());
setKeepAlive(Json::getValue(object, kKeepalive));
# ifdef XMRIG_FEATURE_BENCHMARK
if (setBenchSize(Json::getString(object, kBenchmark, nullptr))) {
m_mode = MODE_BENCHMARK;
return;
}
# endif
if (m_daemon.isValid()) {
m_mode = MODE_SELF_SELECT;
}
else if (Json::getBool(object, kDaemon)) {
m_mode = MODE_DAEMON;
}
const rapidjson::Value &keepalive = Json::getValue(object, kKeepalive);
if (keepalive.IsInt()) {
setKeepAlive(keepalive.GetInt());
}
else if (keepalive.IsBool()) {
setKeepAlive(keepalive.GetBool());
}
}
@@ -217,6 +231,11 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
client = new AutoClient(id, Platform::userAgent(), listener);
}
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
else if (m_mode == MODE_BENCHMARK) {
client = new NullClient(listener);
}
# endif
assert(client != nullptr);
@@ -307,3 +326,34 @@ void xmrig::Pool::print() const
LOG_DEBUG ("keepAlive: %d", m_keepAlive);
}
#endif
void xmrig::Pool::setKeepAlive(const rapidjson::Value &value)
{
if (value.IsInt()) {
setKeepAlive(value.GetInt());
}
else if (value.IsBool()) {
setKeepAlive(value.GetBool());
}
}
#ifdef XMRIG_FEATURE_BENCHMARK
bool xmrig::Pool::setBenchSize(const char *benchmark)
{
if (!benchmark) {
return false;
}
const auto size = strtoul(benchmark, nullptr, 10);
if (size < 1 || size > 10) {
return false;
}
const std::string s = std::to_string(size) + "M";
m_benchSize = strcasecmp(benchmark, s.c_str()) == 0 ? size * 1000000 : 0;
return m_benchSize > 0;
}
#endif

Some files were not shown because too many files have changed in this diff Show More