1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-12 01:42:48 -05:00

Compare commits

...

81 Commits

Author SHA1 Message Date
XMRig
467e5115b0 v4.2.0-beta 2019-09-28 23:55:49 +07:00
XMRig
c495802f64 Merge branch 'evo' into beta 2019-09-28 23:34:12 +07:00
XMRig
66e48ed2d7 Fixed ARM build. 2019-09-28 23:26:03 +07:00
XMRig
ac4cd3eb9b v4.2.0 2019-09-28 23:10:07 +07:00
XMRig
5d73402651 Merge branch 'evo' into beta 2019-09-28 23:09:20 +07:00
xmrig
166d8dd53c Update CHANGELOG.md 2019-09-28 22:45:25 +07:00
XMRig
680081b93b #1202 Fixed algorithm verification in donate strategy. 2019-09-28 22:07:44 +07:00
XMRig
e66eeefb14 Fixed build on macOS. 2019-09-28 18:20:56 +07:00
XMRig
4453727754 Merge branch 'dev' into evo 2019-09-28 03:25:59 +07:00
XMRig
d086318f4e Set "rx/0" as user visible RandomX name. 2019-09-28 03:25:03 +07:00
XMRig
5b7f1fe853 Updated default config example. 2019-09-28 02:34:10 +07:00
xmrig
4c357d2d60 Update CHANGELOG.md 2019-09-28 02:32:02 +07:00
xmrig
0eb5588454 Update CPU.md 2019-09-28 02:25:34 +07:00
xmrig
5ba8b43fb8 Update CPU.md 2019-09-28 02:25:00 +07:00
xmrig
0eb754d76e Create CPU_MAX_USAGE.md 2019-09-28 02:22:38 +07:00
XMRig
7c463849cc Added config option "cpu/max-threads-hint" and command line option "--cpu-max-threads-hint". 2019-09-28 02:02:20 +07:00
XMRig
daed23422e Merge branch 'dev' into evo 2019-09-27 23:40:36 +07:00
XMRig
550e332909 Fixed coin option in daemon mode. 2019-09-27 23:39:57 +07:00
XMRig
43f26dcd76 Merge branch 'dev' into evo 2019-09-27 05:54:33 +07:00
XMRig
e1d1a5226c Added coin option. 2019-09-27 05:41:45 +07:00
XMRig
82aaa89ab6 v4.2.0-evo 2019-09-27 02:56:22 +07:00
XMRig
aac384f54f Merge remote-tracking branch 'remotes/origin/beta' into evo 2019-09-27 02:55:57 +07:00
XMRig
ffccaa8817 v4.1.0-beta 2019-09-27 02:14:32 +07:00
XMRig
bd488a6182 Merge branch 'evo' into beta 2019-09-27 02:14:06 +07:00
XMRig
41ec1b4cb2 Fixed build with gcc 4.8. 2019-09-27 01:55:05 +07:00
XMRig
18bf9d3d95 Reduced PciTopology class size. 2019-09-27 01:03:37 +07:00
XMRig
56e070b3d1 v4.1.0-evo 2019-09-26 23:41:11 +07:00
xmrig
88a9f8d892 Update CHANGELOG.md 2019-09-26 23:40:01 +07:00
XMRig
0f367ab117 Added "restricted" field to "GET /1/summary" request. 2019-09-26 17:29:24 +07:00
XMRig
838f078fa5 Advanced opencl options postponed. 2019-09-26 01:53:16 +07:00
XMRig
d6f0555771 Added command line option --opencl-devices (hint mode) 2019-09-24 23:01:03 +07:00
XMRig
3ee3d13f0f Merge branch 'evo' of github.com:xmrig/xmrig into evo 2019-09-24 18:40:10 +07:00
XMRig
6267ecc3dc Implemented --opencl-no-cache, --opencl-loader, --opencl-platform command line options. 2019-09-24 18:39:43 +07:00
xmrig
1487a037ed Merge pull request #1191 from SChernykh/evo
Workaround for a bug in binutils-2.32-1 on ARM
2019-09-24 15:24:08 +07:00
SChernykh
1bba25e080 Set scratchpad pointer to null by default
To avoid freeing random blocks of memory in some cases.
2019-09-24 08:53:00 +02:00
SChernykh
c6096c3c34 Workaround for a bug in binutils-2.32-1 on ARM
ldr/madd instruction sequence makes compiled binary crash, so separate them.
2019-09-23 23:12:40 +02:00
XMRig
2604705bab Added command line option --opencl. 2019-09-24 03:14:35 +07:00
XMRig
5f948d0d96 Fixed potential truncation. 2019-09-24 00:03:50 +07:00
XMRig
3e42fa28df OpenCL backend disabled by default. 2019-09-23 05:51:46 +07:00
XMRig
d9dc6a396f Add support for initialize OpenCL in runtime. 2019-09-23 05:33:48 +07:00
XMRig
bdb72684b0 Added command line option --no-cpu 2019-09-23 05:08:59 +07:00
XMRig
0f05936e63 Removed option --http-enabled. 2019-09-23 04:53:33 +07:00
xmrig
290493e485 Update CHANGELOG.md 2019-09-23 03:57:33 +07:00
XMRig
637301d340 Improved/restructured --help output. 2019-09-23 03:47:40 +07:00
XMRig
c7e4815d79 Use more JS friendly names. 2019-09-23 01:27:05 +07:00
XMRig
54d73b7ac5 Extended OpenCL threads information. 2019-09-22 02:10:14 +07:00
XMRig
cbdf1e6c09 Revert instructions_portable.cpp to avoid warning on gcc compilers. 2019-09-22 00:59:53 +07:00
XMRig
2e49930b94 Optimized initialization. 2019-09-21 19:26:27 +07:00
XMRig
9da0cb2ad1 Merge branch 'dev' into evo 2019-09-21 19:08:10 +07:00
XMRig
cf6bd0e772 #1183 Fixed crash in background mode. 2019-09-21 19:05:52 +07:00
xmrig
dc686bd1bf Merge pull request #1185 from SChernykh/evo
Added JIT compiler for RandomX on ARMv8
2019-09-21 16:36:12 +07:00
SChernykh
e002dbf57e Update CMakeLists.txt 2019-09-21 10:48:14 +02:00
SChernykh
38f4f4f695 Added JIT compiler for RandomX on ARMv8 2019-09-21 10:10:52 +02:00
XMRig
a4bc548fe5 Merge branch 'dev' into evo 2019-09-21 03:24:34 +07:00
XMRig
e57798360f #1183 Disable stdin handler if not available. 2019-09-21 03:22:19 +07:00
XMRig
6e45ab599e v4.0.2-evo 2019-09-20 16:46:56 +07:00
XMRig
e55fb68a29 Merge branch 'beta' into evo 2019-09-20 16:46:06 +07:00
XMRig
7a1ff6bfed v3.1.4-dev 2019-09-20 16:45:17 +07:00
XMRig
18809ddf0b Merge branch 'master' into dev 2019-09-20 16:44:51 +07:00
XMRig
7158514d48 v4.0.1-beta 2019-09-20 15:48:23 +07:00
XMRig
3445f47482 Merge branch 'evo' into beta 2019-09-20 15:44:21 +07:00
XMRig
5b33443607 Updated default config example. 2019-09-20 15:09:24 +07:00
XMRig
05b2c66aaf v3.1.3 2019-09-20 15:02:20 +07:00
XMRig
50038516cb Merge branch 'dev' 2019-09-20 15:01:59 +07:00
XMRig
f6752310b4 Backport fixes from v4. 2019-09-20 14:54:18 +07:00
xmrig
e5c75fa2f7 Update CHANGELOG.md 2019-09-20 14:30:38 +07:00
XMRig
40e8bfe443 Added global backends hashrate to "GET /2/backends" endpoint. 2019-09-20 14:15:35 +07:00
XMRig
ed11c0a6da Fixed config file permissions after write (MSYS only). 2019-09-20 02:54:33 +07:00
XMRig
365667ee0a #1180 Fixed race condition in nonce reset. 2019-09-20 00:30:20 +07:00
XMRig
1cfd5f0735 [opencl] Better cn/r specific resource management. 2019-09-19 03:42:11 +07:00
XMRig
e8ee091e5a Fixes for Intel OpenCL platform. 2019-09-19 02:05:42 +07:00
XMRig
133cd30b2e #1177 Fixed unroll syntax for old drivers. 2019-09-18 23:46:51 +07:00
XMRig
e3fcb99d84 Allow partially started threads. 2019-09-17 02:22:59 +07:00
XMRig
e8acb8a2a9 Simplify code. 2019-09-16 23:53:39 +07:00
XMRig
2a107cc463 Improved thread self test error message. 2019-09-16 01:27:51 +07:00
XMRig
1cd1f13fee v3.1.3-dev 2019-09-16 00:29:46 +07:00
XMRig
7af3e4e340 Merge branch 'master' into dev 2019-09-16 00:29:18 +07:00
XMRig
d8b07570a3 v4.0.1-evo 2019-09-16 00:28:40 +07:00
XMRig
95c960574a Merge branch 'beta' into evo 2019-09-16 00:27:57 +07:00
XMRig
171762d1aa v3.1.2 2019-09-15 18:04:18 +07:00
XMRig
78fd2fd0ac Merge branch 'dev' 2019-09-15 18:01:30 +07:00
118 changed files with 6522 additions and 3347 deletions

View File

@@ -1,8 +1,32 @@
# v4.2.0-beta
- [#1202](https://github.com/xmrig/xmrig/issues/1202) Fixed algorithm verification in donate strategy.
- Added per pool option `coin` with single possible value `monero` for pools without algorithm negotiation, for upcoming Monero fork.
- Added config option `cpu/max-threads-hint` and command line option `--cpu-max-threads-hint`.
# v4.1.0-beta
- **OpenCL backend disabled by default.**.
- [#1183](https://github.com/xmrig/xmrig/issues/1183) Fixed compatibility with systemd.
- [#1185](https://github.com/xmrig/xmrig/pull/1185) Added JIT compiler for RandomX on ARMv8.
- Improved API endpoint `GET /2/backends` and added support for this endpoint to [workers.xmrig.info](http://workers.xmrig.info).
- Added command line option `--no-cpu` to disable CPU backend.
- Added OpenCL specific command line options: `--opencl`, `--opencl-devices`, `--opencl-platform`, `--opencl-loader` and `--opencl-no-cache`.
- Removed command line option `--http-enabled`, HTTP API enabled automatically if any other `--http-*` option provided.
# v4.0.1-beta
- [#1177](https://github.com/xmrig/xmrig/issues/1177) Fixed compatibility with old AMD drivers.
- [#1180](https://github.com/xmrig/xmrig/issues/1180) Fixed possible duplicated shares after algorithm switching.
- Added support for case if not all backend threads successfully started.
- Fixed wrong config file permissions after write (only gcc builds on recent Windows 10 affected).
# v4.0.0-beta # v4.0.0-beta
- [#1172](https://github.com/xmrig/xmrig/issues/1172) **Added OpenCL mining backend.** - [#1172](https://github.com/xmrig/xmrig/issues/1172) **Added OpenCL mining backend.**
- [#268](https://github.com/xmrig/xmrig-amd/pull/268) [#270](https://github.com/xmrig/xmrig-amd/pull/270) [#271](https://github.com/xmrig/xmrig-amd/pull/271) [#273](https://github.com/xmrig/xmrig-amd/pull/273) [#274](https://github.com/xmrig/xmrig-amd/pull/274) [#1171](https://github.com/xmrig/xmrig/pull/1171) Added RandomX support for OpenCL, thanks [@SChernykh](https://github.com/SChernykh). - [#268](https://github.com/xmrig/xmrig-amd/pull/268) [#270](https://github.com/xmrig/xmrig-amd/pull/270) [#271](https://github.com/xmrig/xmrig-amd/pull/271) [#273](https://github.com/xmrig/xmrig-amd/pull/273) [#274](https://github.com/xmrig/xmrig-amd/pull/274) [#1171](https://github.com/xmrig/xmrig/pull/1171) Added RandomX support for OpenCL, thanks [@SChernykh](https://github.com/SChernykh).
- Algorithm `cn/wow` removed, as no longer alive. - Algorithm `cn/wow` removed, as no longer alive.
# v3.1.3
- [#1180](https://github.com/xmrig/xmrig/issues/1180) Fixed possible duplicated shares after algorithm switching.
- Fixed wrong config file permissions after write (only gcc builds on recent Windows 10 affected).
# v3.1.2 # v3.1.2
- Many RandomX optimizations and fixes. - Many RandomX optimizations and fixes.
- [#1132](https://github.com/xmrig/xmrig/issues/1132) Fixed build on CentOS 7. - [#1132](https://github.com/xmrig/xmrig/issues/1132) Fixed build on CentOS 7.

View File

@@ -71,6 +71,7 @@ set(HEADERS_CRYPTO
src/crypto/cn/skein_port.h src/crypto/cn/skein_port.h
src/crypto/cn/soft_aes.h src/crypto/cn/soft_aes.h
src/crypto/common/Algorithm.h src/crypto/common/Algorithm.h
src/crypto/common/Coin.h
src/crypto/common/keccak.h src/crypto/common/keccak.h
src/crypto/common/Nonce.h src/crypto/common/Nonce.h
src/crypto/common/portable/mm_malloc.h src/crypto/common/portable/mm_malloc.h
@@ -108,6 +109,7 @@ set(SOURCES_CRYPTO
src/crypto/cn/CnCtx.cpp src/crypto/cn/CnCtx.cpp
src/crypto/cn/CnHash.cpp src/crypto/cn/CnHash.cpp
src/crypto/common/Algorithm.cpp src/crypto/common/Algorithm.cpp
src/crypto/common/Coin.cpp
src/crypto/common/keccak.cpp src/crypto/common/keccak.cpp
src/crypto/common/Nonce.cpp src/crypto/common/Nonce.cpp
src/crypto/common/VirtualMemory.cpp src/crypto/common/VirtualMemory.cpp
@@ -143,7 +145,7 @@ else()
endif() endif()
endif() endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux") if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android")
EXECUTE_PROCESS(COMMAND uname -o COMMAND tr -d '\n' OUTPUT_VARIABLE OPERATING_SYSTEM) EXECUTE_PROCESS(COMMAND uname -o COMMAND tr -d '\n' OUTPUT_VARIABLE OPERATING_SYSTEM)
if (OPERATING_SYSTEM MATCHES "Android") if (OPERATING_SYSTEM MATCHES "Android")
set(EXTRA_LIBS ${EXTRA_LIBS} log) set(EXTRA_LIBS ${EXTRA_LIBS} log)

View File

@@ -51,6 +51,13 @@ if (WITH_RANDOMX)
) )
# cheat because cmake and ccache hate each other # cheat because cmake and ccache hate each other
set_property(SOURCE src/crypto/randomx/jit_compiler_x86_static.S PROPERTY LANGUAGE C) set_property(SOURCE src/crypto/randomx/jit_compiler_x86_static.S PROPERTY LANGUAGE C)
elseif (XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND SOURCES_CRYPTO
src/crypto/randomx/jit_compiler_a64_static.S
src/crypto/randomx/jit_compiler_a64.cpp
)
# cheat because cmake and ccache hate each other
set_property(SOURCE src/crypto/randomx/jit_compiler_a64_static.S PROPERTY LANGUAGE C)
endif() endif()
if (CMAKE_CXX_COMPILER_ID MATCHES Clang) if (CMAKE_CXX_COMPILER_ID MATCHES Clang)

View File

@@ -94,3 +94,6 @@ Enable/configure or disable ASM optimizations. Possible values: `true`, `false`,
#### `argon2-impl` (since v3.1.0) #### `argon2-impl` (since v3.1.0)
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash. Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash.
#### `max-threads-hint` (since v4.2.0)
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md)

26
doc/CPU_MAX_USAGE.md Normal file
View File

@@ -0,0 +1,26 @@
# Maximum CPU usage
Please read this document carefully, `max-threads-hint` (was known as `max-cpu-usage`) option is most confusing option in the miner with many myth and legends.
This option is just hint for automatic configuration and can't precise define CPU usage.
### Option definition
#### Config file:
```json
{
...
"cpu": {
"max-threads-hint": 100,
...
},
...
}
```
#### Command line
`--cpu-max-threads-hint 100`
### Known issues and usage
* This option has no effect if miner already generated CPU configuration, to prevent config generation use `"autosave":false,`.
* Only threads count can be changed, for 1 core CPU this option has no effect, for 2 core CPU only 2 values possible 50% and 100%, for 4 cores: 25%, 50%, 75%, 100%. etc.
* You CPU may limited by other factors, eg cache.

View File

@@ -0,0 +1,262 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topology SYSTEM "hwloc2.dtd">
<topology version="2.0">
<object type="Machine" os_index="0" cpuset="0x00ffffff" complete_cpuset="0x00ffffff" allowed_cpuset="0x00ffffff" nodeset="0x0000000f" complete_nodeset="0x0000000f" allowed_nodeset="0x0000000f" gp_index="1">
<info name="Backend" value="Windows"/>
<info name="hwlocVersion" value="2.0.4"/>
<object type="Package" cpuset="0x00000fff" complete_cpuset="0x00000fff" nodeset="0x00000003" complete_nodeset="0x00000003" gp_index="36">
<info name="CPUVendor" value="AuthenticAMD"/>
<info name="CPUFamilyNumber" value="21"/>
<info name="CPUModelNumber" value="2"/>
<info name="CPUModel" value="AMD Opteron(tm) Processor 6344 "/>
<info name="CPUStepping" value="0"/>
<object type="L3Cache" cpuset="0x0000003f" complete_cpuset="0x0000003f" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="20" cache_size="12582912" depth="3" cache_linesize="64" cache_associativity="1" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="0" cpuset="0x0000003f" complete_cpuset="0x0000003f" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="80" local_memory="7009357824">
<page_type size="4096" count="0"/>
</object>
<object type="L2Cache" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="4" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="3" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="2">
<object type="PU" os_index="0" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="85"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="7" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="6" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="5">
<object type="PU" os_index="1" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="86"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="10" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="9" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="8">
<object type="PU" os_index="2" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="87"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="13" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="12" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="11">
<object type="PU" os_index="3" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="88"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="16" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="15" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="14">
<object type="PU" os_index="4" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="89"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="19" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="18" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="17">
<object type="PU" os_index="5" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000001" complete_nodeset="0x00000001" gp_index="90"/>
</object>
</object>
</object>
</object>
<object type="L3Cache" cpuset="0x00000fc0" complete_cpuset="0x00000fc0" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="40" cache_size="12582912" depth="3" cache_linesize="64" cache_associativity="1" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="1" cpuset="0x00000fc0" complete_cpuset="0x00000fc0" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="81" local_memory="8018194432">
<page_type size="4096" count="0"/>
</object>
<object type="L2Cache" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="23" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="22" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="21">
<object type="PU" os_index="6" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="91"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="26" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="25" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="24">
<object type="PU" os_index="7" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="92"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="29" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="28" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="27">
<object type="PU" os_index="8" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="93"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="32" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="31" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="30">
<object type="PU" os_index="9" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="94"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="35" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="34" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="33">
<object type="PU" os_index="10" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="95"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="39" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="38" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="37">
<object type="PU" os_index="11" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="96"/>
</object>
</object>
</object>
</object>
</object>
<object type="Package" cpuset="0x00fff000" complete_cpuset="0x00fff000" nodeset="0x0000000c" complete_nodeset="0x0000000c" gp_index="75">
<info name="CPUVendor" value="AuthenticAMD"/>
<info name="CPUFamilyNumber" value="21"/>
<info name="CPUModelNumber" value="2"/>
<info name="CPUModel" value="AMD Opteron(tm) Processor 6344 "/>
<info name="CPUStepping" value="0"/>
<object type="L3Cache" cpuset="0x0003f000" complete_cpuset="0x0003f000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="59" cache_size="12582912" depth="3" cache_linesize="64" cache_associativity="1" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="2" cpuset="0x0003f000" complete_cpuset="0x0003f000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="82" local_memory="8035020800">
<page_type size="4096" count="0"/>
</object>
<object type="L2Cache" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="43" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="42" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="41">
<object type="PU" os_index="12" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="97"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="46" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="45" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="44">
<object type="PU" os_index="13" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="98"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="49" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="48" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="47">
<object type="PU" os_index="14" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="99"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="52" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="51" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="50">
<object type="PU" os_index="15" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="100"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="55" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="54" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="53">
<object type="PU" os_index="16" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="101"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="58" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="57" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="56">
<object type="PU" os_index="17" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="102"/>
</object>
</object>
</object>
</object>
<object type="L3Cache" cpuset="0x00fc0000" complete_cpuset="0x00fc0000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="79" cache_size="12582912" depth="3" cache_linesize="64" cache_associativity="1" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="3" cpuset="0x00fc0000" complete_cpuset="0x00fc0000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="83" local_memory="8097337344">
<page_type size="4096" count="0"/>
</object>
<object type="L2Cache" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="62" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="61" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="60">
<object type="PU" os_index="18" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="103"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="65" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="64" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="63">
<object type="PU" os_index="19" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="104"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="68" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="67" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="66">
<object type="PU" os_index="20" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="105"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="71" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="70" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="69">
<object type="PU" os_index="21" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="106"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="74" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="73" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="72">
<object type="PU" os_index="22" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="107"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="78" cache_size="2097152" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="77" cache_size="16384" depth="1" cache_linesize="64" cache_associativity="4" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="76">
<object type="PU" os_index="23" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000008" complete_nodeset="0x00000008" gp_index="108"/>
</object>
</object>
</object>
</object>
</object>
</object>
</topology>

View File

@@ -0,0 +1,399 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topology SYSTEM "hwloc2.dtd">
<topology version="2.0">
<object type="Machine" os_index="0" cpuset="0xffffffff" complete_cpuset="0xffffffff" allowed_cpuset="0xffffffff" nodeset="0x00000066" complete_nodeset="0x000000ff" allowed_nodeset="0x00000066" gp_index="1">
<info name="DMIProductName" value="H8QG6"/>
<info name="DMIProductVersion" value="1234567890"/>
<info name="DMIProductSerial" value="1234567890"/>
<info name="DMIProductUUID" value="0"/>
<info name="DMIBoardVendor" value="Supermicro"/>
<info name="DMIBoardName" value="H8QG6"/>
<info name="DMIBoardVersion" value="1234567890"/>
<info name="DMIBoardSerial" value="0"/>
<info name="DMIBoardAssetTag" value="1234567890"/>
<info name="DMIChassisVendor" value="Supermicro"/>
<info name="DMIChassisType" value="3"/>
<info name="DMIChassisVersion" value="1234567890"/>
<info name="DMIChassisSerial" value="1234567890."/>
<info name="DMIChassisAssetTag" value="1234567890"/>
<info name="DMIBIOSVendor" value="American Megatrends Inc."/>
<info name="DMIBIOSVersion" value="080016 "/>
<info name="DMIBIOSDate" value="10/11/2010"/>
<info name="DMISysVendor" value="Supermicro"/>
<info name="Backend" value="Linux"/>
<info name="LinuxCgroup" value="/"/>
<info name="OSName" value="Linux"/>
<info name="OSRelease" value="4.15.0-20-generic"/>
<info name="OSVersion" value="#21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018"/>
<info name="HostName" value="host"/>
<info name="Architecture" value="x86_64"/>
<info name="hwlocVersion" value="2.0.4"/>
<info name="ProcessName" value="xmrig"/>
<object type="Package" os_index="0" cpuset="0x000000ff" complete_cpuset="0x000000ff" nodeset="0x00000002" complete_nodeset="0x00000003" gp_index="2">
<info name="CPUVendor" value="AuthenticAMD"/>
<info name="CPUFamilyNumber" value="16"/>
<info name="CPUModelNumber" value="9"/>
<info name="CPUModel" value="AMD Opteron(tm) Processor 6128"/>
<info name="CPUStepping" value="1"/>
<object type="L3Cache" cpuset="0x0000000f" complete_cpuset="0x0000000f" nodeset="0x0" complete_nodeset="0x00000001" gp_index="7" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L2Cache" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x0" complete_nodeset="0x00000001" gp_index="6" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x0" complete_nodeset="0x00000001" gp_index="5" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x0" complete_nodeset="0x00000001" gp_index="3">
<object type="PU" os_index="0" cpuset="0x00000001" complete_cpuset="0x00000001" nodeset="0x0" complete_nodeset="0x00000001" gp_index="4"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x0" complete_nodeset="0x00000001" gp_index="11" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x0" complete_nodeset="0x00000001" gp_index="10" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x0" complete_nodeset="0x00000001" gp_index="8">
<object type="PU" os_index="1" cpuset="0x00000002" complete_cpuset="0x00000002" nodeset="0x0" complete_nodeset="0x00000001" gp_index="9"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x0" complete_nodeset="0x00000001" gp_index="15" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x0" complete_nodeset="0x00000001" gp_index="14" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x0" complete_nodeset="0x00000001" gp_index="12">
<object type="PU" os_index="2" cpuset="0x00000004" complete_cpuset="0x00000004" nodeset="0x0" complete_nodeset="0x00000001" gp_index="13"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x0" complete_nodeset="0x00000001" gp_index="19" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x0" complete_nodeset="0x00000001" gp_index="18" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x0" complete_nodeset="0x00000001" gp_index="16">
<object type="PU" os_index="3" cpuset="0x00000008" complete_cpuset="0x00000008" nodeset="0x0" complete_nodeset="0x00000001" gp_index="17"/>
</object>
</object>
</object>
</object>
<object type="L3Cache" cpuset="0x000000f0" complete_cpuset="0x000000f0" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="24" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="1" cpuset="0x000000f0" complete_cpuset="0x000000f0" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="143" local_memory="4156817408">
<page_type size="4096" count="854592"/>
<page_type size="2097152" count="313"/>
<page_type size="1073741824" count="0"/>
</object>
<object type="L2Cache" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="23" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="22" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="20">
<object type="PU" os_index="4" cpuset="0x00000010" complete_cpuset="0x00000010" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="21"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="28" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="27" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="25">
<object type="PU" os_index="5" cpuset="0x00000020" complete_cpuset="0x00000020" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="26"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="32" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="31" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="29">
<object type="PU" os_index="6" cpuset="0x00000040" complete_cpuset="0x00000040" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="30"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="36" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="35" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="33">
<object type="PU" os_index="7" cpuset="0x00000080" complete_cpuset="0x00000080" nodeset="0x00000002" complete_nodeset="0x00000002" gp_index="34"/>
</object>
</object>
</object>
</object>
</object>
<object type="Package" os_index="1" cpuset="0x0000ff00" complete_cpuset="0x0000ff00" nodeset="0x00000004" complete_nodeset="0x0000000c" gp_index="37">
<info name="CPUVendor" value="AuthenticAMD"/>
<info name="CPUFamilyNumber" value="16"/>
<info name="CPUModelNumber" value="9"/>
<info name="CPUModel" value="AMD Opteron(tm) Processor 6128"/>
<info name="CPUStepping" value="1"/>
<object type="L3Cache" cpuset="0x00000f00" complete_cpuset="0x00000f00" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="42" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="2" cpuset="0x00000f00" complete_cpuset="0x00000f00" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="144" local_memory="4204060672">
<page_type size="4096" count="866126"/>
<page_type size="2097152" count="313"/>
<page_type size="1073741824" count="0"/>
</object>
<object type="L2Cache" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="41" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="40" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="38">
<object type="PU" os_index="8" cpuset="0x00000100" complete_cpuset="0x00000100" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="39"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="46" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="45" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="43">
<object type="PU" os_index="9" cpuset="0x00000200" complete_cpuset="0x00000200" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="44"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="50" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="49" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="47">
<object type="PU" os_index="10" cpuset="0x00000400" complete_cpuset="0x00000400" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="48"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="54" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="53" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="51">
<object type="PU" os_index="11" cpuset="0x00000800" complete_cpuset="0x00000800" nodeset="0x00000004" complete_nodeset="0x00000004" gp_index="52"/>
</object>
</object>
</object>
</object>
<object type="L3Cache" cpuset="0x0000f000" complete_cpuset="0x0000f000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="59" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L2Cache" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="58" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="57" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="55">
<object type="PU" os_index="12" cpuset="0x00001000" complete_cpuset="0x00001000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="56"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="63" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="62" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="60">
<object type="PU" os_index="13" cpuset="0x00002000" complete_cpuset="0x00002000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="61"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="67" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="66" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="64">
<object type="PU" os_index="14" cpuset="0x00004000" complete_cpuset="0x00004000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="65"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="71" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="70" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="68">
<object type="PU" os_index="15" cpuset="0x00008000" complete_cpuset="0x00008000" nodeset="0x0" complete_nodeset="0x00000008" gp_index="69"/>
</object>
</object>
</object>
</object>
</object>
<object type="Package" os_index="2" cpuset="0x00ff0000" complete_cpuset="0x00ff0000" nodeset="0x00000020" complete_nodeset="0x00000030" gp_index="72">
<info name="CPUVendor" value="AuthenticAMD"/>
<info name="CPUFamilyNumber" value="16"/>
<info name="CPUModelNumber" value="9"/>
<info name="CPUModel" value="AMD Opteron(tm) Processor 6128"/>
<info name="CPUStepping" value="1"/>
<object type="L3Cache" cpuset="0x000f0000" complete_cpuset="0x000f0000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="77" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L2Cache" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="76" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="75" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="73">
<object type="PU" os_index="16" cpuset="0x00010000" complete_cpuset="0x00010000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="74"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="81" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="80" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="78">
<object type="PU" os_index="17" cpuset="0x00020000" complete_cpuset="0x00020000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="79"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="85" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="84" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="82">
<object type="PU" os_index="18" cpuset="0x00040000" complete_cpuset="0x00040000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="83"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="89" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="88" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="86">
<object type="PU" os_index="19" cpuset="0x00080000" complete_cpuset="0x00080000" nodeset="0x0" complete_nodeset="0x00000010" gp_index="87"/>
</object>
</object>
</object>
</object>
<object type="L3Cache" cpuset="0x00f00000" complete_cpuset="0x00f00000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="94" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="5" cpuset="0x00f00000" complete_cpuset="0x00f00000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="147" local_memory="4226170880">
<page_type size="4096" count="872036"/>
<page_type size="2097152" count="312"/>
<page_type size="1073741824" count="0"/>
</object>
<object type="L2Cache" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="93" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="92" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="90">
<object type="PU" os_index="20" cpuset="0x00100000" complete_cpuset="0x00100000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="91"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="98" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="97" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="95">
<object type="PU" os_index="21" cpuset="0x00200000" complete_cpuset="0x00200000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="96"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="102" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="101" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="99">
<object type="PU" os_index="22" cpuset="0x00400000" complete_cpuset="0x00400000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="100"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="106" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="105" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="103">
<object type="PU" os_index="23" cpuset="0x00800000" complete_cpuset="0x00800000" nodeset="0x00000020" complete_nodeset="0x00000020" gp_index="104"/>
</object>
</object>
</object>
</object>
</object>
<object type="Package" os_index="3" cpuset="0xff000000" complete_cpuset="0xff000000" nodeset="0x00000040" complete_nodeset="0x000000c0" gp_index="107">
<info name="CPUVendor" value="AuthenticAMD"/>
<info name="CPUFamilyNumber" value="16"/>
<info name="CPUModelNumber" value="9"/>
<info name="CPUModel" value="AMD Opteron(tm) Processor 6128"/>
<info name="CPUStepping" value="1"/>
<object type="L3Cache" cpuset="0x0f000000" complete_cpuset="0x0f000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="112" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="NUMANode" os_index="6" cpuset="0x0f000000" complete_cpuset="0x0f000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="148" local_memory="4221870080">
<page_type size="4096" count="870986"/>
<page_type size="2097152" count="312"/>
<page_type size="1073741824" count="0"/>
</object>
<object type="L2Cache" cpuset="0x01000000" complete_cpuset="0x01000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="111" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x01000000" complete_cpuset="0x01000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="110" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x01000000" complete_cpuset="0x01000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="108">
<object type="PU" os_index="24" cpuset="0x01000000" complete_cpuset="0x01000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="109"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x02000000" complete_cpuset="0x02000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="116" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x02000000" complete_cpuset="0x02000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="115" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x02000000" complete_cpuset="0x02000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="113">
<object type="PU" os_index="25" cpuset="0x02000000" complete_cpuset="0x02000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="114"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x04000000" complete_cpuset="0x04000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="120" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x04000000" complete_cpuset="0x04000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="119" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x04000000" complete_cpuset="0x04000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="117">
<object type="PU" os_index="26" cpuset="0x04000000" complete_cpuset="0x04000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="118"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x08000000" complete_cpuset="0x08000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="124" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x08000000" complete_cpuset="0x08000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="123" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x08000000" complete_cpuset="0x08000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="121">
<object type="PU" os_index="27" cpuset="0x08000000" complete_cpuset="0x08000000" nodeset="0x00000040" complete_nodeset="0x00000040" gp_index="122"/>
</object>
</object>
</object>
</object>
<object type="L3Cache" cpuset="0xf0000000" complete_cpuset="0xf0000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="129" cache_size="5240832" depth="3" cache_linesize="64" cache_associativity="48" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L2Cache" cpuset="0x10000000" complete_cpuset="0x10000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="128" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x10000000" complete_cpuset="0x10000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="127" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="0" cpuset="0x10000000" complete_cpuset="0x10000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="125">
<object type="PU" os_index="28" cpuset="0x10000000" complete_cpuset="0x10000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="126"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x20000000" complete_cpuset="0x20000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="133" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x20000000" complete_cpuset="0x20000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="132" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="1" cpuset="0x20000000" complete_cpuset="0x20000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="130">
<object type="PU" os_index="29" cpuset="0x20000000" complete_cpuset="0x20000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="131"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x40000000" complete_cpuset="0x40000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="137" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x40000000" complete_cpuset="0x40000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="136" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="2" cpuset="0x40000000" complete_cpuset="0x40000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="134">
<object type="PU" os_index="30" cpuset="0x40000000" complete_cpuset="0x40000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="135"/>
</object>
</object>
</object>
<object type="L2Cache" cpuset="0x80000000" complete_cpuset="0x80000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="141" cache_size="524288" depth="2" cache_linesize="64" cache_associativity="16" cache_type="0">
<info name="Inclusive" value="0"/>
<object type="L1Cache" cpuset="0x80000000" complete_cpuset="0x80000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="140" cache_size="65536" depth="1" cache_linesize="64" cache_associativity="2" cache_type="1">
<info name="Inclusive" value="0"/>
<object type="Core" os_index="3" cpuset="0x80000000" complete_cpuset="0x80000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="138">
<object type="PU" os_index="31" cpuset="0x80000000" complete_cpuset="0x80000000" nodeset="0x0" complete_nodeset="0x00000080" gp_index="139"/>
</object>
</object>
</object>
</object>
</object>
</object>
<distances2 type="NUMANode" nbobjs="4" kind="5" indexing="os">
<indexes length="8">1 2 5 6 </indexes>
<u64values length="30">10 22 16 22 22 10 22 16 16 22 </u64values>
<u64values length="18">10 22 22 16 22 10 </u64values>
</distances2>
</topology>

View File

@@ -24,7 +24,7 @@
*/ */
#include <stdlib.h> #include <cstdlib>
#include <uv.h> #include <uv.h>
@@ -42,18 +42,9 @@
#include "version.h" #include "version.h"
xmrig::App::App(Process *process) : xmrig::App::App(Process *process)
m_console(nullptr),
m_signals(nullptr)
{ {
m_controller = new Controller(process); m_controller = new Controller(process);
if (m_controller->init() != 0) {
return;
}
if (!m_controller->config()->isBackground()) {
m_console = new Console(this);
}
} }
@@ -68,12 +59,26 @@ xmrig::App::~App()
int xmrig::App::exec() int xmrig::App::exec()
{ {
if (!m_controller->isReady()) { if (!m_controller->isReady()) {
LOG_EMERG("no valid configuration found.");
return 2; return 2;
} }
m_signals = new Signals(this); m_signals = new Signals(this);
background(); int rc = 0;
if (background(rc)) {
return rc;
}
rc = m_controller->init();
if (rc != 0) {
return rc;
}
if (!m_controller->isBackground()) {
m_console = new Console(this);
}
VirtualMemory::init(m_controller->config()->cpu().isHugePages()); VirtualMemory::init(m_controller->config()->cpu().isHugePages());
@@ -87,10 +92,10 @@ int xmrig::App::exec()
m_controller->start(); m_controller->start();
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); rc = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop()); uv_loop_close(uv_default_loop());
return r; return rc;
} }
@@ -150,7 +155,11 @@ void xmrig::App::onSignal(int signum)
void xmrig::App::close() void xmrig::App::close()
{ {
m_signals->stop(); m_signals->stop();
m_console->stop();
if (m_console) {
m_console->stop();
}
m_controller->stop(); m_controller->stop();
Log::destroy(); Log::destroy();

View File

@@ -29,6 +29,7 @@
#include "base/kernel/interfaces/IConsoleListener.h" #include "base/kernel/interfaces/IConsoleListener.h"
#include "base/kernel/interfaces/ISignalListener.h" #include "base/kernel/interfaces/ISignalListener.h"
#include "base/tools/Object.h"
namespace xmrig { namespace xmrig {
@@ -44,6 +45,8 @@ class Signals;
class App : public IConsoleListener, public ISignalListener class App : public IConsoleListener, public ISignalListener
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(App)
App(Process *process); App(Process *process);
~App() override; ~App() override;
@@ -54,12 +57,12 @@ protected:
void onSignal(int signum) override; void onSignal(int signum) override;
private: private:
void background(); bool background(int &rc);
void close(); void close();
Console *m_console; Console *m_console = nullptr;
Controller *m_controller; Controller *m_controller = nullptr;
Signals *m_signals; Signals *m_signals = nullptr;
}; };

View File

@@ -23,33 +23,36 @@
*/ */
#include <stdlib.h> #include <cstdlib>
#include <signal.h> #include <csignal>
#include <errno.h> #include <cerrno>
#include <unistd.h> #include <unistd.h>
#include "App.h" #include "App.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "core/config/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
void xmrig::App::background() bool xmrig::App::background(int &rc)
{ {
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
if (!m_controller->config()->isBackground()) { if (!m_controller->isBackground()) {
return; return false;
} }
int i = fork(); int i = fork();
if (i < 0) { if (i < 0) {
exit(1); rc = 1;
return true;
} }
if (i > 0) { if (i > 0) {
exit(0); rc = 0;
return true;
} }
i = setsid(); i = setsid();
@@ -62,4 +65,6 @@ void xmrig::App::background()
if (i < 0) { if (i < 0) {
LOG_ERR("chdir() failed (errno = %d)", errno); LOG_ERR("chdir() failed (errno = %d)", errno);
} }
return false;
} }

View File

@@ -29,13 +29,12 @@
#include "App.h" #include "App.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "core/config/Config.h"
void xmrig::App::background() bool xmrig::App::background(int &)
{ {
if (!m_controller->config()->isBackground()) { if (!m_controller->isBackground()) {
return; return false;
} }
HWND hcon = GetConsoleWindow(); HWND hcon = GetConsoleWindow();
@@ -46,4 +45,6 @@ void xmrig::App::background()
CloseHandle(h); CloseHandle(h);
FreeConsole(); FreeConsole();
} }
return false;
} }

View File

@@ -23,10 +23,10 @@
*/ */
#include <assert.h> #include <cassert>
#include <cmath> #include <cmath>
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <cstdio>
#include "backend/common/Hashrate.h" #include "backend/common/Hashrate.h"
@@ -133,8 +133,8 @@ double xmrig::Hashrate::calc(size_t threadId, size_t ms) const
return nan(""); return nan("");
} }
const double hashes = static_cast<double>(lastestHashCnt - earliestHashCount); const auto hashes = static_cast<double>(lastestHashCnt - earliestHashCount);
const double time = static_cast<double>(lastestStamp - earliestStamp) / 1000.0; const auto time = static_cast<double>(lastestStamp - earliestStamp) / 1000.0;
return hashes / time; return hashes / time;
} }
@@ -175,3 +175,33 @@ rapidjson::Value xmrig::Hashrate::normalize(double d)
return Value(floor(d * 100.0) / 100.0); return Value(floor(d * 100.0) / 100.0);
} }
#ifdef XMRIG_FEATURE_API
rapidjson::Value xmrig::Hashrate::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value out(kArrayType);
out.PushBack(normalize(calc(ShortInterval)), allocator);
out.PushBack(normalize(calc(MediumInterval)), allocator);
out.PushBack(normalize(calc(LargeInterval)), allocator);
return out;
}
rapidjson::Value xmrig::Hashrate::toJSON(size_t threadId, rapidjson::Document &doc) const
{
using namespace rapidjson;
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);
return out;
}
#endif

View File

@@ -26,10 +26,11 @@
#define XMRIG_HASHRATE_H #define XMRIG_HASHRATE_H
#include <stddef.h> #include <cstddef>
#include <stdint.h> #include <cstdint>
#include "base/tools/Object.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@@ -39,6 +40,8 @@ namespace xmrig {
class Hashrate class Hashrate
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Hashrate)
enum Intervals { enum Intervals {
ShortInterval = 10000, ShortInterval = 10000,
MediumInterval = 60000, MediumInterval = 60000,
@@ -58,6 +61,11 @@ public:
static const char *format(double h, char *buf, size_t size); static const char *format(double h, char *buf, size_t size);
static rapidjson::Value normalize(double d); static rapidjson::Value normalize(double d);
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const;
rapidjson::Value toJSON(size_t threadId, rapidjson::Document &doc) const;
# endif
private: private:
constexpr static size_t kBucketSize = 2 << 11; constexpr static size_t kBucketSize = 2 << 11;
constexpr static size_t kBucketMask = kBucketSize - 1; constexpr static size_t kBucketMask = kBucketSize - 1;

View File

@@ -26,10 +26,11 @@
#define XMRIG_THREAD_H #define XMRIG_THREAD_H
#include <thread>
#include "backend/common/interfaces/IWorker.h" #include "backend/common/interfaces/IWorker.h"
#include "base/tools/Object.h"
#include <thread>
namespace xmrig { namespace xmrig {
@@ -42,6 +43,8 @@ template<class T>
class Thread class Thread
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Thread)
inline Thread(IBackend *backend, size_t id, const T &config) : m_id(id), m_config(config), m_backend(backend) {} inline Thread(IBackend *backend, size_t id, const T &config) : m_id(id), m_config(config), m_backend(backend) {}
inline ~Thread() { m_thread.join(); delete m_worker; } inline ~Thread() { m_thread.join(); delete m_worker; }

View File

@@ -44,6 +44,7 @@ class Threads
public: public:
inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; } inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; }
inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; } inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; }
inline bool isEmpty() const { return m_profiles.empty(); }
inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); } inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); }
inline const T &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); } inline const T &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); }
inline void disable(const Algorithm &algo) { m_disabled.insert(algo); } inline void disable(const Algorithm &algo) { m_disabled.insert(algo); }

View File

@@ -29,6 +29,7 @@
#include "backend/common/Workers.h" #include "backend/common/Workers.h"
#include "backend/cpu/CpuWorker.h" #include "backend/cpu/CpuWorker.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "base/tools/Object.h"
#ifdef XMRIG_FEATURE_OPENCL #ifdef XMRIG_FEATURE_OPENCL
@@ -42,9 +43,10 @@ namespace xmrig {
class WorkersPrivate class WorkersPrivate
{ {
public: public:
inline WorkersPrivate() XMRIG_DISABLE_COPY_MOVE(WorkersPrivate)
{
}
WorkersPrivate() = default;
inline ~WorkersPrivate() inline ~WorkersPrivate()
@@ -131,7 +133,7 @@ void xmrig::Workers<T>::tick(uint64_t)
for (Thread<T> *handle : m_workers) { for (Thread<T> *handle : m_workers) {
if (!handle->worker()) { if (!handle->worker()) {
return; continue;
} }
d_ptr->hashrate->add(handle->id(), handle->worker()->hashCount(), handle->worker()->timestamp()); d_ptr->hashrate->add(handle->id(), handle->worker()->hashCount(), handle->worker()->timestamp());
@@ -154,17 +156,21 @@ void xmrig::Workers<T>::onReady(void *arg)
auto handle = static_cast<Thread<T>* >(arg); auto handle = static_cast<Thread<T>* >(arg);
IWorker *worker = create(handle); IWorker *worker = create(handle);
if (!worker || !worker->selfTest()) { assert(worker != nullptr);
LOG_ERR("thread %zu error: \"hash self-test failed\".", worker->id());
if (!worker || !worker->selfTest()) {
LOG_ERR("%s " RED("thread ") RED_BOLD("#%zu") RED(" self-test failed"), T::tag(), worker->id());
handle->backend()->start(worker, false);
delete worker; delete worker;
return; return;
} }
assert(handle->backend() != nullptr); assert(handle->backend() != nullptr);
handle->setWorker(worker); handle->setWorker(worker);
handle->backend()->start(worker); handle->backend()->start(worker, true);
} }

View File

@@ -29,6 +29,7 @@
#include "backend/common/Thread.h" #include "backend/common/Thread.h"
#include "backend/cpu/CpuLaunchData.h" #include "backend/cpu/CpuLaunchData.h"
#include "base/tools/Object.h"
#ifdef XMRIG_FEATURE_OPENCL #ifdef XMRIG_FEATURE_OPENCL
@@ -47,6 +48,8 @@ template<class T>
class Workers class Workers
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE(Workers)
Workers(); Workers();
~Workers(); ~Workers();

View File

@@ -26,7 +26,7 @@
#define XMRIG_IBACKEND_H #define XMRIG_IBACKEND_H
#include <stdint.h> #include <cstdint>
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@@ -56,7 +56,7 @@ public:
virtual void prepare(const Job &nextJob) = 0; virtual void prepare(const Job &nextJob) = 0;
virtual void printHashrate(bool details) = 0; virtual void printHashrate(bool details) = 0;
virtual void setJob(const Job &job) = 0; virtual void setJob(const Job &job) = 0;
virtual void start(IWorker *worker) = 0; virtual void start(IWorker *worker, bool ready) = 0;
virtual void stop() = 0; virtual void stop() = 0;
virtual void tick(uint64_t ticks) = 0; virtual void tick(uint64_t ticks) = 0;

View File

@@ -26,8 +26,8 @@
#define XMRIG_IWORKER_H #define XMRIG_IWORKER_H
#include <stdint.h> #include <cstdint>
#include <stddef.h> #include <cstddef>
namespace xmrig { namespace xmrig {
@@ -44,6 +44,7 @@ public:
virtual bool selfTest() = 0; virtual bool selfTest() = 0;
virtual const VirtualMemory *memory() const = 0; virtual const VirtualMemory *memory() const = 0;
virtual size_t id() const = 0; virtual size_t id() const = 0;
virtual size_t intensity() const = 0;
virtual uint64_t hashCount() const = 0; virtual uint64_t hashCount() const = 0;
virtual uint64_t timestamp() const = 0; virtual uint64_t timestamp() const = 0;
virtual void start() = 0; virtual void start() = 0;

View File

@@ -27,7 +27,7 @@
#define XMRIG_PCITOPOLOGY_H #define XMRIG_PCITOPOLOGY_H
#include <stdio.h> #include <cstdio>
#include "base/tools/String.h" #include "base/tools/String.h"
@@ -40,19 +40,30 @@ class PciTopology
{ {
public: public:
PciTopology() = default; PciTopology() = default;
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : bus(bus), device(device), function(function) {} PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
uint32_t bus = 0; inline bool isValid() const { return m_valid; }
uint32_t device = 0; inline uint8_t bus() const { return m_bus; }
uint32_t function = 0; inline uint8_t device() const { return m_device; }
inline uint8_t function() const { return m_function; }
String toString() const String toString() const
{ {
if (!isValid()) {
return "n/a";
}
char *buf = new char[8](); char *buf = new char[8]();
snprintf(buf, 8, "%02x:%02x.%01x", bus, device, function); snprintf(buf, 8, "%02hhx:%02hhx.%01hhx", bus(), device(), function());
return buf; return buf;
} }
private:
bool m_valid = false;
uint8_t m_bus = 0;
uint8_t m_device = 0;
uint8_t m_function = 0;
}; };

View File

@@ -23,7 +23,7 @@
*/ */
#include <assert.h> #include <cassert>
#include "backend/cpu/Cpu.h" #include "backend/cpu/Cpu.h"
@@ -44,7 +44,15 @@ static xmrig::ICpuInfo *cpuInfo = nullptr;
xmrig::ICpuInfo *xmrig::Cpu::info() xmrig::ICpuInfo *xmrig::Cpu::info()
{ {
assert(cpuInfo != nullptr); if (cpuInfo == nullptr) {
# if defined(XMRIG_FEATURE_HWLOC)
cpuInfo = new HwlocCpuInfo();
# elif defined(XMRIG_FEATURE_LIBCPUID)
cpuInfo = new AdvancedCpuInfo();
# else
cpuInfo = new BasicCpuInfo();
# endif
}
return cpuInfo; return cpuInfo;
} }
@@ -62,7 +70,7 @@ rapidjson::Value xmrig::Cpu::toJSON(rapidjson::Document &doc)
cpu.AddMember("brand", StringRef(i->brand()), allocator); cpu.AddMember("brand", StringRef(i->brand()), allocator);
cpu.AddMember("aes", i->hasAES(), allocator); cpu.AddMember("aes", i->hasAES(), allocator);
cpu.AddMember("avx2", i->hasAVX2(), allocator); cpu.AddMember("avx2", i->hasAVX2(), allocator);
cpu.AddMember("x64", i->isX64(), allocator); cpu.AddMember("x64", ICpuInfo::isX64(), allocator);
cpu.AddMember("l2", static_cast<uint64_t>(i->L2()), allocator); cpu.AddMember("l2", static_cast<uint64_t>(i->L2()), allocator);
cpu.AddMember("l3", static_cast<uint64_t>(i->L3()), allocator); cpu.AddMember("l3", static_cast<uint64_t>(i->L3()), allocator);
cpu.AddMember("cores", static_cast<uint64_t>(i->cores()), allocator); cpu.AddMember("cores", static_cast<uint64_t>(i->cores()), allocator);
@@ -81,20 +89,6 @@ rapidjson::Value xmrig::Cpu::toJSON(rapidjson::Document &doc)
} }
void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
# if defined(XMRIG_FEATURE_HWLOC)
cpuInfo = new HwlocCpuInfo();
# elif defined(XMRIG_FEATURE_LIBCPUID)
cpuInfo = new AdvancedCpuInfo();
# else
cpuInfo = new BasicCpuInfo();
# endif
}
void xmrig::Cpu::release() void xmrig::Cpu::release()
{ {
assert(cpuInfo != nullptr); assert(cpuInfo != nullptr);

View File

@@ -37,7 +37,6 @@ class Cpu
public: public:
static ICpuInfo *info(); static ICpuInfo *info();
static rapidjson::Value toJSON(rapidjson::Document &doc); static rapidjson::Value toJSON(rapidjson::Document &doc);
static void init();
static void release(); static void release();
inline static Assembly::Id assembly(Assembly::Id hint) { return hint == Assembly::AUTO ? Cpu::info()->assembly() : hint; } inline static Assembly::Id assembly(Assembly::Id hint) { return hint == Assembly::AUTO ? Cpu::info()->assembly() : hint; }

View File

@@ -60,7 +60,7 @@ namespace xmrig {
extern template class Threads<CpuThreads>; extern template class Threads<CpuThreads>;
static const char *tag = CYAN_BG_BOLD(" cpu "); static const char *tag = CYAN_BG_BOLD(WHITE_BOLD_S " cpu ");
static const String kType = "cpu"; static const String kType = "cpu";
static std::mutex mutex; static std::mutex mutex;
@@ -80,38 +80,51 @@ public:
m_memory = memory; m_memory = memory;
m_pages = 0; m_pages = 0;
m_started = 0; m_started = 0;
m_errors = 0;
m_threads = threads.size(); m_threads = threads.size();
m_ways = 0; m_ways = 0;
m_ts = Chrono::steadyMSecs(); m_ts = Chrono::steadyMSecs();
for (const CpuLaunchData &data : threads) {
m_ways += data.intensity;
}
} }
inline bool started(const std::pair<size_t, size_t> &hugePages) inline bool started(IWorker *worker, bool ready)
{ {
m_started++; if (ready) {
m_hugePages += hugePages.first; auto hugePages = worker->memory()->hugePages();
m_pages += hugePages.second;
return m_started == m_threads; m_started++;
m_hugePages += hugePages.first;
m_pages += hugePages.second;
m_ways += worker->intensity();
}
else {
m_errors++;
}
return (m_started + m_errors) == m_threads;
} }
inline void print() const inline void print() const
{ {
LOG_INFO("%s" GREEN_BOLD(" READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"), if (m_started == 0) {
LOG_ERR("%s " RED_BOLD("disabled") YELLOW(" (failed to start threads)"), tag);
return;
}
LOG_INFO("%s" GREEN_BOLD(" READY") " threads %s%zu/%zu (%zu)" CLEAR " huge pages %s%zu/%zu %1.0f%%" CLEAR " memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"),
tag, tag,
m_threads, m_ways, m_errors == 0 ? CYAN_BOLD_S : YELLOW_BOLD_S,
m_started, m_threads, m_ways,
(m_hugePages == m_pages ? GREEN_BOLD_S : (m_hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), (m_hugePages == m_pages ? GREEN_BOLD_S : (m_hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
m_hugePages, m_pages, m_hugePages, m_pages,
m_hugePages == 0 ? 0.0 : static_cast<double>(m_hugePages) / m_pages * 100.0, m_hugePages == 0 ? 0.0 : static_cast<double>(m_hugePages) / m_pages * 100.0,
m_ways * m_memory / 1024, memory() / 1024,
Chrono::steadyMSecs() - m_ts Chrono::steadyMSecs() - m_ts
); );
} }
private: private:
size_t m_errors = 0;
size_t m_hugePages = 0; size_t m_hugePages = 0;
size_t m_memory = 0; size_t m_memory = 0;
size_t m_pages = 0; size_t m_pages = 0;
@@ -322,17 +335,19 @@ void xmrig::CpuBackend::setJob(const Job &job)
} }
void xmrig::CpuBackend::start(IWorker *worker) void xmrig::CpuBackend::start(IWorker *worker, bool ready)
{ {
mutex.lock(); mutex.lock();
if (d_ptr->status.started(worker->memory()->hugePages())) { if (d_ptr->status.started(worker, ready)) {
d_ptr->status.print(); d_ptr->status.print();
} }
mutex.unlock(); mutex.unlock();
worker->start(); if (ready) {
worker->start();
}
} }
@@ -390,8 +405,9 @@ rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const
return out; return out;
} }
out.AddMember("hashrate", hashrate()->toJSON(doc), allocator);
Value threads(kArrayType); Value threads(kArrayType);
const Hashrate *hr = hashrate();
size_t i = 0; size_t i = 0;
for (const CpuLaunchData &data : d_ptr->threads) { for (const CpuLaunchData &data : d_ptr->threads) {
@@ -399,15 +415,9 @@ rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const
thread.AddMember("intensity", data.intensity, allocator); thread.AddMember("intensity", data.intensity, allocator);
thread.AddMember("affinity", data.affinity, allocator); thread.AddMember("affinity", data.affinity, allocator);
thread.AddMember("av", data.av(), allocator); thread.AddMember("av", data.av(), allocator);
thread.AddMember("hashrate", hashrate()->toJSON(i, doc), allocator);
Value hashrate(kArrayType);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
i++; i++;
thread.AddMember("hashrate", hashrate, allocator);
threads.PushBack(thread, allocator); threads.PushBack(thread, allocator);
} }

View File

@@ -26,10 +26,11 @@
#define XMRIG_CPUBACKEND_H #define XMRIG_CPUBACKEND_H
#include <utility>
#include "backend/common/interfaces/IBackend.h" #include "backend/common/interfaces/IBackend.h"
#include "base/tools/Object.h"
#include <utility>
namespace xmrig { namespace xmrig {
@@ -43,6 +44,8 @@ class Miner;
class CpuBackend : public IBackend class CpuBackend : public IBackend
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(CpuBackend)
CpuBackend(Controller *controller); CpuBackend(Controller *controller);
~CpuBackend() override; ~CpuBackend() override;
@@ -55,7 +58,7 @@ protected:
void prepare(const Job &nextJob) override; void prepare(const Job &nextJob) override;
void printHashrate(bool details) override; void printHashrate(bool details) override;
void setJob(const Job &job) override; void setJob(const Job &job) override;
void start(IWorker *worker) override; void start(IWorker *worker, bool ready) override;
void stop() override; void stop() override;
void tick(uint64_t ticks) override; void tick(uint64_t ticks) override;

View File

@@ -35,6 +35,7 @@ static const char *kCn = "cn";
static const char *kEnabled = "enabled"; static const char *kEnabled = "enabled";
static const char *kHugePages = "huge-pages"; static const char *kHugePages = "huge-pages";
static const char *kHwAes = "hw-aes"; static const char *kHwAes = "hw-aes";
static const char *kMaxThreadsHint = "max-threads-hint";
static const char *kPriority = "priority"; static const char *kPriority = "priority";
#ifdef XMRIG_FEATURE_ASM #ifdef XMRIG_FEATURE_ASM
@@ -72,11 +73,6 @@ extern template class Threads<CpuThreads>;
} }
xmrig::CpuConfig::CpuConfig()
{
}
bool xmrig::CpuConfig::isHwAES() const bool xmrig::CpuConfig::isHwAES() const
{ {
return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW; return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW;
@@ -95,6 +91,10 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), 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(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
if (m_threads.isEmpty()) {
obj.AddMember(StringRef(kMaxThreadsHint), m_limit, allocator);
}
# ifdef XMRIG_FEATURE_ASM # ifdef XMRIG_FEATURE_ASM
obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator); obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator);
# endif # endif
@@ -131,8 +131,9 @@ std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, cons
void xmrig::CpuConfig::read(const rapidjson::Value &value, uint32_t version) void xmrig::CpuConfig::read(const rapidjson::Value &value, uint32_t version)
{ {
if (value.IsObject()) { if (value.IsObject()) {
m_enabled = Json::getBool(value, kEnabled, m_enabled); m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages); m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
setAesMode(Json::getValue(value, kHwAes)); setAesMode(Json::getValue(value, kHwAes));
setPriority(Json::getInt(value, kPriority, -1)); setPriority(Json::getInt(value, kPriority, -1));
@@ -168,28 +169,28 @@ void xmrig::CpuConfig::generate()
ICpuInfo *cpu = Cpu::info(); ICpuInfo *cpu = Cpu::info();
m_threads.disable(Algorithm::CN_0); m_threads.disable(Algorithm::CN_0);
m_threads.move(kCn, cpu->threads(Algorithm::CN_0)); m_threads.move(kCn, cpu->threads(Algorithm::CN_0, m_limit));
# ifdef XMRIG_ALGO_CN_GPU # ifdef XMRIG_ALGO_CN_GPU
m_threads.move(kCnGPU, cpu->threads(Algorithm::CN_GPU)); m_threads.move(kCnGPU, cpu->threads(Algorithm::CN_GPU, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_CN_LITE # ifdef XMRIG_ALGO_CN_LITE
m_threads.disable(Algorithm::CN_LITE_0); m_threads.disable(Algorithm::CN_LITE_0);
m_threads.move(kCnLite, cpu->threads(Algorithm::CN_LITE_1)); m_threads.move(kCnLite, cpu->threads(Algorithm::CN_LITE_1, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_CN_HEAVY # ifdef XMRIG_ALGO_CN_HEAVY
m_threads.move(kCnHeavy, cpu->threads(Algorithm::CN_HEAVY_0)); m_threads.move(kCnHeavy, cpu->threads(Algorithm::CN_HEAVY_0, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_CN_PICO # ifdef XMRIG_ALGO_CN_PICO
m_threads.move(kCnPico, cpu->threads(Algorithm::CN_PICO_0)); m_threads.move(kCnPico, cpu->threads(Algorithm::CN_PICO_0, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
m_threads.move(kRx, cpu->threads(Algorithm::RX_0)); m_threads.move(kRx, cpu->threads(Algorithm::RX_0, m_limit));
m_threads.move(kRxWOW, cpu->threads(Algorithm::RX_WOW)); m_threads.move(kRxWOW, cpu->threads(Algorithm::RX_WOW, m_limit));
# endif # endif
generateArgon2(); generateArgon2();
@@ -199,7 +200,7 @@ void xmrig::CpuConfig::generate()
void xmrig::CpuConfig::generateArgon2() void xmrig::CpuConfig::generateArgon2()
{ {
# ifdef XMRIG_ALGO_ARGON2 # ifdef XMRIG_ALGO_ARGON2
m_threads.move(kArgon2, Cpu::info()->threads(Algorithm::AR2_CHUKWA)); m_threads.move(kArgon2, Cpu::info()->threads(Algorithm::AR2_CHUKWA, m_limit));
# endif # endif
} }

View File

@@ -44,7 +44,7 @@ public:
AES_SOFT AES_SOFT
}; };
CpuConfig(); CpuConfig() = default;
bool isHwAES() const; bool isHwAES() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const; rapidjson::Value toJSON(rapidjson::Document &doc) const;
@@ -74,6 +74,7 @@ private:
int m_priority = -1; int m_priority = -1;
String m_argon2Impl; String m_argon2Impl;
Threads<CpuThreads> m_threads; Threads<CpuThreads> m_threads;
uint32_t m_limit = 100;
}; };

View File

@@ -24,13 +24,15 @@
*/ */
#include <algorithm>
#include "backend/cpu/CpuLaunchData.h" #include "backend/cpu/CpuLaunchData.h"
#include "backend/common/Tags.h"
#include "backend/cpu/CpuConfig.h" #include "backend/cpu/CpuConfig.h"
#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) :
algorithm(algorithm), algorithm(algorithm),
assembly(config.assembly()), assembly(config.assembly()),
@@ -65,3 +67,9 @@ xmrig::CnHash::AlgoVariant xmrig::CpuLaunchData::av() const
return static_cast<CnHash::AlgoVariant>(!hwAES ? (intensity + 5) : (intensity + 2)); return static_cast<CnHash::AlgoVariant>(!hwAES ? (intensity + 5) : (intensity + 2));
} }
const char *xmrig::CpuLaunchData::tag()
{
return cpu_tag();
}

View File

@@ -54,6 +54,8 @@ public:
inline bool operator!=(const CpuLaunchData &other) const { return !isEqual(other); } inline bool operator!=(const CpuLaunchData &other) const { return !isEqual(other); }
inline bool operator==(const CpuLaunchData &other) const { return isEqual(other); } inline bool operator==(const CpuLaunchData &other) const { return isEqual(other); }
static const char *tag();
const Algorithm algorithm; const Algorithm algorithm;
const Assembly assembly; const Assembly assembly;
const bool hugePages; const bool hugePages;

View File

@@ -54,6 +54,7 @@ protected:
void start() override; void start() override;
inline const VirtualMemory *memory() const override { return m_memory; } inline const VirtualMemory *memory() const override { return m_memory; }
inline size_t intensity() const override { return N; }
private: private:
inline cn_hash_fun fn(const Algorithm &algorithm) const { return CnHash::fn(algorithm, m_av, m_assembly); } inline cn_hash_fun fn(const Algorithm &algorithm) const { return CnHash::fn(algorithm, m_av, m_assembly); }

View File

@@ -45,18 +45,18 @@ public:
inline constexpr static bool isX64() { return false; } inline constexpr static bool isX64() { return false; }
# endif # endif
virtual Assembly::Id assembly() const = 0; virtual Assembly::Id assembly() const = 0;
virtual bool hasAES() const = 0; virtual bool hasAES() const = 0;
virtual bool hasAVX2() const = 0; virtual bool hasAVX2() const = 0;
virtual const char *backend() const = 0; virtual const char *backend() const = 0;
virtual const char *brand() const = 0; virtual const char *brand() const = 0;
virtual CpuThreads threads(const Algorithm &algorithm) const = 0; virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
virtual size_t cores() const = 0; virtual size_t cores() const = 0;
virtual size_t L2() const = 0; virtual size_t L2() const = 0;
virtual size_t L3() const = 0; virtual size_t L3() const = 0;
virtual size_t nodes() const = 0; virtual size_t nodes() const = 0;
virtual size_t packages() const = 0; virtual size_t packages() const = 0;
virtual size_t threads() const = 0; virtual size_t threads() const = 0;
}; };

View File

@@ -23,10 +23,10 @@
*/ */
#include <algorithm> #include <algorithm>
#include <assert.h> #include <cassert>
#include <math.h> #include <cmath>
#include <stdio.h> #include <cstdio>
#include <string.h> #include <cstring>
#include "3rdparty/libcpuid/libcpuid.h" #include "3rdparty/libcpuid/libcpuid.h"
@@ -109,7 +109,7 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
} }
xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) const xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
{ {
if (threads() == 1) { if (threads() == 1) {
return 1; return 1;
@@ -153,5 +153,12 @@ xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) co
} }
# endif # endif
return CpuThreads(std::max<size_t>(std::min<size_t>(count, threads()), 1), intensity); if (limit > 0 && limit < 100) {
count = std::min(count, static_cast<size_t>(round(threads() * (limit / 100.0))));
}
else {
count = std::min(count, threads());
}
return CpuThreads(std::max<size_t>(count, 1), intensity);
} }

View File

@@ -38,7 +38,7 @@ public:
AdvancedCpuInfo(); AdvancedCpuInfo();
protected: protected:
CpuThreads threads(const Algorithm &algorithm) const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
inline Assembly::Id assembly() const override { return m_assembly; } inline Assembly::Id assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; } inline bool hasAES() const override { return m_aes; }

View File

@@ -179,7 +179,7 @@ const char *xmrig::BasicCpuInfo::backend() const
} }
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
{ {
const size_t count = std::thread::hardware_concurrency(); const size_t count = std::thread::hardware_concurrency();

View File

@@ -39,7 +39,7 @@ public:
protected: protected:
const char *backend() const override; const char *backend() const override;
CpuThreads threads(const Algorithm &algorithm) const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
inline Assembly::Id assembly() const override { return m_assembly; } inline Assembly::Id assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; } inline bool hasAES() const override { return m_aes; }

View File

@@ -63,7 +63,7 @@ const char *xmrig::BasicCpuInfo::backend() const
} }
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &) const xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &, uint32_t) const
{ {
return CpuThreads(threads()); return CpuThreads(threads());
} }

View File

@@ -29,6 +29,7 @@
#include <algorithm> #include <algorithm>
#include <cmath>
#include <hwloc.h> #include <hwloc.h>
@@ -127,9 +128,7 @@ static inline bool isCacheExclusive(hwloc_obj_t obj)
} // namespace xmrig } // namespace xmrig
xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(), xmrig::HwlocCpuInfo::HwlocCpuInfo()
m_backend(),
m_cache()
{ {
m_threads = 0; m_threads = 0;
@@ -149,7 +148,7 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(),
# endif # endif
const std::vector<hwloc_obj_t> packages = findByType(hwloc_get_root_obj(m_topology), HWLOC_OBJ_PACKAGE); const std::vector<hwloc_obj_t> packages = findByType(hwloc_get_root_obj(m_topology), HWLOC_OBJ_PACKAGE);
if (packages.size()) { if (!packages.empty()) {
const char *value = hwloc_obj_get_info_by_name(packages[0], "CPUModel"); const char *value = hwloc_obj_get_info_by_name(packages[0], "CPUModel");
if (value) { if (value) {
strncpy(m_brand, value, 64); strncpy(m_brand, value, 64);
@@ -202,10 +201,10 @@ xmrig::HwlocCpuInfo::~HwlocCpuInfo()
} }
xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm) const xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
{ {
if (L2() == 0 && L3() == 0) { if (L2() == 0 && L3() == 0) {
return BasicCpuInfo::threads(algorithm); return BasicCpuInfo::threads(algorithm, limit);
} }
const unsigned depth = L3() > 0 ? 3 : 2; const unsigned depth = L3() > 0 ? 3 : 2;
@@ -218,21 +217,37 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm) const
findCache(hwloc_get_root_obj(m_topology), depth, depth, [&caches](hwloc_obj_t found) { caches.emplace_back(found); }); findCache(hwloc_get_root_obj(m_topology), depth, depth, [&caches](hwloc_obj_t found) { caches.emplace_back(found); });
for (hwloc_obj_t cache : caches) { if (limit > 0 && limit < 100 && !caches.empty()) {
processTopLevelCache(cache, algorithm, threads); const double maxTotalThreads = round(m_threads * (limit / 100.0));
const auto maxPerCache = std::max(static_cast<int>(round(maxTotalThreads / caches.size())), 1);
int remaining = std::max(static_cast<int>(maxTotalThreads), 1);
for (hwloc_obj_t cache : caches) {
processTopLevelCache(cache, algorithm, threads, std::min(maxPerCache, remaining));
remaining -= maxPerCache;
if (remaining <= 0) {
break;
}
}
}
else {
for (hwloc_obj_t cache : caches) {
processTopLevelCache(cache, algorithm, threads, 0);
}
} }
if (threads.isEmpty()) { if (threads.isEmpty()) {
LOG_WARN("hwloc auto configuration for algorithm \"%s\" failed.", algorithm.shortName()); LOG_WARN("hwloc auto configuration for algorithm \"%s\" failed.", algorithm.shortName());
return BasicCpuInfo::threads(algorithm); return BasicCpuInfo::threads(algorithm, limit);
} }
return threads; return threads;
} }
void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads) const void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const
{ {
constexpr size_t oneMiB = 1024u * 1024u; constexpr size_t oneMiB = 1024u * 1024u;
@@ -296,6 +311,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
} }
# endif # endif
if (limit > 0) {
cacheHashes = std::min(cacheHashes, limit);
}
if (cacheHashes >= PUs) { if (cacheHashes >= PUs) {
for (hwloc_obj_t core : cores) { for (hwloc_obj_t core : cores) {
const std::vector<hwloc_obj_t> units = findByType(core, HWLOC_OBJ_PU); const std::vector<hwloc_obj_t> units = findByType(core, HWLOC_OBJ_PU);

View File

@@ -27,10 +27,11 @@
#include "backend/cpu/platform/BasicCpuInfo.h" #include "backend/cpu/platform/BasicCpuInfo.h"
#include "base/tools/Object.h"
typedef struct hwloc_obj *hwloc_obj_t; using hwloc_obj_t = struct hwloc_obj *;
typedef struct hwloc_topology *hwloc_topology_t; using hwloc_topology_t = struct hwloc_topology *;
namespace xmrig { namespace xmrig {
@@ -39,6 +40,9 @@ namespace xmrig {
class HwlocCpuInfo : public BasicCpuInfo class HwlocCpuInfo : public BasicCpuInfo
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE(HwlocCpuInfo)
enum Feature : uint32_t { enum Feature : uint32_t {
SET_THISTHREAD_MEMBIND = 1 SET_THISTHREAD_MEMBIND = 1
}; };
@@ -51,7 +55,7 @@ public:
static inline const std::vector<uint32_t> &nodeIndexes() { return m_nodeIndexes; } static inline const std::vector<uint32_t> &nodeIndexes() { return m_nodeIndexes; }
protected: protected:
CpuThreads threads(const Algorithm &algorithm) const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
inline const char *backend() const override { return m_backend; } inline const char *backend() const override { return m_backend; }
inline size_t cores() const override { return m_cores; } inline size_t cores() const override { return m_cores; }
@@ -61,17 +65,17 @@ protected:
inline size_t packages() const override { return m_packages; } inline size_t packages() const override { return m_packages; }
private: private:
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads) const; void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;
static std::vector<uint32_t> m_nodeIndexes; static std::vector<uint32_t> m_nodeIndexes;
static uint32_t m_features; static uint32_t m_features;
char m_backend[20]; char m_backend[20] = { 0 };
hwloc_topology_t m_topology; hwloc_topology_t m_topology = nullptr;
size_t m_cache[5]; size_t m_cache[5] = { 0 };
size_t m_cores = 0; size_t m_cores = 0;
size_t m_nodes = 0; size_t m_nodes = 0;
size_t m_packages = 0; size_t m_packages = 0;
}; };

View File

@@ -72,12 +72,19 @@ static void printDisabled(const char *reason)
struct OclLaunchStatus struct OclLaunchStatus
{ {
public: public:
inline bool started() { m_started++; return m_started == m_threads; } inline size_t threads() const { return m_threads; }
inline size_t threads() const { return m_threads; }
inline bool started(bool ready)
{
ready ? m_started++ : m_errors++;
return (m_started + m_errors) == m_threads;
}
inline void start(size_t threads) inline void start(size_t threads)
{ {
m_started = 0; m_started = 0;
m_errors = 0;
m_threads = threads; m_threads = threads;
m_ts = Chrono::steadyMSecs(); m_ts = Chrono::steadyMSecs();
OclWorker::ready = false; OclWorker::ready = false;
@@ -85,14 +92,23 @@ public:
inline void print() const inline void print() const
{ {
LOG_INFO("%s" GREEN_BOLD(" READY") " threads " CYAN_BOLD("%zu") BLACK_BOLD(" (%" PRIu64 " ms)"), if (m_started == 0) {
LOG_ERR("%s " RED_BOLD("disabled") YELLOW(" (failed to start threads)"), tag);
return;
}
LOG_INFO("%s" GREEN_BOLD(" READY") " threads " "%s%zu/%zu" BLACK_BOLD(" (%" PRIu64 " ms)"),
tag, tag,
m_errors == 0 ? CYAN_BOLD_S : YELLOW_BOLD_S,
m_started,
m_threads, m_threads,
Chrono::steadyMSecs() - m_ts Chrono::steadyMSecs() - m_ts
); );
} }
private: private:
size_t m_errors = 0;
size_t m_started = 0; size_t m_started = 0;
size_t m_threads = 0; size_t m_threads = 0;
uint64_t m_ts = 0; uint64_t m_ts = 0;
@@ -119,6 +135,10 @@ public:
return printDisabled(RED_S " (failed to load OpenCL runtime)"); return printDisabled(RED_S " (failed to load OpenCL runtime)");
} }
if (platform.isValid()) {
return;
}
platform = cl.platform(); platform = cl.platform();
if (!platform.isValid()) { if (!platform.isValid()) {
return printDisabled(RED_S " (selected OpenCL platform NOT found)"); return printDisabled(RED_S " (selected OpenCL platform NOT found)");
@@ -134,7 +154,7 @@ public:
for (const OclDevice &device : devices) { for (const OclDevice &device : devices) {
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") " %s " WHITE_BOLD("%uMHz") " cu:" WHITE_BOLD("%u") " mem:" CYAN("%zu/%zu") " MB", "OPENCL GPU", Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") " %s " WHITE_BOLD("%uMHz") " cu:" WHITE_BOLD("%u") " mem:" CYAN("%zu/%zu") " MB", "OPENCL GPU",
device.index(), device.index(),
device.hasTopology() ? device.topology().toString().data() : "n/a", device.topology().toString().data(),
device.printableName().data(), device.printableName().data(),
device.clock(), device.clock(),
device.computeUnits(), device.computeUnits(),
@@ -161,7 +181,7 @@ public:
CYAN_BOLD("%3u") " |" CYAN_BOLD("%3s") " |" CYAN_BOLD("%3u") " |" CYAN("%5zu") " | %s", CYAN_BOLD("%3u") " |" CYAN_BOLD("%3s") " |" CYAN_BOLD("%3u") " |" CYAN("%5zu") " | %s",
i, i,
data.thread.index(), data.thread.index(),
data.device.hasTopology() ? data.device.topology().toString().data() : "n/a", data.device.topology().toString().data(),
data.thread.intensity(), data.thread.intensity(),
data.thread.worksize(), data.thread.worksize(),
data.thread.stridedIndex(), data.thread.stridedIndex(),
@@ -269,7 +289,7 @@ void xmrig::OclBackend::printHashrate(bool details)
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, 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, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3),
data.device.index(), data.device.index(),
data.device.hasTopology() ? data.device.topology().toString().data() : "n/a", data.device.topology().toString().data(),
data.device.printableName().data() data.device.printableName().data()
); );
@@ -286,12 +306,15 @@ void xmrig::OclBackend::printHashrate(bool details)
void xmrig::OclBackend::setJob(const Job &job) void xmrig::OclBackend::setJob(const Job &job)
{ {
const OclConfig &cl = d_ptr->controller->config()->cl();
if (cl.isEnabled()) {
d_ptr->init(cl);
}
if (!isEnabled()) { if (!isEnabled()) {
return stop(); return stop();
} }
const OclConfig &cl = d_ptr->controller->config()->cl();
std::vector<OclLaunchData> threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices, tag); std::vector<OclLaunchData> threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices, tag);
if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) { if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
return; return;
@@ -319,11 +342,11 @@ void xmrig::OclBackend::setJob(const Job &job)
} }
void xmrig::OclBackend::start(IWorker *worker) void xmrig::OclBackend::start(IWorker *worker, bool ready)
{ {
mutex.lock(); mutex.lock();
if (d_ptr->status.started()) { if (d_ptr->status.started(ready)) {
d_ptr->status.print(); d_ptr->status.print();
OclWorker::ready = true; OclWorker::ready = true;
@@ -331,7 +354,9 @@ void xmrig::OclBackend::start(IWorker *worker)
mutex.unlock(); mutex.unlock();
worker->start(); if (ready) {
worker->start();
}
} }
@@ -373,22 +398,19 @@ rapidjson::Value xmrig::OclBackend::toJSON(rapidjson::Document &doc) const
return out; return out;
} }
out.AddMember("hashrate", hashrate()->toJSON(doc), allocator);
Value threads(kArrayType); Value threads(kArrayType);
const Hashrate *hr = hashrate();
size_t i = 0; size_t i = 0;
for (const OclLaunchData &data : d_ptr->threads) { for (const OclLaunchData &data : d_ptr->threads) {
Value thread = data.thread.toJSON(doc); Value thread = data.thread.toJSON(doc);
thread.AddMember("affinity", data.affinity, allocator); thread.AddMember("affinity", data.affinity, allocator);
thread.AddMember("hashrate", hashrate()->toJSON(i, doc), allocator);
Value hashrate(kArrayType); data.device.toJSON(thread, doc);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
i++; i++;
thread.AddMember("hashrate", hashrate, allocator);
threads.PushBack(thread, allocator); threads.PushBack(thread, allocator);
} }

View File

@@ -62,7 +62,7 @@ protected:
void prepare(const Job &nextJob) override; void prepare(const Job &nextJob) override;
void printHashrate(bool details) override; void printHashrate(bool details) override;
void setJob(const Job &job) override; void setJob(const Job &job) override;
void start(IWorker *worker) override; void start(IWorker *worker, bool ready) override;
void stop() override; void stop() override;
void tick(uint64_t ticks) override; void tick(uint64_t ticks) override;

View File

@@ -30,12 +30,16 @@
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include <algorithm>
namespace xmrig { namespace xmrig {
static const char *kAMD = "AMD"; static const char *kAMD = "AMD";
static const char *kCache = "cache"; static const char *kCache = "cache";
static const char *kCn = "cn"; static const char *kCn = "cn";
static const char *kCn2 = "cn/2"; static const char *kCn2 = "cn/2";
static const char *kDevicesHint = "devices-hint";
static const char *kEnabled = "enabled"; static const char *kEnabled = "enabled";
static const char *kINTEL = "INTEL"; static const char *kINTEL = "INTEL";
static const char *kLoader = "loader"; static const char *kLoader = "loader";
@@ -90,6 +94,22 @@ static size_t generate(const char *key, Threads<OclThreads> &threads, const Algo
} }
static inline std::vector<OclDevice> filterDevices(const std::vector<OclDevice> &devices, const std::vector<uint32_t> &hints)
{
std::vector<OclDevice> out;
out.reserve(std::min(devices.size(), hints.size()));
for (const auto &device : devices) {
auto it = std::find(hints.begin(), hints.end(), device.index());
if (it != hints.end()) {
out.emplace_back(device);
}
}
return out;
}
} }
@@ -214,17 +234,20 @@ void xmrig::OclConfig::read(const rapidjson::Value &value)
m_loader = Json::getString(value, kLoader); m_loader = Json::getString(value, kLoader);
setPlatform(Json::getValue(value, kPlatform)); setPlatform(Json::getValue(value, kPlatform));
setDevicesHint(Json::getString(value, kDevicesHint));
if (isEnabled()) { m_threads.read(value);
m_threads.read(value);
generate(); generate();
}
} }
else if (value.IsBool() && value.IsFalse()) { else if (value.IsBool()) {
m_enabled = false; m_enabled = value.GetBool();
generate();
} }
else { else {
m_shouldSave = true;
generate(); generate();
} }
} }
@@ -232,11 +255,15 @@ void xmrig::OclConfig::read(const rapidjson::Value &value)
void xmrig::OclConfig::generate() void xmrig::OclConfig::generate()
{ {
if (!isEnabled() || m_threads.has("*")) {
return;
}
if (!OclLib::init(loader())) { if (!OclLib::init(loader())) {
return; return;
} }
const auto devices = platform().devices(); const auto devices = m_devicesHint.empty() ? platform().devices() : filterDevices(platform().devices(), m_devicesHint);
if (devices.empty()) { if (devices.empty()) {
return; return;
} }
@@ -281,6 +308,21 @@ void xmrig::OclConfig::generate()
} }
void xmrig::OclConfig::setDevicesHint(const char *devicesHint)
{
if (devicesHint == nullptr) {
return;
}
const auto indexes = String(devicesHint).split(',');
m_devicesHint.reserve(indexes.size());
for (const auto &index : indexes) {
m_devicesHint.push_back(strtoul(index, nullptr, 10));
}
}
void xmrig::OclConfig::setPlatform(const rapidjson::Value &platform) void xmrig::OclConfig::setPlatform(const rapidjson::Value &platform)
{ {
if (platform.IsString()) { if (platform.IsString()) {

View File

@@ -53,11 +53,13 @@ public:
private: private:
void generate(); void generate();
void setDevicesHint(const char *devicesHint);
void setPlatform(const rapidjson::Value &platform); void setPlatform(const rapidjson::Value &platform);
bool m_cache = true; bool m_cache = true;
bool m_enabled = true; bool m_enabled = false;
bool m_shouldSave = false; bool m_shouldSave = false;
std::vector<uint32_t> m_devicesHint;
String m_loader; String m_loader;
String m_platformVendor; String m_platformVendor;
Threads<OclThreads> m_threads; Threads<OclThreads> m_threads;

View File

@@ -25,6 +25,8 @@
#include "backend/opencl/OclLaunchData.h" #include "backend/opencl/OclLaunchData.h"
#include "backend/common/Tags.h"
#include "backend/opencl/OclConfig.h" #include "backend/opencl/OclConfig.h"
@@ -45,3 +47,9 @@ bool xmrig::OclLaunchData::isEqual(const OclLaunchData &other) const
return (other.algorithm == algorithm && return (other.algorithm == algorithm &&
other.thread == thread); other.thread == thread);
} }
const char *xmrig::OclLaunchData::tag()
{
return ocl_tag();
}

View File

@@ -62,6 +62,8 @@ public:
inline bool operator!=(const OclLaunchData &other) const { return !isEqual(other); } inline bool operator!=(const OclLaunchData &other) const { return !isEqual(other); }
inline bool operator==(const OclLaunchData &other) const { return isEqual(other); } inline bool operator==(const OclLaunchData &other) const { return isEqual(other); }
static const char *tag();
cl_context ctx = nullptr; cl_context ctx = nullptr;
const Algorithm algorithm; const Algorithm algorithm;
const bool cache; const bool cache;

View File

@@ -52,6 +52,10 @@ static const char* kDatasetHost = "dataset_host";
xmrig::OclThread::OclThread(const rapidjson::Value &value) xmrig::OclThread::OclThread(const rapidjson::Value &value)
{ {
if (!value.IsObject()) {
return;
}
m_index = Json::getUint(value, kIndex); m_index = Json::getUint(value, kIndex);
m_worksize = std::max(std::min(Json::getUint(value, kWorksize), 128u), 1u); m_worksize = std::max(std::min(Json::getUint(value, kWorksize), 128u), 1u);
m_unrollFactor = std::max(std::min(Json::getUint(value, kUnroll, m_unrollFactor), 128u), 1u); m_unrollFactor = std::max(std::min(Json::getUint(value, kUnroll, m_unrollFactor), 128u), 1u);

View File

@@ -137,6 +137,12 @@ bool xmrig::OclWorker::selfTest()
} }
size_t xmrig::OclWorker::intensity() const
{
return m_runner ? m_runner->intensity() : 0;
}
void xmrig::OclWorker::start() void xmrig::OclWorker::start()
{ {
cl_uint results[0x100]; cl_uint results[0x100];

View File

@@ -56,6 +56,7 @@ public:
protected: protected:
bool selfTest() override; bool selfTest() override;
size_t intensity() const override;
void start() override; void start() override;
private: private:

View File

@@ -604,7 +604,7 @@ __kernel void hashAes1Rx4(__global const void* input, __global void* hash, uint
__local const uint* const t2 = ((sub & 1) == 0) ? (T + 512) : (T + 1536); __local const uint* const t2 = ((sub & 1) == 0) ? (T + 512) : (T + 1536);
__local const uint* const t3 = ((sub & 1) == 0) ? (T + 768) : (T + 1280); __local const uint* const t3 = ((sub & 1) == 0) ? (T + 768) : (T + 1280);
#pragma unroll(8) #pragma unroll 8
for (uint i = 0; i < inputSize / sizeof(uint4); i += 4, p += 4) for (uint i = 0; i < inputSize / sizeof(uint4); i += 4, p += 4)
{ {
uint k[4], y[4]; uint k[4], y[4];

View File

@@ -72,7 +72,7 @@ __kernel void fillAes_name(__global void* state, __global void* out, uint batch_
const __local uint* const t2 = (sub & 1) ? (T + 512) : (T + 1536); const __local uint* const t2 = (sub & 1) ? (T + 512) : (T + 1536);
const __local uint* const t3 = (sub & 1) ? (T + 768) : (T + 1280); const __local uint* const t3 = (sub & 1) ? (T + 768) : (T + 1280);
#pragma unroll(unroll_factor) #pragma unroll unroll_factor
for (uint i = 0; i < outputSize / sizeof(uint4); i += 4, p += 4) for (uint i = 0; i < outputSize / sizeof(uint4); i += 4, p += 4)
{ {
uint y[4]; uint y[4];

File diff suppressed because it is too large Load Diff

View File

@@ -902,7 +902,7 @@ __global uint* generate_jit_code(__global uint2* e, __global uint2* p0, __global
{ {
int prefetch_data_count; int prefetch_data_count;
#pragma unroll(1) #pragma unroll 1
for (int pass = 0; pass < 2; ++pass) for (int pass = 0; pass < 2; ++pass)
{ {
#if RANDOMX_PROGRAM_SIZE > 256 #if RANDOMX_PROGRAM_SIZE > 256
@@ -929,7 +929,7 @@ __global uint* generate_jit_code(__global uint2* e, __global uint2* p0, __global
prefetch_data_count = 0; prefetch_data_count = 0;
#pragma unroll(1) #pragma unroll 1
for (uint i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) for (uint i = 0; i < RANDOMX_PROGRAM_SIZE; ++i)
{ {
// Clean flags // Clean flags
@@ -1314,7 +1314,7 @@ __global uint* generate_jit_code(__global uint2* e, __global uint2* p0, __global
// Sort p0 // Sort p0
uint prev = p0[0].x; uint prev = p0[0].x;
#pragma unroll(1) #pragma unroll 1
for (int j = 1; j < prefetch_data_count; ++j) for (int j = 1; j < prefetch_data_count; ++j)
{ {
uint2 cur = p0[j]; uint2 cur = p0[j];
@@ -1344,7 +1344,7 @@ __global uint* generate_jit_code(__global uint2* e, __global uint2* p0, __global
__global int* prefetched_vgprs = prefecth_vgprs_stack + num_prefetch_vgprs; __global int* prefetched_vgprs = prefecth_vgprs_stack + num_prefetch_vgprs;
#pragma unroll(8) #pragma unroll 8
for (int i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) for (int i = 0; i < RANDOMX_PROGRAM_SIZE; ++i)
prefetched_vgprs[i] = 0; prefetched_vgprs[i] = 0;
@@ -1359,7 +1359,7 @@ __global uint* generate_jit_code(__global uint2* e, __global uint2* p0, __global
const uint size_limit = (COMPILED_PROGRAM_SIZE - 200) / sizeof(uint); const uint size_limit = (COMPILED_PROGRAM_SIZE - 200) / sizeof(uint);
__global uint* start_p = p; __global uint* start_p = p;
#pragma unroll(1) #pragma unroll 1
for (int i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) for (int i = 0; i < RANDOMX_PROGRAM_SIZE; ++i)
{ {
const uint2 inst = e[i]; const uint2 inst = e[i];

View File

@@ -1658,7 +1658,7 @@ uint32_t inner_loop(
const int32_t sub2 = sub >> 1; const int32_t sub2 = sub >> 1;
imm_buf[IMM_INDEX_COUNT + 1] = fprc; imm_buf[IMM_INDEX_COUNT + 1] = fprc;
#pragma unroll(1) #pragma unroll 1
for (int32_t ip = 0; ip < program_length;) for (int32_t ip = 0; ip < program_length;)
{ {
imm_buf[IMM_INDEX_COUNT] = ip; imm_buf[IMM_INDEX_COUNT] = ip;
@@ -1934,7 +1934,7 @@ __kernel void execute_vm(__global void* vm_states, __global void* rounding, __gl
const uint32_t workers_mask = ((1 << WORKERS_PER_HASH) - 1) << ((get_local_id(0) / IDX_WIDTH) * IDX_WIDTH); const uint32_t workers_mask = ((1 << WORKERS_PER_HASH) - 1) << ((get_local_id(0) / IDX_WIDTH) * IDX_WIDTH);
const uint32_t fp_workers_mask = 3 << (((sub >> 1) << 1) + (get_local_id(0) / IDX_WIDTH) * IDX_WIDTH); const uint32_t fp_workers_mask = 3 << (((sub >> 1) << 1) + (get_local_id(0) / IDX_WIDTH) * IDX_WIDTH);
#pragma unroll(1) #pragma unroll 1
for (int ic = 0; ic < num_iterations; ++ic) for (int ic = 0; ic < num_iterations; ++ic)
{ {
__local uint64_t *r; __local uint64_t *r;

View File

@@ -45,7 +45,13 @@ static inline uint32_t getMaxThreads(const OclDevice &device, const Algorithm &a
return 40000u; return 40000u;
} }
return ((algorithm.l3() <= oneMiB) ? 2u : 1u) * 1000u; const uint32_t ratio = (algorithm.l3() <= oneMiB) ? 2u : 1u;
if (device.vendorId() == OCL_VENDOR_INTEL) {
return ratio * device.computeUnits() * 8;
}
return ratio * 1000u;
} }
@@ -107,7 +113,7 @@ bool ocl_generic_cn_generator(const OclDevice &device, const Algorithm &algorith
return false; return false;
} }
const uint32_t threadCount = ((device.globalMemSize() - intensity * 2 * algorithm.l3()) > 128 * oneMiB) ? 2 : 1; const uint32_t threadCount = (device.vendorId() == OCL_VENDOR_AMD && (device.globalMemSize() - intensity * 2 * algorithm.l3()) > 128 * oneMiB) ? 2 : 1;
threads.add(OclThread(device.index(), intensity, 8, getStridedIndex(device, algorithm), 2, threadCount, 8)); threads.add(OclThread(device.index(), intensity, 8, getStridedIndex(device, algorithm), 2, threadCount, 8));

View File

@@ -86,7 +86,7 @@ bool ocl_generic_rx_generator(const OclDevice &device, const Algorithm &algorith
return false; return false;
} }
threads.add(OclThread(device.index(), intensity, 8, 2, gcnAsm, datasetHost, 6)); threads.add(OclThread(device.index(), intensity, 8, device.vendorId() == OCL_VENDOR_AMD ? 2 : 1, gcnAsm, datasetHost, 6));
return true; return true;
} }

View File

@@ -51,18 +51,19 @@ public:
IOclRunner() = default; IOclRunner() = default;
virtual ~IOclRunner() = default; virtual ~IOclRunner() = default;
virtual void run(uint32_t nonce, uint32_t *hashOutput) = 0;
virtual void set(const Job &job, uint8_t *blob) = 0;
virtual cl_context ctx() const = 0; virtual cl_context ctx() const = 0;
virtual const Algorithm &algorithm() const = 0; virtual const Algorithm &algorithm() const = 0;
virtual const char *buildOptions() const = 0; virtual const char *buildOptions() const = 0;
virtual const char *deviceKey() const = 0; virtual const char *deviceKey() const = 0;
virtual const char *source() const = 0; virtual const char *source() const = 0;
virtual const OclLaunchData &data() const = 0; virtual const OclLaunchData &data() const = 0;
virtual size_t intensity() const = 0;
virtual size_t threadId() const = 0; virtual size_t threadId() const = 0;
virtual uint32_t deviceIndex() const = 0; virtual uint32_t deviceIndex() const = 0;
virtual void build() = 0; virtual void build() = 0;
virtual void init() = 0; virtual void init() = 0;
virtual void run(uint32_t nonce, uint32_t *hashOutput) = 0;
virtual void set(const Job &job, uint8_t *blob) = 0;
protected: protected:
virtual size_t bufferSize() const = 0; virtual size_t bufferSize() const = 0;

View File

@@ -40,7 +40,8 @@ xmrig::OclBaseRunner::OclBaseRunner(size_t id, const OclLaunchData &data) :
m_source(OclSource::get(data.algorithm)), m_source(OclSource::get(data.algorithm)),
m_data(data), m_data(data),
m_align(OclLib::getUint(data.device.id(), CL_DEVICE_MEM_BASE_ADDR_ALIGN)), m_align(OclLib::getUint(data.device.id(), CL_DEVICE_MEM_BASE_ADDR_ALIGN)),
m_threadId(id) m_threadId(id),
m_intensity(data.thread.intensity())
{ {
m_deviceKey = data.device.name(); m_deviceKey = data.device.name();
@@ -97,7 +98,7 @@ void xmrig::OclBaseRunner::init()
constexpr size_t oneGiB = 1024 * 1024 * 1024; constexpr size_t oneGiB = 1024 * 1024 * 1024;
size_t size = bufferSize(); size_t size = bufferSize();
if (size < oneGiB && data().device.freeMemSize() >= oneGiB) { if (size < oneGiB && data().device.vendorId() == OCL_VENDOR_AMD && data().device.freeMemSize() >= oneGiB) {
size = oneGiB; size = oneGiB;
} }

View File

@@ -55,6 +55,7 @@ protected:
inline const char *deviceKey() const override { return m_deviceKey.c_str(); } inline const char *deviceKey() const override { return m_deviceKey.c_str(); }
inline const char *source() const override { return m_source; } inline const char *source() const override { return m_source; }
inline const OclLaunchData &data() const override { return m_data; } inline const OclLaunchData &data() const override { return m_data; }
inline size_t intensity() const override { return m_intensity; }
inline size_t threadId() const override { return m_threadId; } inline size_t threadId() const override { return m_threadId; }
size_t bufferSize() const override; size_t bufferSize() const override;
@@ -83,6 +84,7 @@ protected:
size_t m_offset = 0; size_t m_offset = 0;
std::string m_deviceKey; std::string m_deviceKey;
std::string m_options; std::string m_options;
uint32_t m_intensity;
}; };

View File

@@ -83,12 +83,10 @@ xmrig::OclCnRunner::~OclCnRunner()
size_t xmrig::OclCnRunner::bufferSize() const size_t xmrig::OclCnRunner::bufferSize() const
{ {
const size_t g_thd = data().thread.intensity();
return OclBaseRunner::bufferSize() + return OclBaseRunner::bufferSize() +
align(m_algorithm.l3() * g_thd) + align(m_algorithm.l3() * m_intensity) +
align(200 * g_thd) + align(200 * m_intensity) +
(align(sizeof(cl_uint) * (g_thd + 2)) * BRANCH_MAX); (align(sizeof(cl_uint) * (m_intensity + 2)) * BRANCH_MAX);
} }
@@ -96,14 +94,13 @@ void xmrig::OclCnRunner::run(uint32_t nonce, uint32_t *hashOutput)
{ {
static const cl_uint zero = 0; static const cl_uint zero = 0;
const size_t g_intensity = data().thread.intensity(); const size_t w_size = data().thread.worksize();
const size_t w_size = data().thread.worksize(); const size_t g_thd = ((m_intensity + w_size - 1u) / w_size) * w_size;
const size_t g_thd = ((g_intensity + w_size - 1u) / w_size) * w_size;
assert(g_thd % w_size == 0); assert(g_thd % w_size == 0);
for (size_t i = 0; i < BRANCH_MAX; ++i) { for (size_t i = 0; i < BRANCH_MAX; ++i) {
enqueueWriteBuffer(m_branches[i], CL_FALSE, sizeof(cl_uint) * g_intensity, sizeof(cl_uint), &zero); enqueueWriteBuffer(m_branches[i], CL_FALSE, sizeof(cl_uint) * m_intensity, sizeof(cl_uint), &zero);
} }
enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(cl_uint), &zero); enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(cl_uint), &zero);
@@ -134,10 +131,15 @@ void xmrig::OclCnRunner::set(const Job &job, uint8_t *blob)
if (m_algorithm == Algorithm::CN_R && m_height != job.height()) { if (m_algorithm == Algorithm::CN_R && m_height != job.height()) {
delete m_cn1; delete m_cn1;
m_height = job.height(); m_height = job.height();
m_cnr = OclCnR::get(*this, m_height); auto program = OclCnR::get(*this, m_height);
m_cn1 = new Cn1Kernel(m_cnr, m_height); m_cn1 = new Cn1Kernel(program, m_height);
m_cn1->setArgs(m_input, m_scratchpads, m_states, data().thread.intensity()); m_cn1->setArgs(m_input, m_scratchpads, m_states, m_intensity);
if (m_cnr != program) {
OclLib::release(m_cnr);
m_cnr = OclLib::retain(program);
}
} }
for (auto kernel : m_branchKernels) { for (auto kernel : m_branchKernels) {
@@ -150,22 +152,20 @@ void xmrig::OclCnRunner::build()
{ {
OclBaseRunner::build(); OclBaseRunner::build();
const uint32_t intensity = data().thread.intensity();
m_cn0 = new Cn0Kernel(m_program); m_cn0 = new Cn0Kernel(m_program);
m_cn0->setArgs(m_input, m_scratchpads, m_states, intensity); m_cn0->setArgs(m_input, m_scratchpads, m_states, m_intensity);
m_cn2 = new Cn2Kernel(m_program); m_cn2 = new Cn2Kernel(m_program);
m_cn2->setArgs(m_scratchpads, m_states, m_branches, intensity); m_cn2->setArgs(m_scratchpads, m_states, m_branches, m_intensity);
if (m_algorithm != Algorithm::CN_R) { if (m_algorithm != Algorithm::CN_R) {
m_cn1 = new Cn1Kernel(m_program); m_cn1 = new Cn1Kernel(m_program);
m_cn1->setArgs(m_input, m_scratchpads, m_states, intensity); m_cn1->setArgs(m_input, m_scratchpads, m_states, m_intensity);
} }
for (size_t i = 0; i < BRANCH_MAX; ++i) { for (size_t i = 0; i < BRANCH_MAX; ++i) {
auto kernel = new CnBranchKernel(i, m_program); auto kernel = new CnBranchKernel(i, m_program);
kernel->setArgs(m_states, m_branches[i], m_output, intensity); kernel->setArgs(m_states, m_branches[i], m_output, m_intensity);
m_branchKernels[i] = kernel; m_branchKernels[i] = kernel;
} }
@@ -176,12 +176,10 @@ void xmrig::OclCnRunner::init()
{ {
OclBaseRunner::init(); OclBaseRunner::init();
const size_t g_thd = data().thread.intensity(); m_scratchpads = createSubBuffer(CL_MEM_READ_WRITE, m_algorithm.l3() * m_intensity);
m_states = createSubBuffer(CL_MEM_READ_WRITE, 200 * m_intensity);
m_scratchpads = createSubBuffer(CL_MEM_READ_WRITE, m_algorithm.l3() * g_thd);
m_states = createSubBuffer(CL_MEM_READ_WRITE, 200 * g_thd);
for (size_t i = 0; i < BRANCH_MAX; ++i) { for (size_t i = 0; i < BRANCH_MAX; ++i) {
m_branches[i] = createSubBuffer(CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2)); m_branches[i] = createSubBuffer(CL_MEM_READ_WRITE, sizeof(cl_uint) * (m_intensity + 2));
} }
} }

View File

@@ -87,28 +87,26 @@ void xmrig::OclRxBaseRunner::run(uint32_t nonce, uint32_t *hashOutput)
enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(uint32_t), &zero); enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(uint32_t), &zero);
const uint32_t g_intensity = data().thread.intensity(); m_blake2b_initial_hash->enqueue(m_queue, m_intensity);
m_fillAes1Rx4_scratchpad->enqueue(m_queue, m_intensity);
m_blake2b_initial_hash->enqueue(m_queue, g_intensity);
m_fillAes1Rx4_scratchpad->enqueue(m_queue, g_intensity);
const uint32_t programCount = RxAlgo::programCount(m_algorithm); const uint32_t programCount = RxAlgo::programCount(m_algorithm);
for (uint32_t i = 0; i < programCount; ++i) { for (uint32_t i = 0; i < programCount; ++i) {
m_fillAes4Rx4_entropy->enqueue(m_queue, g_intensity); m_fillAes4Rx4_entropy->enqueue(m_queue, m_intensity);
execute(i); execute(i);
if (i == programCount - 1) { if (i == programCount - 1) {
m_hashAes1Rx4->enqueue(m_queue, g_intensity); m_hashAes1Rx4->enqueue(m_queue, m_intensity);
m_blake2b_hash_registers_32->enqueue(m_queue, g_intensity); m_blake2b_hash_registers_32->enqueue(m_queue, m_intensity);
} }
else { else {
m_blake2b_hash_registers_64->enqueue(m_queue, g_intensity); m_blake2b_hash_registers_64->enqueue(m_queue, m_intensity);
} }
} }
m_find_shares->enqueue(m_queue, g_intensity); m_find_shares->enqueue(m_queue, m_intensity);
finalize(hashOutput); finalize(hashOutput);
@@ -138,13 +136,11 @@ void xmrig::OclRxBaseRunner::set(const Job &job, uint8_t *blob)
size_t xmrig::OclRxBaseRunner::bufferSize() const size_t xmrig::OclRxBaseRunner::bufferSize() const
{ {
const size_t g_thd = data().thread.intensity();
return OclBaseRunner::bufferSize() + return OclBaseRunner::bufferSize() +
align((m_algorithm.l3() + 64) * g_thd) + align((m_algorithm.l3() + 64) * m_intensity) +
align(64 * g_thd) + align(64 * m_intensity) +
align((128 + 2560) * g_thd) + align((128 + 2560) * m_intensity) +
align(sizeof(uint32_t) * g_thd); align(sizeof(uint32_t) * m_intensity);
} }
@@ -152,14 +148,13 @@ void xmrig::OclRxBaseRunner::build()
{ {
OclBaseRunner::build(); OclBaseRunner::build();
const uint32_t batch_size = data().thread.intensity();
const uint32_t rx_version = RxAlgo::version(m_algorithm); const uint32_t rx_version = RxAlgo::version(m_algorithm);
m_fillAes1Rx4_scratchpad = new FillAesKernel(m_program, "fillAes1Rx4_scratchpad"); m_fillAes1Rx4_scratchpad = new FillAesKernel(m_program, "fillAes1Rx4_scratchpad");
m_fillAes1Rx4_scratchpad->setArgs(m_hashes, m_scratchpads, batch_size, rx_version); m_fillAes1Rx4_scratchpad->setArgs(m_hashes, m_scratchpads, m_intensity, rx_version);
m_fillAes4Rx4_entropy = new FillAesKernel(m_program, "fillAes4Rx4_entropy"); m_fillAes4Rx4_entropy = new FillAesKernel(m_program, "fillAes4Rx4_entropy");
m_fillAes4Rx4_entropy->setArgs(m_hashes, m_entropy, batch_size, rx_version); m_fillAes4Rx4_entropy->setArgs(m_hashes, m_entropy, m_intensity, rx_version);
m_hashAes1Rx4 = new HashAesKernel(m_program); m_hashAes1Rx4 = new HashAesKernel(m_program);
@@ -178,10 +173,8 @@ void xmrig::OclRxBaseRunner::init()
{ {
OclBaseRunner::init(); OclBaseRunner::init();
const size_t g_thd = data().thread.intensity(); m_scratchpads = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, (m_algorithm.l3() + 64) * m_intensity);
m_hashes = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 64 * m_intensity);
m_scratchpads = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, (m_algorithm.l3() + 64) * g_thd); m_entropy = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, (128 + 2560) * m_intensity);
m_hashes = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 64 * g_thd); m_rounding = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, sizeof(uint32_t) * m_intensity);
m_entropy = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, (128 + 2560) * g_thd);
m_rounding = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, sizeof(uint32_t) * g_thd);
} }

View File

@@ -54,9 +54,7 @@ xmrig::OclRxJitRunner::~OclRxJitRunner()
size_t xmrig::OclRxJitRunner::bufferSize() const size_t xmrig::OclRxJitRunner::bufferSize() const
{ {
const size_t g_thd = data().thread.intensity(); return OclRxBaseRunner::bufferSize() + align(256 * m_intensity) + align(5120 * m_intensity) + align(10048 * m_intensity);
return OclRxBaseRunner::bufferSize() + align(256 * g_thd) + align(5120 * g_thd) + align(10048 * g_thd);
} }
@@ -64,33 +62,29 @@ void xmrig::OclRxJitRunner::build()
{ {
OclRxBaseRunner::build(); OclRxBaseRunner::build();
const uint32_t batch_size = data().thread.intensity(); m_hashAes1Rx4->setArgs(m_scratchpads, m_registers, 256, m_intensity);
m_hashAes1Rx4->setArgs(m_scratchpads, m_registers, 256, batch_size);
m_blake2b_hash_registers_32->setArgs(m_hashes, m_registers, 256); m_blake2b_hash_registers_32->setArgs(m_hashes, m_registers, 256);
m_blake2b_hash_registers_64->setArgs(m_hashes, m_registers, 256); m_blake2b_hash_registers_64->setArgs(m_hashes, m_registers, 256);
m_randomx_jit = new RxJitKernel(m_program); m_randomx_jit = new RxJitKernel(m_program);
m_randomx_jit->setArgs(m_entropy, m_registers, m_intermediate_programs, m_programs, batch_size, m_rounding); m_randomx_jit->setArgs(m_entropy, m_registers, m_intermediate_programs, m_programs, m_intensity, m_rounding);
if (!loadAsmProgram()) { if (!loadAsmProgram()) {
throw std::runtime_error(OclError::toString(CL_INVALID_PROGRAM)); throw std::runtime_error(OclError::toString(CL_INVALID_PROGRAM));
} }
m_randomx_run = new RxRunKernel(m_asmProgram); m_randomx_run = new RxRunKernel(m_asmProgram);
m_randomx_run->setArgs(data().dataset->get(), m_scratchpads, m_registers, m_rounding, m_programs, batch_size, m_algorithm); m_randomx_run->setArgs(data().dataset->get(), m_scratchpads, m_registers, m_rounding, m_programs, m_intensity, m_algorithm);
} }
void xmrig::OclRxJitRunner::execute(uint32_t iteration) void xmrig::OclRxJitRunner::execute(uint32_t iteration)
{ {
const uint32_t g_intensity = data().thread.intensity(); m_randomx_jit->enqueue(m_queue, m_intensity, iteration);
m_randomx_jit->enqueue(m_queue, g_intensity, iteration);
OclLib::finish(m_queue); OclLib::finish(m_queue);
m_randomx_run->enqueue(m_queue, g_intensity); m_randomx_run->enqueue(m_queue, m_intensity);
} }
@@ -98,11 +92,9 @@ void xmrig::OclRxJitRunner::init()
{ {
OclRxBaseRunner::init(); OclRxBaseRunner::init();
const size_t g_thd = data().thread.intensity(); m_registers = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 256 * m_intensity);
m_intermediate_programs = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 5120 * m_intensity);
m_registers = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 256 * g_thd); m_programs = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 10048 * m_intensity);
m_intermediate_programs = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 5120 * g_thd);
m_programs = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 10048 * g_thd);
} }

View File

@@ -52,7 +52,7 @@ xmrig::OclRxVmRunner::~OclRxVmRunner()
size_t xmrig::OclRxVmRunner::bufferSize() const size_t xmrig::OclRxVmRunner::bufferSize() const
{ {
return OclRxBaseRunner::bufferSize() + (align(2560 * data().thread.intensity())); return OclRxBaseRunner::bufferSize() + (align(2560 * m_intensity));
} }
@@ -60,10 +60,9 @@ void xmrig::OclRxVmRunner::build()
{ {
OclRxBaseRunner::build(); OclRxBaseRunner::build();
const uint32_t batch_size = data().thread.intensity(); const uint32_t hashStrideBytes = RxAlgo::programSize(m_algorithm) * 8;
const uint32_t hashStrideBytes = RxAlgo::programSize(m_algorithm) * 8;
m_hashAes1Rx4->setArgs(m_scratchpads, m_vm_states, hashStrideBytes, batch_size); m_hashAes1Rx4->setArgs(m_scratchpads, m_vm_states, hashStrideBytes, m_intensity);
m_blake2b_hash_registers_32->setArgs(m_hashes, m_vm_states, hashStrideBytes); m_blake2b_hash_registers_32->setArgs(m_hashes, m_vm_states, hashStrideBytes);
m_blake2b_hash_registers_64->setArgs(m_hashes, m_vm_states, hashStrideBytes); m_blake2b_hash_registers_64->setArgs(m_hashes, m_vm_states, hashStrideBytes);
@@ -71,7 +70,7 @@ void xmrig::OclRxVmRunner::build()
m_init_vm->setArgs(m_entropy, m_vm_states, m_rounding); m_init_vm->setArgs(m_entropy, m_vm_states, m_rounding);
m_execute_vm = new ExecuteVmKernel(m_program); m_execute_vm = new ExecuteVmKernel(m_program);
m_execute_vm->setArgs(m_vm_states, m_rounding, m_scratchpads, data().dataset->get(), batch_size); m_execute_vm->setArgs(m_vm_states, m_rounding, m_scratchpads, data().dataset->get(), m_intensity);
} }
@@ -79,9 +78,8 @@ void xmrig::OclRxVmRunner::execute(uint32_t iteration)
{ {
const uint32_t bfactor = std::min(data().thread.bfactor(), 8u); const uint32_t bfactor = std::min(data().thread.bfactor(), 8u);
const uint32_t num_iterations = RxAlgo::programIterations(m_algorithm) >> bfactor; const uint32_t num_iterations = RxAlgo::programIterations(m_algorithm) >> bfactor;
const uint32_t g_intensity = data().thread.intensity();
m_init_vm->enqueue(m_queue, g_intensity, iteration); m_init_vm->enqueue(m_queue, m_intensity, iteration);
m_execute_vm->setIterations(num_iterations); m_execute_vm->setIterations(num_iterations);
@@ -90,7 +88,7 @@ void xmrig::OclRxVmRunner::execute(uint32_t iteration)
m_execute_vm->setLast(1); m_execute_vm->setLast(1);
} }
m_execute_vm->enqueue(m_queue, g_intensity, m_worksize); m_execute_vm->enqueue(m_queue, m_intensity, m_worksize);
if (j == 0) { if (j == 0) {
m_execute_vm->setFirst(0); m_execute_vm->setFirst(0);
@@ -103,5 +101,5 @@ void xmrig::OclRxVmRunner::init()
{ {
OclRxBaseRunner::init(); OclRxBaseRunner::init();
m_vm_states = createSubBuffer(CL_MEM_READ_WRITE, 2560 * data().thread.intensity()); m_vm_states = createSubBuffer(CL_MEM_READ_WRITE, 2560 * m_intensity);
} }

View File

@@ -63,9 +63,7 @@ xmrig::OclRyoRunner::~OclRyoRunner()
size_t xmrig::OclRyoRunner::bufferSize() const size_t xmrig::OclRyoRunner::bufferSize() const
{ {
const size_t g_thd = data().thread.intensity(); return OclBaseRunner::bufferSize() + align(data().algorithm.l3() * m_intensity) + align(200 * m_intensity);
return OclBaseRunner::bufferSize() + align(data().algorithm.l3() * g_thd) + align(200 * g_thd);
} }
@@ -73,9 +71,8 @@ void xmrig::OclRyoRunner::run(uint32_t nonce, uint32_t *hashOutput)
{ {
static const cl_uint zero = 0; static const cl_uint zero = 0;
const size_t g_intensity = data().thread.intensity(); const size_t w_size = data().thread.worksize();
const size_t w_size = data().thread.worksize(); const size_t g_thd = ((m_intensity + w_size - 1u) / w_size) * w_size;
const size_t g_thd = ((g_intensity + w_size - 1u) / w_size) * w_size;
assert(g_thd % w_size == 0); assert(g_thd % w_size == 0);
@@ -109,19 +106,17 @@ void xmrig::OclRyoRunner::build()
{ {
OclBaseRunner::build(); OclBaseRunner::build();
const uint32_t intensity = data().thread.intensity();
m_cn00 = new Cn00RyoKernel(m_program); m_cn00 = new Cn00RyoKernel(m_program);
m_cn00->setArgs(m_scratchpads, m_states); m_cn00->setArgs(m_scratchpads, m_states);
m_cn0 = new Cn0Kernel(m_program); m_cn0 = new Cn0Kernel(m_program);
m_cn0->setArgs(m_input, m_scratchpads, m_states, intensity); m_cn0->setArgs(m_input, m_scratchpads, m_states, m_intensity);
m_cn1 = new Cn1RyoKernel(m_program); m_cn1 = new Cn1RyoKernel(m_program);
m_cn1->setArgs(m_scratchpads, m_states, intensity); m_cn1->setArgs(m_scratchpads, m_states, m_intensity);
m_cn2 = new Cn2RyoKernel(m_program); m_cn2 = new Cn2RyoKernel(m_program);
m_cn2->setArgs(m_scratchpads, m_states, m_output, intensity); m_cn2->setArgs(m_scratchpads, m_states, m_output, m_intensity);
} }
@@ -129,8 +124,6 @@ void xmrig::OclRyoRunner::init()
{ {
OclBaseRunner::init(); OclBaseRunner::init();
const size_t g_thd = data().thread.intensity(); m_scratchpads = createSubBuffer(CL_MEM_READ_WRITE, data().algorithm.l3() * m_intensity);
m_states = createSubBuffer(CL_MEM_READ_WRITE, 200 * m_intensity);
m_scratchpads = createSubBuffer(CL_MEM_READ_WRITE, data().algorithm.l3() * g_thd);
m_states = createSubBuffer(CL_MEM_READ_WRITE, 200 * g_thd);
} }

View File

@@ -237,7 +237,7 @@ private:
for (size_t i = 0; i < OclCnR::kHeightChunkSize; ++i) { for (size_t i = 0; i < OclCnR::kHeightChunkSize; ++i) {
V4_Instruction code[256]; V4_Instruction code[256];
const int code_size = v4_random_math_init<Algorithm::CN_R>(code, offset + i); const int code_size = v4_random_math_init<Algorithm::CN_R>(code, offset + i);
const std::string kernel = std::regex_replace(cryptonight_r_cl, std::regex("XMRIG_INCLUDE_RANDOM_MATH"), getCode(code, code_size)); const std::string kernel = std::regex_replace(std::string(cryptonight_r_cl), std::regex("XMRIG_INCLUDE_RANDOM_MATH"), getCode(code, code_size));
source += std::regex_replace(kernel, std::regex("KERNEL_NAME"), "cn1_" + std::to_string(offset + i)); source += std::regex_replace(kernel, std::regex("KERNEL_NAME"), "cn1_" + std::to_string(offset + i));
} }

View File

@@ -59,7 +59,7 @@ extern bool ocl_vega_cn_generator(const OclDevice &device, const Algorithm &algo
extern bool ocl_generic_cn_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads); extern bool ocl_generic_cn_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads);
ocl_gen_config_fun generators[] = { static ocl_gen_config_fun generators[] = {
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
ocl_generic_rx_generator, ocl_generic_rx_generator,
# endif # endif
@@ -142,16 +142,14 @@ xmrig::OclDevice::OclDevice(uint32_t index, cl_device_id id, cl_platform_id plat
topology_amd topology; topology_amd topology;
if (OclLib::getDeviceInfo(id, 0x4037 /* CL_DEVICE_TOPOLOGY_AMD */, sizeof(topology), &topology, nullptr) == CL_SUCCESS && topology.raw.type == 1) { if (OclLib::getDeviceInfo(id, 0x4037 /* CL_DEVICE_TOPOLOGY_AMD */, sizeof(topology), &topology, nullptr) == CL_SUCCESS && topology.raw.type == 1) {
m_topology = true; m_topology = PciTopology(static_cast<uint32_t>(topology.pcie.bus), static_cast<uint32_t>(topology.pcie.device), static_cast<uint32_t>(topology.pcie.function));
m_pciTopology = PciTopology(static_cast<uint32_t>(topology.pcie.bus), static_cast<uint32_t>(topology.pcie.device), static_cast<uint32_t>(topology.pcie.function));
} }
} }
else if (m_vendorId == OCL_VENDOR_NVIDIA) { else if (m_vendorId == OCL_VENDOR_NVIDIA) {
cl_uint bus = 0; cl_uint bus = 0;
if (OclLib::getDeviceInfo(id, 0x4008 /* CL_DEVICE_PCI_BUS_ID_NV */, sizeof (bus), &bus, nullptr) == CL_SUCCESS) { if (OclLib::getDeviceInfo(id, 0x4008 /* CL_DEVICE_PCI_BUS_ID_NV */, sizeof (bus), &bus, nullptr) == CL_SUCCESS) {
m_topology = true;
cl_uint slot = OclLib::getUint(id, 0x4009 /* CL_DEVICE_PCI_SLOT_ID_NV */); cl_uint slot = OclLib::getUint(id, 0x4009 /* CL_DEVICE_PCI_SLOT_ID_NV */);
m_pciTopology = PciTopology(bus, (slot >> 3) & 0xff, slot & 7); m_topology = PciTopology(bus, (slot >> 3) & 0xff, slot & 7);
} }
} }
} }
@@ -205,3 +203,18 @@ void xmrig::OclDevice::generate(const Algorithm &algorithm, OclThreads &threads)
} }
} }
} }
#ifdef XMRIG_FEATURE_API
void xmrig::OclDevice::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
out.AddMember("board", board().toJSON(doc), allocator);
out.AddMember("name", name().toJSON(doc), allocator);
out.AddMember("bus_id", topology().toString().toJSON(doc), allocator);
out.AddMember("cu", computeUnits(), allocator);
out.AddMember("global_mem", static_cast<uint64_t>(globalMemSize()), allocator);
}
#endif

View File

@@ -69,10 +69,9 @@ public:
uint32_t clock() const; uint32_t clock() const;
void generate(const Algorithm &algorithm, OclThreads &threads) const; void generate(const Algorithm &algorithm, OclThreads &threads) const;
inline bool hasTopology() const { return m_topology; }
inline bool isValid() const { return m_id != nullptr && m_platform != nullptr; } inline bool isValid() const { return m_id != nullptr && m_platform != nullptr; }
inline cl_device_id id() const { return m_id; } inline cl_device_id id() const { return m_id; }
inline const PciTopology &topology() const { return m_pciTopology; } inline const PciTopology &topology() const { return m_topology; }
inline const String &board() const { return m_board.isNull() ? m_name : m_board; } inline const String &board() const { return m_board.isNull() ? m_name : m_board; }
inline const String &name() const { return m_name; } inline const String &name() const { return m_name; }
inline const String &vendor() const { return m_vendor; } inline const String &vendor() const { return m_vendor; }
@@ -81,8 +80,11 @@ public:
inline uint32_t computeUnits() const { return m_computeUnits; } inline uint32_t computeUnits() const { return m_computeUnits; }
inline uint32_t index() const { return m_index; } inline uint32_t index() const { return m_index; }
# ifdef XMRIG_FEATURE_API
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
# endif
private: private:
bool m_topology = false;
cl_device_id m_id = nullptr; cl_device_id m_id = nullptr;
cl_platform_id m_platform = nullptr; cl_platform_id m_platform = nullptr;
const String m_board; const String m_board;
@@ -91,7 +93,7 @@ private:
const uint32_t m_computeUnits = 1; const uint32_t m_computeUnits = 1;
const uint32_t m_index = 0; const uint32_t m_index = 0;
OclVendor m_vendorId = OCL_VENDOR_UNKNOWN; OclVendor m_vendorId = OCL_VENDOR_UNKNOWN;
PciTopology m_pciTopology; PciTopology m_topology;
Type m_type = Unknown; Type m_type = Unknown;
}; };

View File

@@ -73,6 +73,7 @@ static const char *kReleaseDevice = "clReleaseDevice";
static const char *kReleaseKernel = "clReleaseKernel"; static const char *kReleaseKernel = "clReleaseKernel";
static const char *kReleaseMemObject = "clReleaseMemObject"; static const char *kReleaseMemObject = "clReleaseMemObject";
static const char *kReleaseProgram = "clReleaseProgram"; static const char *kReleaseProgram = "clReleaseProgram";
static const char *kRetainProgram = "clRetainProgram";
static const char *kSetKernelArg = "clSetKernelArg"; static const char *kSetKernelArg = "clSetKernelArg";
static const char *kSetMemObjectDestructorCallback = "clSetMemObjectDestructorCallback"; static const char *kSetMemObjectDestructorCallback = "clSetMemObjectDestructorCallback";
static const char *kUnloadPlatformCompiler = "clUnloadPlatformCompiler"; static const char *kUnloadPlatformCompiler = "clUnloadPlatformCompiler";
@@ -105,6 +106,7 @@ typedef cl_int (CL_API_CALL *releaseDevice_t)(cl_device_id device);
typedef cl_int (CL_API_CALL *releaseKernel_t)(cl_kernel); typedef cl_int (CL_API_CALL *releaseKernel_t)(cl_kernel);
typedef cl_int (CL_API_CALL *releaseMemObject_t)(cl_mem); typedef cl_int (CL_API_CALL *releaseMemObject_t)(cl_mem);
typedef cl_int (CL_API_CALL *releaseProgram_t)(cl_program); typedef cl_int (CL_API_CALL *releaseProgram_t)(cl_program);
typedef cl_int (CL_API_CALL *retainProgram_t)(cl_program);
typedef cl_int (CL_API_CALL *setKernelArg_t)(cl_kernel, cl_uint, size_t, const void *); typedef cl_int (CL_API_CALL *setKernelArg_t)(cl_kernel, cl_uint, size_t, const void *);
typedef cl_int (CL_API_CALL *setMemObjectDestructorCallback_t)(cl_mem, void (CL_CALLBACK *)(cl_mem, void *), void *); typedef cl_int (CL_API_CALL *setMemObjectDestructorCallback_t)(cl_mem, void (CL_CALLBACK *)(cl_mem, void *), void *);
typedef cl_int (CL_API_CALL *unloadPlatformCompiler_t)(cl_platform_id); typedef cl_int (CL_API_CALL *unloadPlatformCompiler_t)(cl_platform_id);
@@ -146,6 +148,7 @@ static releaseDevice_t pReleaseDevice = nu
static releaseKernel_t pReleaseKernel = nullptr; static releaseKernel_t pReleaseKernel = nullptr;
static releaseMemObject_t pReleaseMemObject = nullptr; static releaseMemObject_t pReleaseMemObject = nullptr;
static releaseProgram_t pReleaseProgram = nullptr; static releaseProgram_t pReleaseProgram = nullptr;
static retainProgram_t pRetainProgram = nullptr;
static setKernelArg_t pSetKernelArg = nullptr; static setKernelArg_t pSetKernelArg = nullptr;
static setMemObjectDestructorCallback_t pSetMemObjectDestructorCallback = nullptr; static setMemObjectDestructorCallback_t pSetMemObjectDestructorCallback = nullptr;
static unloadPlatformCompiler_t pUnloadPlatformCompiler = nullptr; static unloadPlatformCompiler_t pUnloadPlatformCompiler = nullptr;
@@ -235,6 +238,7 @@ bool xmrig::OclLib::load()
DLSYM(UnloadPlatformCompiler); DLSYM(UnloadPlatformCompiler);
DLSYM(SetMemObjectDestructorCallback); DLSYM(SetMemObjectDestructorCallback);
DLSYM(CreateSubBuffer); DLSYM(CreateSubBuffer);
DLSYM(RetainProgram);
# if defined(CL_VERSION_2_0) # if defined(CL_VERSION_2_0)
uv_dlsym(&oclLib, kCreateCommandQueueWithProperties, reinterpret_cast<void**>(&pCreateCommandQueueWithProperties)); uv_dlsym(&oclLib, kCreateCommandQueueWithProperties, reinterpret_cast<void**>(&pCreateCommandQueueWithProperties));
@@ -696,6 +700,18 @@ cl_program xmrig::OclLib::createProgramWithSource(cl_context context, cl_uint co
} }
cl_program xmrig::OclLib::retain(cl_program program) noexcept
{
assert(pRetainProgram != nullptr);
if (program != nullptr) {
pRetainProgram(program);
}
return program;
}
cl_uint xmrig::OclLib::getNumPlatforms() noexcept cl_uint xmrig::OclLib::getNumPlatforms() noexcept
{ {
cl_uint count = 0; cl_uint count = 0;

View File

@@ -81,6 +81,7 @@ public:
static cl_mem createSubBuffer(cl_mem buffer, cl_mem_flags flags, size_t offset, size_t size); static cl_mem createSubBuffer(cl_mem buffer, cl_mem_flags flags, size_t offset, size_t size);
static cl_program createProgramWithBinary(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const size_t *lengths, const unsigned char **binaries, cl_int *binary_status, cl_int *errcode_ret) noexcept; static cl_program createProgramWithBinary(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const size_t *lengths, const unsigned char **binaries, cl_int *binary_status, cl_int *errcode_ret) noexcept;
static cl_program createProgramWithSource(cl_context context, cl_uint count, const char **strings, const size_t *lengths, cl_int *errcode_ret) noexcept; static cl_program createProgramWithSource(cl_context context, cl_uint count, const char **strings, const size_t *lengths, cl_int *errcode_ret) noexcept;
static cl_program retain(cl_program program) noexcept;
static cl_uint getNumPlatforms() noexcept; static cl_uint getNumPlatforms() noexcept;
static cl_uint getUint(cl_command_queue command_queue, cl_command_queue_info param_name, cl_uint defaultValue = 0) noexcept; static cl_uint getUint(cl_command_queue command_queue, cl_command_queue_info param_name, cl_uint defaultValue = 0) noexcept;
static cl_uint getUint(cl_context context, cl_context_info param_name, cl_uint defaultValue = 0) noexcept; static cl_uint getUint(cl_context context, cl_context_info param_name, cl_uint defaultValue = 0) noexcept;

View File

@@ -73,7 +73,7 @@ rapidjson::Value xmrig::OclPlatform::toJSON(rapidjson::Document &doc) const
} }
Value out(kObjectType); Value out(kObjectType);
out.AddMember("index", index(), allocator); out.AddMember("index", static_cast<uint64_t>(index()), allocator);
out.AddMember("profile", profile().toJSON(doc), allocator); out.AddMember("profile", profile().toJSON(doc), allocator);
out.AddMember("version", version().toJSON(doc), allocator); out.AddMember("version", version().toJSON(doc), allocator);
out.AddMember("name", name().toJSON(doc), allocator); out.AddMember("name", name().toJSON(doc), allocator);

View File

@@ -117,9 +117,10 @@ void xmrig::Api::exec(IApiRequest &request)
auto &allocator = request.doc().GetAllocator(); auto &allocator = request.doc().GetAllocator();
request.accept(); request.accept();
request.reply().AddMember("id", StringRef(m_id), allocator); request.reply().AddMember("id", StringRef(m_id), allocator);
request.reply().AddMember("worker_id", StringRef(m_workerId), allocator); request.reply().AddMember("worker_id", StringRef(m_workerId), allocator);
request.reply().AddMember("uptime", (Chrono::currentMSecsSinceEpoch() - m_timestamp) / 1000, allocator); request.reply().AddMember("uptime", (Chrono::currentMSecsSinceEpoch() - m_timestamp) / 1000, allocator);
request.reply().AddMember("restricted", request.isRestricted(), allocator);
Value features(kArrayType); Value features(kArrayType);
# ifdef XMRIG_FEATURE_API # ifdef XMRIG_FEATURE_API

View File

@@ -27,10 +27,11 @@
#include <vector> #include <vector>
#include <stdint.h> #include <cstdint>
#include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/IBaseListener.h"
#include "base/tools/Object.h"
namespace xmrig { namespace xmrig {
@@ -47,6 +48,8 @@ class String;
class Api : public IBaseListener class Api : public IBaseListener
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Api)
Api(Base *base); Api(Base *base);
~Api() override; ~Api() override;

View File

@@ -31,8 +31,11 @@
xmrig::Console::Console(IConsoleListener *listener) xmrig::Console::Console(IConsoleListener *listener)
: m_listener(listener) : m_listener(listener)
{ {
m_tty = new uv_tty_t; if (!isSupported()) {
return;
}
m_tty = new uv_tty_t;
m_tty->data = this; m_tty->data = this;
uv_tty_init(uv_default_loop(), m_tty, 0, 1); uv_tty_init(uv_default_loop(), m_tty, 0, 1);
@@ -53,6 +56,10 @@ xmrig::Console::~Console()
void xmrig::Console::stop() void xmrig::Console::stop()
{ {
if (!m_tty) {
return;
}
uv_tty_reset_mode(); uv_tty_reset_mode();
Handle::close(m_tty); Handle::close(m_tty);
@@ -60,6 +67,13 @@ void xmrig::Console::stop()
} }
bool xmrig::Console::isSupported() const
{
const uv_handle_type type = uv_guess_handle(0);
return type == UV_TTY || type == UV_NAMED_PIPE;
}
void xmrig::Console::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf) void xmrig::Console::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
{ {
auto console = static_cast<Console*>(handle->data); auto console = static_cast<Console*>(handle->data);

View File

@@ -26,9 +26,11 @@
#define XMRIG_CONSOLE_H #define XMRIG_CONSOLE_H
#include <uv.h> #include "base/tools/Object.h"
#include <uv.h>
namespace xmrig { namespace xmrig {
@@ -39,18 +41,22 @@ class IConsoleListener;
class Console class Console
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Console)
Console(IConsoleListener *listener); Console(IConsoleListener *listener);
~Console(); ~Console();
void stop(); void stop();
private: private:
bool isSupported() const;
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
char m_buf[1]; char m_buf[1] = { 0 };
IConsoleListener *m_listener; IConsoleListener *m_listener;
uv_tty_t *m_tty; uv_tty_t *m_tty = nullptr;
}; };

View File

@@ -27,6 +27,9 @@
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include <cassert>
namespace xmrig { namespace xmrig {
static const rapidjson::Value kNullValue; static const rapidjson::Value kNullValue;
@@ -36,6 +39,8 @@ static const rapidjson::Value kNullValue;
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue) bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsBool()) { if (i != obj.MemberEnd() && i->value.IsBool()) {
return i->value.GetBool(); return i->value.GetBool();
@@ -47,6 +52,8 @@ bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool def
const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key, const char *defaultValue) const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key, const char *defaultValue)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsString()) { if (i != obj.MemberEnd() && i->value.IsString()) {
return i->value.GetString(); return i->value.GetString();
@@ -58,6 +65,8 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key) const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsArray()) { if (i != obj.MemberEnd() && i->value.IsArray()) {
return i->value; return i->value;
@@ -69,6 +78,8 @@ const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const
const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key) const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsObject()) { if (i != obj.MemberEnd() && i->value.IsObject()) {
return i->value; return i->value;
@@ -80,6 +91,8 @@ const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, cons
const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key) const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd()) { if (i != obj.MemberEnd()) {
return i->value; return i->value;
@@ -91,6 +104,8 @@ const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue) int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsInt()) { if (i != obj.MemberEnd() && i->value.IsInt()) {
return i->value.GetInt(); return i->value.GetInt();
@@ -102,6 +117,8 @@ int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaul
int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue) int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsInt64()) { if (i != obj.MemberEnd() && i->value.IsInt64()) {
return i->value.GetInt64(); return i->value.GetInt64();
@@ -113,6 +130,8 @@ int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int6
uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue) uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsUint64()) { if (i != obj.MemberEnd() && i->value.IsUint64()) {
return i->value.GetUint64(); return i->value.GetUint64();
@@ -124,6 +143,8 @@ uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, ui
unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue) unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue)
{ {
assert(obj.IsObject());
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsUint()) { if (i != obj.MemberEnd() && i->value.IsUint()) {
return i->value.GetUint(); return i->value.GetUint();

View File

@@ -28,6 +28,7 @@
#ifdef __GNUC__ #ifdef __GNUC__
# include <fcntl.h> # include <fcntl.h>
# include <sys/stat.h>
# include <ext/stdio_filebuf.h> # include <ext/stdio_filebuf.h>
#endif #endif
@@ -102,7 +103,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
return false; return false;
} }
# elif defined(__GNUC__) # elif defined(__GNUC__)
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC); const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC, _S_IWRITE);
if (fd == -1) { if (fd == -1) {
return false; return false;
} }

View File

@@ -24,7 +24,7 @@
*/ */
#include <stdio.h> #include <cstdio>
#include "base/tools/Handle.h" #include "base/tools/Handle.h"
@@ -32,9 +32,13 @@
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
xmrig::ConsoleLog::ConsoleLog() : xmrig::ConsoleLog::ConsoleLog()
m_stream(nullptr)
{ {
if (!isSupported()) {
Log::colors = false;
return;
}
m_tty = new uv_tty_t; m_tty = new uv_tty_t;
if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) { if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) {
@@ -66,7 +70,7 @@ xmrig::ConsoleLog::~ConsoleLog()
void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors) void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors)
{ {
if (Log::colors != colors) { if (!m_tty || Log::colors != colors) {
return; return;
} }
@@ -86,12 +90,18 @@ void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool c
} }
bool xmrig::ConsoleLog::isSupported() const
{
const uv_handle_type type = uv_guess_handle(1);
return type == UV_TTY || type == UV_NAMED_PIPE;
}
bool xmrig::ConsoleLog::isWritable() const bool xmrig::ConsoleLog::isWritable() const
{ {
if (!m_stream || uv_is_writable(m_stream) != 1) { if (!m_stream || uv_is_writable(m_stream) != 1) {
return false; return false;
} }
const uv_handle_type type = uv_guess_handle(1); return isSupported();
return type == UV_TTY || type == UV_NAMED_PIPE;
} }

View File

@@ -27,11 +27,12 @@
#define XMRIG_CONSOLELOG_H #define XMRIG_CONSOLELOG_H
typedef struct uv_stream_s uv_stream_t; using uv_stream_t = struct uv_stream_s;
typedef struct uv_tty_s uv_tty_t; using uv_tty_t = struct uv_tty_s;
#include "base/kernel/interfaces/ILogBackend.h" #include "base/kernel/interfaces/ILogBackend.h"
#include "base/tools/Object.h"
namespace xmrig { namespace xmrig {
@@ -40,6 +41,8 @@ namespace xmrig {
class ConsoleLog : public ILogBackend class ConsoleLog : public ILogBackend
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE(ConsoleLog)
ConsoleLog(); ConsoleLog();
~ConsoleLog() override; ~ConsoleLog() override;
@@ -47,10 +50,11 @@ protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override; void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
private: private:
bool isSupported() const;
bool isWritable() const; bool isWritable() const;
uv_stream_t *m_stream; uv_stream_t *m_stream = nullptr;
uv_tty_t *m_tty; uv_tty_t *m_tty = nullptr;
}; };

View File

@@ -23,7 +23,7 @@
*/ */
#include <assert.h> #include <cassert>
#include <memory> #include <memory>
@@ -64,15 +64,16 @@ static const char *kConfigPathV2 = "/2/config";
#endif #endif
class xmrig::BasePrivate namespace xmrig {
class BasePrivate
{ {
public: public:
inline BasePrivate(Process *process) : XMRIG_DISABLE_COPY_MOVE_DEFAULT(BasePrivate)
api(nullptr),
config(nullptr),
process(process), inline BasePrivate(Process *process) : config(load(process)) {}
watcher(nullptr)
{}
inline ~BasePrivate() inline ~BasePrivate()
@@ -94,13 +95,33 @@ public:
} }
inline Config *load() inline void replace(Config *newConfig)
{
Config *previousConfig = config;
config = newConfig;
for (IBaseListener *listener : listeners) {
listener->onConfigChanged(config, previousConfig);
}
delete previousConfig;
}
Api *api = nullptr;
Config *config = nullptr;
std::vector<IBaseListener *> listeners;
Watcher *watcher = nullptr;
private:
inline Config *load(Process *process)
{ {
JsonChain chain; JsonChain chain;
ConfigTransform transform; ConfigTransform transform;
std::unique_ptr<Config> config; std::unique_ptr<Config> config;
transform.load(chain, process, transform); ConfigTransform::load(chain, process, transform);
if (read(chain, config)) { if (read(chain, config)) {
return config.release(); return config.release();
@@ -122,29 +143,12 @@ public:
return nullptr; return nullptr;
} }
inline void replace(Config *newConfig)
{
Config *previousConfig = config;
config = newConfig;
for (IBaseListener *listener : listeners) {
listener->onConfigChanged(config, previousConfig);
}
delete previousConfig;
}
Api *api;
Config *config;
Process *process;
std::vector<IBaseListener *> listeners;
Watcher *watcher;
}; };
} // namespace xmrig
xmrig::Base::Base(Process *process) xmrig::Base::Base(Process *process)
: d_ptr(new BasePrivate(process)) : d_ptr(new BasePrivate(process))
{ {
@@ -165,14 +169,6 @@ bool xmrig::Base::isReady() const
int xmrig::Base::init() int xmrig::Base::init()
{ {
d_ptr->config = d_ptr->load();
if (!d_ptr->config) {
LOG_EMERG("No valid configuration found. Exiting.");
return 1;
}
# ifdef XMRIG_FEATURE_API # ifdef XMRIG_FEATURE_API
d_ptr->api = new Api(this); d_ptr->api = new Api(this);
d_ptr->api->addListener(this); d_ptr->api->addListener(this);
@@ -184,7 +180,7 @@ int xmrig::Base::init()
Platform::setProcessPriority(config()->cpu().priority()); Platform::setProcessPriority(config()->cpu().priority());
# endif # endif
if (config()->isBackground()) { if (isBackground()) {
Log::background = true; Log::background = true;
} }
else { else {
@@ -240,6 +236,12 @@ xmrig::Api *xmrig::Base::api() const
} }
bool xmrig::Base::isBackground() const
{
return d_ptr->config && d_ptr->config->isBackground();
}
bool xmrig::Base::reload(const rapidjson::Value &json) bool xmrig::Base::reload(const rapidjson::Value &json)
{ {
JsonReader reader(json); JsonReader reader(json);
@@ -247,7 +249,7 @@ bool xmrig::Base::reload(const rapidjson::Value &json)
return false; return false;
} }
Config *config = new Config(); auto config = new Config();
if (!config->read(reader, d_ptr->config->fileName())) { if (!config->read(reader, d_ptr->config->fileName())) {
delete config; delete config;
@@ -289,7 +291,7 @@ void xmrig::Base::onFileChanged(const String &fileName)
JsonChain chain; JsonChain chain;
chain.addFile(fileName); chain.addFile(fileName);
Config *config = new Config(); auto config = new Config();
if (!config->read(chain, chain.fileName())) { if (!config->read(chain, chain.fileName())) {
LOG_ERR("reloading failed"); LOG_ERR("reloading failed");

View File

@@ -29,6 +29,7 @@
#include "base/api/interfaces/IApiListener.h" #include "base/api/interfaces/IApiListener.h"
#include "base/kernel/interfaces/IConfigListener.h" #include "base/kernel/interfaces/IConfigListener.h"
#include "base/kernel/interfaces/IWatcherListener.h" #include "base/kernel/interfaces/IWatcherListener.h"
#include "base/tools/Object.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@@ -45,6 +46,8 @@ class Process;
class Base : public IWatcherListener, public IApiListener class Base : public IWatcherListener, public IApiListener
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Base)
Base(Process *process); Base(Process *process);
~Base() override; ~Base() override;
@@ -54,6 +57,7 @@ public:
virtual void stop(); virtual void stop();
Api *api() const; Api *api() const;
bool isBackground() const;
bool reload(const rapidjson::Value &json); bool reload(const rapidjson::Value &json);
Config *config() const; Config *config() const;
void addListener(IBaseListener *listener); void addListener(IBaseListener *listener);

View File

@@ -23,7 +23,7 @@
*/ */
#include <stdio.h> #include <cstdio>
#include <uv.h> #include <uv.h>
@@ -161,7 +161,7 @@ int xmrig::Entry::exec(const Process &process, Id id)
{ {
switch (id) { switch (id) {
case Usage: case Usage:
printf(usage); printf("%s\n", usage().c_str());
return 0; return 0;
case Version: case Version:

View File

@@ -23,8 +23,8 @@
*/ */
#include <ctime>
#include <uv.h> #include <uv.h>
#include <time.h>
#include "base/kernel/Process.h" #include "base/kernel/Process.h"
@@ -55,11 +55,6 @@ xmrig::Process::Process(int argc, char **argv) :
} }
xmrig::Process::~Process()
{
}
xmrig::String xmrig::Process::location(Location location, const char *fileName) const xmrig::String xmrig::Process::location(Location location, const char *fileName) const
{ {
constexpr const size_t max = 520; constexpr const size_t max = 520;

View File

@@ -47,7 +47,6 @@ public:
# endif # endif
Process(int argc, char **argv); Process(int argc, char **argv);
~Process();
String location(Location location, const char *fileName = nullptr) const; String location(Location location, const char *fileName = nullptr) const;

View File

@@ -23,7 +23,7 @@
*/ */
#include <stdio.h> #include <cstdio>
#ifdef _MSC_VER #ifdef _MSC_VER
@@ -47,15 +47,11 @@ namespace xmrig
static const char *kAlgo = "algo"; static const char *kAlgo = "algo";
static const char *kApi = "api"; static const char *kApi = "api";
static const char *kCoin = "coin";
static const char *kHttp = "http"; static const char *kHttp = "http";
static const char *kPools = "pools"; static const char *kPools = "pools";
} } // namespace xmrig
xmrig::BaseTransform::BaseTransform()
{
}
void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform) void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform)
@@ -68,7 +64,7 @@ void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTrans
Document doc(kObjectType); Document doc(kObjectType);
while (1) { while (true) {
key = getopt_long(argc, argv, short_options, options, nullptr); key = getopt_long(argc, argv, short_options, options, nullptr);
if (key < 0) { if (key < 0) {
break; break;
@@ -107,6 +103,19 @@ void xmrig::BaseTransform::finalize(rapidjson::Document &doc)
} }
} }
} }
if (m_coin.isValid() && doc.HasMember(kPools)) {
auto &pools = doc[kPools];
for (Value &pool : pools.GetArray()) {
if (!pool.HasMember(kCoin)) {
pool.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator);
}
}
}
if (m_http) {
set(doc, kHttp, "enabled", true);
}
} }
@@ -122,6 +131,15 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
} }
break; break;
case IConfig::CoinKey: /* --coin */
if (!doc.HasMember(kPools)) {
m_coin = arg;
}
else {
return add(doc, kPools, kCoin, arg);
}
break;
case IConfig::UserpassKey: /* --userpass */ case IConfig::UserpassKey: /* --userpass */
{ {
const char *p = strrchr(arg, ':'); const char *p = strrchr(arg, ':');
@@ -169,9 +187,11 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
return set(doc, "log-file", arg); return set(doc, "log-file", arg);
case IConfig::HttpAccessTokenKey: /* --http-access-token */ case IConfig::HttpAccessTokenKey: /* --http-access-token */
m_http = true;
return set(doc, kHttp, "access-token", arg); return set(doc, kHttp, "access-token", arg);
case IConfig::HttpHostKey: /* --http-host */ case IConfig::HttpHostKey: /* --http-host */
m_http = true;
return set(doc, kHttp, "host", arg); return set(doc, kHttp, "host", arg);
case IConfig::ApiWorkerIdKey: /* --api-worker-id */ case IConfig::ApiWorkerIdKey: /* --api-worker-id */
@@ -226,8 +246,10 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
case IConfig::TlsKey: /* --tls */ case IConfig::TlsKey: /* --tls */
return add(doc, kPools, "tls", enable); return add(doc, kPools, "tls", enable);
# ifdef XMRIG_FEATURE_HTTP
case IConfig::DaemonKey: /* --daemon */ case IConfig::DaemonKey: /* --daemon */
return add(doc, kPools, "daemon", enable); return add(doc, kPools, "daemon", enable);
# endif
# ifndef XMRIG_PROXY_PROJECT # ifndef XMRIG_PROXY_PROJECT
case IConfig::NicehashKey: /* --nicehash */ case IConfig::NicehashKey: /* --nicehash */
@@ -238,10 +260,12 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
return set(doc, "colors", enable); return set(doc, "colors", enable);
case IConfig::HttpRestrictedKey: /* --http-no-restricted */ case IConfig::HttpRestrictedKey: /* --http-no-restricted */
m_http = true;
return set(doc, kHttp, "restricted", enable); return set(doc, kHttp, "restricted", enable);
case IConfig::HttpEnabledKey: /* --http-enabled */ case IConfig::HttpEnabledKey: /* --http-enabled */
return set(doc, kHttp, "enabled", enable); m_http = true;
break;
case IConfig::DryRunKey: /* --dry-run */ case IConfig::DryRunKey: /* --dry-run */
return set(doc, "dry-run", enable); return set(doc, "dry-run", enable);
@@ -268,13 +292,16 @@ void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, ui
return set(doc, "donate-over-proxy", arg); return set(doc, "donate-over-proxy", arg);
case IConfig::HttpPort: /* --http-port */ case IConfig::HttpPort: /* --http-port */
m_http = true;
return set(doc, kHttp, "port", arg); return set(doc, kHttp, "port", arg);
case IConfig::PrintTimeKey: /* --print-time */ case IConfig::PrintTimeKey: /* --print-time */
return set(doc, "print-time", arg); return set(doc, "print-time", arg);
# ifdef XMRIG_FEATURE_HTTP
case IConfig::DaemonPollKey: /* --daemon-poll-interval */ case IConfig::DaemonPollKey: /* --daemon-poll-interval */
return add(doc, kPools, "daemon-poll-interval", arg); return add(doc, kPools, "daemon-poll-interval", arg);
# endif
default: default:
break; break;

View File

@@ -27,6 +27,7 @@
#include "base/kernel/interfaces/IConfigTransform.h" #include "base/kernel/interfaces/IConfigTransform.h"
#include "crypto/common/Coin.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
@@ -44,8 +45,6 @@ class Process;
class BaseTransform : public IConfigTransform class BaseTransform : public IConfigTransform
{ {
public: public:
BaseTransform();
static void load(JsonChain &chain, Process *process, IConfigTransform &transform); static void load(JsonChain &chain, Process *process, IConfigTransform &transform);
protected: protected:
@@ -99,11 +98,14 @@ protected:
protected: protected:
Algorithm m_algorithm; Algorithm m_algorithm;
Coin m_coin;
private: private:
void transformBoolean(rapidjson::Document &doc, int key, bool enable); void transformBoolean(rapidjson::Document &doc, int key, bool enable);
void transformUint64(rapidjson::Document &doc, int key, uint64_t arg); void transformUint64(rapidjson::Document &doc, int key, uint64_t arg);
bool m_http = false;
}; };

View File

@@ -43,6 +43,7 @@ public:
enum Keys { enum Keys {
// common // common
AlgorithmKey = 'a', AlgorithmKey = 'a',
CoinKey = 1025,
ApiWorkerIdKey = 4002, ApiWorkerIdKey = 4002,
ApiIdKey = 4005, ApiIdKey = 4005,
HttpPort = 4100, HttpPort = 4100,
@@ -78,6 +79,7 @@ public:
PrintTimeKey = 1007, PrintTimeKey = 1007,
// xmrig cpu // xmrig cpu
CPUKey = 1024,
AVKey = 'v', AVKey = 'v',
CPUAffinityKey = 1020, CPUAffinityKey = 1020,
DryRunKey = 5000, DryRunKey = 5000,
@@ -86,6 +88,7 @@ public:
AssemblyKey = 1015, AssemblyKey = 1015,
RandomXInitKey = 1022, RandomXInitKey = 1022,
RandomXNumaKey = 1023, RandomXNumaKey = 1023,
CPUMaxThreadsKey = 1026,
// xmrig amd // xmrig amd
OclPlatformKey = 1400, OclPlatformKey = 1400,
@@ -99,6 +102,7 @@ public:
OclMemChunkKey = 1408, OclMemChunkKey = 1408,
OclUnrollKey = 1409, OclUnrollKey = 1409,
OclCompModeKey = 1410, OclCompModeKey = 1410,
OclKey = 1411,
// xmrig-proxy // xmrig-proxy
AccessLogFileKey = 'A', AccessLogFileKey = 'A',

View File

@@ -334,6 +334,9 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
if (algo) { if (algo) {
job.setAlgorithm(algo); job.setAlgorithm(algo);
} }
else if (m_pool.coin().isValid()) {
job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0]));
}
job.setHeight(Json::getUint64(params, "height")); job.setHeight(Json::getUint64(params, "height"));
@@ -426,7 +429,12 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
{ {
if (!algorithm.isValid()) { if (!algorithm.isValid()) {
if (!isQuiet()) { if (!isQuiet()) {
LOG_ERR("[%s] Unknown/unsupported algorithm \"%s\" detected, reconnect", url(), algo); if (algo == nullptr) {
LOG_ERR("[%s] unknown algorithm, make sure you set \"algo\" or \"coin\" option", url(), algo);
}
else {
LOG_ERR("[%s] unsupported algorithm \"%s\" detected, reconnect", url(), algo);
}
} }
return false; return false;
@@ -436,7 +444,7 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
m_listener->onVerifyAlgorithm(this, algorithm, &ok); m_listener->onVerifyAlgorithm(this, algorithm, &ok);
if (!ok && !isQuiet()) { if (!ok && !isQuiet()) {
LOG_ERR("[%s] Incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName()); LOG_ERR("[%s] incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName());
} }
return ok; return ok;

View File

@@ -25,7 +25,7 @@
#include <algorithm> #include <algorithm>
#include <assert.h> #include <cassert>
#include "3rdparty/http-parser/http_parser.h" #include "3rdparty/http-parser/http_parser.h"
@@ -225,6 +225,10 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
job.setDiff(Json::getUint64(params, "difficulty")); job.setDiff(Json::getUint64(params, "difficulty"));
job.setId(blocktemplate.data() + blocktemplate.size() - 32); job.setId(blocktemplate.data() + blocktemplate.size() - 32);
if (m_pool.coin().isValid()) {
job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0]));
}
m_job = std::move(job); m_job = std::move(job);
m_blocktemplate = std::move(blocktemplate); m_blocktemplate = std::move(blocktemplate);
m_prevHash = Json::getString(params, "prev_hash"); m_prevHash = Json::getString(params, "prev_hash");

View File

@@ -75,6 +75,7 @@ public:
inline uint8_t fixedByte() const { return *(m_blob + 42); } inline uint8_t fixedByte() const { return *(m_blob + 42); }
inline uint8_t index() const { return m_index; } inline uint8_t index() const { return m_index; }
inline void reset() { m_size = 0; m_diff = 0; } inline void reset() { m_size = 0; m_diff = 0; }
inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; }
inline void setAlgorithm(const char *algo) { m_algorithm = algo; } inline void setAlgorithm(const char *algo) { m_algorithm = algo; }
inline void setClientId(const String &id) { m_clientId = id; } inline void setClientId(const String &id) { m_clientId = id; }
inline void setHeight(uint64_t height) { m_height = height; } inline void setHeight(uint64_t height) { m_height = height; }

View File

@@ -48,6 +48,7 @@
namespace xmrig { namespace xmrig {
static const char *kAlgo = "algo"; static const char *kAlgo = "algo";
static const char *kCoin = "coin";
static const char *kDaemon = "daemon"; static const char *kDaemon = "daemon";
static const char *kDaemonPollInterval = "daemon-poll-interval"; static const char *kDaemonPollInterval = "daemon-poll-interval";
static const char *kEnabled = "enabled"; static const char *kEnabled = "enabled";
@@ -120,6 +121,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
m_fingerprint = Json::getString(object, kFingerprint); m_fingerprint = Json::getString(object, kFingerprint);
m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval); m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval);
m_algorithm = Json::getString(object, kAlgo); m_algorithm = Json::getString(object, kAlgo);
m_coin = Json::getString(object, kCoin);
m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true)); m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true));
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash));
@@ -172,7 +174,7 @@ bool xmrig::Pool::isEnabled() const
} }
# endif # endif
if (isDaemon() && !algorithm().isValid()) { if (isDaemon() && (!algorithm().isValid() && !coin().isValid())) {
return false; return false;
} }
@@ -186,6 +188,7 @@ bool xmrig::Pool::isEqual(const Pool &other) const
&& m_keepAlive == other.m_keepAlive && m_keepAlive == other.m_keepAlive
&& m_port == other.m_port && m_port == other.m_port
&& m_algorithm == other.m_algorithm && m_algorithm == other.m_algorithm
&& m_coin == other.m_coin
&& m_fingerprint == other.m_fingerprint && m_fingerprint == other.m_fingerprint
&& m_host == other.m_host && m_host == other.m_host
&& m_password == other.m_password && m_password == other.m_password
@@ -268,6 +271,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
Value obj(kObjectType); Value obj(kObjectType);
obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator); obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator);
obj.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator);
obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator); obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator);
obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator); obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator);

View File

@@ -32,7 +32,7 @@
#include "base/tools/String.h" #include "base/tools/String.h"
#include "crypto/common/Algorithm.h" #include "crypto/common/Coin.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@@ -74,6 +74,7 @@ public:
inline bool isTLS() const { return m_flags.test(FLAG_TLS); } inline bool isTLS() const { return m_flags.test(FLAG_TLS); }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const Algorithm &algorithm() const { return m_algorithm; } inline const Algorithm &algorithm() const { return m_algorithm; }
inline const Coin &coin() const { return m_coin; }
inline const String &fingerprint() const { return m_fingerprint; } inline const String &fingerprint() const { return m_fingerprint; }
inline const String &host() const { return m_host; } inline const String &host() const { return m_host; }
inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; } inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; }
@@ -107,6 +108,7 @@ private:
bool parseIPv6(const char *addr); bool parseIPv6(const char *addr);
Algorithm m_algorithm; Algorithm m_algorithm;
Coin m_coin;
int m_keepAlive; int m_keepAlive;
std::bitset<FLAG_MAX> m_flags; std::bitset<FLAG_MAX> m_flags;
String m_fingerprint; String m_fingerprint;

View File

@@ -135,11 +135,12 @@ void xmrig::Pools::print() const
{ {
size_t i = 1; size_t i = 1;
for (const Pool &pool : m_data) { for (const Pool &pool : m_data) {
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " algo " WHITE_BOLD("%s"), Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " %s " WHITE_BOLD("%s"),
i, i,
(pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31), (pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31),
pool.url().data(), pool.url().data(),
pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto" pool.coin().isValid() ? "coin" : "algo",
pool.coin().isValid() ? pool.coin().name() : (pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto")
); );
i++; i++;

View File

@@ -23,17 +23,27 @@
"huge-pages": true, "huge-pages": true,
"hw-aes": null, "hw-aes": null,
"priority": null, "priority": null,
"max-threads-hint": 100,
"asm": true, "asm": true,
"argon2-impl": null, "argon2-impl": null,
"cn/0": false, "cn/0": false,
"cn-lite/0": false "cn-lite/0": false
}, },
"opencl": {
"enabled": false,
"cache": true,
"loader": null,
"platform": "AMD",
"cn/0": false,
"cn-lite/0": false
},
"donate-level": 5, "donate-level": 5,
"donate-over-proxy": 1, "donate-over-proxy": 1,
"log-file": null, "log-file": null,
"pools": [ "pools": [
{ {
"algo": null, "algo": null,
"coin": null,
"url": "donate.v2.xmrig.com:3333", "url": "donate.v2.xmrig.com:3333",
"user": "YOUR_WALLET_ADDRESS", "user": "YOUR_WALLET_ADDRESS",
"pass": "x", "pass": "x",

View File

@@ -23,7 +23,7 @@
*/ */
#include <assert.h> #include <cassert>
#include "backend/cpu/Cpu.h" #include "backend/cpu/Cpu.h"
@@ -44,20 +44,9 @@ xmrig::Controller::~Controller()
} }
bool xmrig::Controller::isReady() const
{
return Base::isReady() && m_network;
}
int xmrig::Controller::init() int xmrig::Controller::init()
{ {
Cpu::init(); Base::init();
const int rc = Base::init();
if (rc != 0) {
return rc;
}
m_network = new Network(this); m_network = new Network(this);
return 0; return 0;

View File

@@ -27,6 +27,7 @@
#include "base/kernel/Base.h" #include "base/kernel/Base.h"
#include "base/tools/Object.h"
namespace xmrig { namespace xmrig {
@@ -40,10 +41,11 @@ class Network;
class Controller : public Base class Controller : public Base
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Controller)
Controller(Process *process); Controller(Process *process);
~Controller() override; ~Controller() override;
bool isReady() const override;
int init() override; int init() override;
void start() override; void start() override;
void stop() override; void stop() override;

View File

@@ -97,7 +97,7 @@ public:
bool isEnabled(const Algorithm &algorithm) const bool isEnabled(const Algorithm &algorithm) const
{ {
for (IBackend *backend : backends) { for (IBackend *backend : backends) {
if (backend->isEnabled(algorithm)) { if (backend->isEnabled() && backend->isEnabled(algorithm)) {
return true; return true;
} }
} }
@@ -124,16 +124,15 @@ public:
{ {
active = true; active = true;
if (reset) {
Nonce::reset(job.index());
}
for (IBackend *backend : backends) { for (IBackend *backend : backends) {
backend->setJob(job); backend->setJob(job);
} }
if (reset) { Nonce::touch();
Nonce::reset(job.index());
}
else {
Nonce::touch();
}
if (enabled) { if (enabled) {
Nonce::pause(false);; Nonce::pause(false);;

View File

@@ -35,11 +35,16 @@ namespace xmrig
static const char *kAffinity = "affinity"; static const char *kAffinity = "affinity";
static const char *kAsterisk = "*"; static const char *kAsterisk = "*";
static const char *kCpu = "cpu"; static const char *kCpu = "cpu";
static const char *kEnabled = "enabled";
static const char *kIntensity = "intensity"; static const char *kIntensity = "intensity";
static const char *kThreads = "threads"; static const char *kThreads = "threads";
#ifdef XMRIG_ALGO_RANDOMX #ifdef XMRIG_ALGO_RANDOMX
static const char *kRandomX = "randomx"; static const char *kRandomX = "randomx";
#endif
#ifdef XMRIG_FEATURE_OPENCL
static const char *kOcl = "opencl";
#endif #endif
@@ -80,12 +85,7 @@ static inline bool isHwAes(uint64_t av)
} }
} } // namespace xmrig
xmrig::ConfigTransform::ConfigTransform() : BaseTransform()
{
}
void xmrig::ConfigTransform::finalize(rapidjson::Document &doc) void xmrig::ConfigTransform::finalize(rapidjson::Document &doc)
@@ -109,6 +109,12 @@ void xmrig::ConfigTransform::finalize(rapidjson::Document &doc)
doc[kCpu].AddMember(StringRef(kAsterisk), profile, doc.GetAllocator()); doc[kCpu].AddMember(StringRef(kAsterisk), profile, doc.GetAllocator());
} }
# ifdef XMRIG_FEATURE_OPENCL
if (m_opencl) {
set(doc, kOcl, kEnabled, true);
}
# endif
} }
@@ -123,6 +129,7 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10))); return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
case IConfig::HugePagesKey: /* --no-huge-pages */ case IConfig::HugePagesKey: /* --no-huge-pages */
case IConfig::CPUKey: /* --no-cpu */
return transformBoolean(doc, key, false); return transformBoolean(doc, key, false);
case IConfig::CPUAffinityKey: /* --cpu-affinity */ case IConfig::CPUAffinityKey: /* --cpu-affinity */
@@ -131,7 +138,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
return transformUint64(doc, key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); return transformUint64(doc, key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
} }
# ifndef XMRIG_NO_ASM case IConfig::CPUMaxThreadsKey: /* --cpu-max-threads-hint */
return set(doc, kCpu, "max-threads-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
# ifdef XMRIG_FEATURE_ASM
case IConfig::AssemblyKey: /* --asm */ case IConfig::AssemblyKey: /* --asm */
return set(doc, kCpu, "asm", arg); return set(doc, kCpu, "asm", arg);
# endif # endif
@@ -144,6 +154,29 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
return set(doc, kRandomX, "numa", false); return set(doc, kRandomX, "numa", false);
# endif # endif
# ifdef XMRIG_FEATURE_OPENCL
case IConfig::OclKey: /* --opencl */
m_opencl = true;
break;
case IConfig::OclCacheKey: /* --opencl-no-cache */
return set(doc, kOcl, "cache", false);
case IConfig::OclLoaderKey: /* --opencl-loader */
return set(doc, kOcl, "loader", arg);
case IConfig::OclDevicesKey: /* --opencl-devices */
m_opencl = true;
return set(doc, kOcl, "devices-hint", arg);
case IConfig::OclPlatformKey: /* --opencl-platform */
if (strlen(arg) < 3) {
return set(doc, kOcl, "platform", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
}
return set(doc, kOcl, "platform", arg);
# endif
default: default:
break; break;
} }
@@ -156,6 +189,9 @@ void xmrig::ConfigTransform::transformBoolean(rapidjson::Document &doc, int key,
case IConfig::HugePagesKey: /* --no-huge-pages */ case IConfig::HugePagesKey: /* --no-huge-pages */
return set(doc, kCpu, "huge-pages", enable); return set(doc, kCpu, "huge-pages", enable);
case IConfig::CPUKey: /* --no-cpu */
return set(doc, kCpu, kEnabled, enable);
default: default:
break; break;
} }

View File

@@ -34,9 +34,6 @@ namespace xmrig {
class ConfigTransform : public BaseTransform class ConfigTransform : public BaseTransform
{ {
public:
ConfigTransform();
protected: protected:
void finalize(rapidjson::Document &doc) override; void finalize(rapidjson::Document &doc) override;
void transform(rapidjson::Document &doc, int key, const char *arg) override; void transform(rapidjson::Document &doc, int key, const char *arg) override;
@@ -45,6 +42,7 @@ private:
void transformBoolean(rapidjson::Document &doc, int key, bool enable); void transformBoolean(rapidjson::Document &doc, int key, bool enable);
void transformUint64(rapidjson::Document &doc, int key, uint64_t arg); void transformUint64(rapidjson::Document &doc, int key, uint64_t arg);
bool m_opencl = false;
int64_t m_affinity = -1; int64_t m_affinity = -1;
uint64_t m_intensity = 1; uint64_t m_intensity = 1;
uint64_t m_threads = 0; uint64_t m_threads = 0;

View File

@@ -57,17 +57,27 @@ R"===(
"huge-pages": true, "huge-pages": true,
"hw-aes": null, "hw-aes": null,
"priority": null, "priority": null,
"max-threads-hint": 100,
"asm": true, "asm": true,
"argon2-impl": null, "argon2-impl": null,
"cn/0": false, "cn/0": false,
"cn-lite/0": false "cn-lite/0": false
}, },
"opencl": {
"enabled": false,
"cache": true,
"loader": null,
"platform": "AMD",
"cn/0": false,
"cn-lite/0": false
},
"donate-level": 5, "donate-level": 5,
"donate-over-proxy": 1, "donate-over-proxy": 1,
"log-file": null, "log-file": null,
"pools": [ "pools": [
{ {
"algo": null, "algo": null,
"coin": null,
"url": "donate.v2.xmrig.com:3333", "url": "donate.v2.xmrig.com:3333",
"user": "YOUR_WALLET_ADDRESS", "user": "YOUR_WALLET_ADDRESS",
"pass": "x", "pass": "x",

View File

@@ -45,6 +45,8 @@ static const char short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S";
static const option options[] = { static const option options[] = {
{ "algo", 1, nullptr, IConfig::AlgorithmKey }, { "algo", 1, nullptr, IConfig::AlgorithmKey },
{ "coin", 1, nullptr, IConfig::CoinKey },
# ifdef XMRIG_FEATURE_HTTP
{ "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey }, { "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
{ "api-id", 1, nullptr, IConfig::ApiIdKey }, { "api-id", 1, nullptr, IConfig::ApiIdKey },
{ "http-enabled", 0, nullptr, IConfig::HttpEnabledKey }, { "http-enabled", 0, nullptr, IConfig::HttpEnabledKey },
@@ -52,6 +54,9 @@ static const option options[] = {
{ "http-access-token", 1, nullptr, IConfig::HttpAccessTokenKey }, { "http-access-token", 1, nullptr, IConfig::HttpAccessTokenKey },
{ "http-port", 1, nullptr, IConfig::HttpPort }, { "http-port", 1, nullptr, IConfig::HttpPort },
{ "http-no-restricted", 0, nullptr, IConfig::HttpRestrictedKey }, { "http-no-restricted", 0, nullptr, IConfig::HttpRestrictedKey },
{ "daemon", 0, nullptr, IConfig::DaemonKey },
{ "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey },
# endif
{ "av", 1, nullptr, IConfig::AVKey }, { "av", 1, nullptr, IConfig::AVKey },
{ "background", 0, nullptr, IConfig::BackgroundKey }, { "background", 0, nullptr, IConfig::BackgroundKey },
{ "config", 1, nullptr, IConfig::ConfigKey }, { "config", 1, nullptr, IConfig::ConfigKey },
@@ -76,13 +81,27 @@ static const option options[] = {
{ "user-agent", 1, nullptr, IConfig::UserAgentKey }, { "user-agent", 1, nullptr, IConfig::UserAgentKey },
{ "userpass", 1, nullptr, IConfig::UserpassKey }, { "userpass", 1, nullptr, IConfig::UserpassKey },
{ "rig-id", 1, nullptr, IConfig::RigIdKey }, { "rig-id", 1, nullptr, IConfig::RigIdKey },
{ "no-cpu", 0, nullptr, IConfig::CPUKey },
{ "max-cpu-usage", 1, nullptr, IConfig::CPUMaxThreadsKey },
{ "cpu-max-threads-hint", 1, nullptr, IConfig::CPUMaxThreadsKey },
# ifdef XMRIG_FEATURE_TLS
{ "tls", 0, nullptr, IConfig::TlsKey }, { "tls", 0, nullptr, IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey }, { "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey },
# endif
# ifdef XMRIG_FEATURE_ASM
{ "asm", 1, nullptr, IConfig::AssemblyKey }, { "asm", 1, nullptr, IConfig::AssemblyKey },
{ "daemon", 0, nullptr, IConfig::DaemonKey }, # endif
{ "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey }, # ifdef XMRIG_ALGO_RANDOMX
{ "randomx-init", 1, nullptr, IConfig::RandomXInitKey }, { "randomx-init", 1, nullptr, IConfig::RandomXInitKey },
{ "randomx-no-numa", 0, nullptr, IConfig::RandomXNumaKey }, { "randomx-no-numa", 0, nullptr, IConfig::RandomXNumaKey },
# endif
# ifdef XMRIG_FEATURE_OPENCL
{ "opencl", 0, nullptr, IConfig::OclKey },
{ "opencl-devices", 1, nullptr, IConfig::OclDevicesKey },
{ "opencl-platform", 1, nullptr, IConfig::OclPlatformKey },
{ "opencl-loader", 1, nullptr, IConfig::OclLoaderKey },
{ "opencl-no-cache", 0, nullptr, IConfig::OclCacheKey },
# endif
{ nullptr, 0, nullptr, 0 } { nullptr, 0, nullptr, 0 }
}; };

View File

@@ -29,99 +29,106 @@
#include "version.h" #include "version.h"
#include <string>
namespace xmrig { namespace xmrig {
static char const usage[] = "\ static inline const std::string &usage()
Usage: " APP_ID " [OPTIONS]\n\ {
Options:\n\ static std::string u;
-a, --algo=ALGO specify the algorithm to use\n\
cn/r, cn/2, cn/1, cn/0, cn/double, cn/half, cn/fast,\n\ if (!u.empty()) {
cn/rwz, cn/zls, cn/xao, cn/rto" return u;
#ifdef XMRIG_ALGO_CN_GPU }
", cn/gpu,\n"
#else u += "Usage: " APP_ID " [OPTIONS]\n\nNetwork:\n";
",\n" u += " -o, --url=URL URL of mining server\n";
#endif u += " -a, --algo=ALGO mining algorithm https://xmrig.com/docs/algorithms\n";
#ifdef XMRIG_ALGO_CN_LITE u += " -u, --user=USERNAME username for mining server\n";
"\ u += " -p, --pass=PASSWORD password for mining server\n";
cn-lite/1,\n" u += " -O, --userpass=U:P username:password pair for mining server\n";
#endif u += " -k, --keepalive send keepalived packet for prevent timeout (needs pool support)\n";
#ifdef XMRIG_ALGO_CN_HEAVY u += " --nicehash enable nicehash.com support\n";
"\ u += " --rig-id=ID rig identifier for pool-side statistics (needs pool support)\n";
cn-heavy/xhv, cn-heavy/tube, cn-heavy/0,\n"
#endif # ifdef XMRIG_FEATURE_TLS
#ifdef XMRIG_ALGO_CN_PICO u += " --tls enable SSL/TLS support (needs pool support)\n";
"\ u += " --tls-fingerprint=HEX pool TLS certificate fingerprint for strict certificate pinning\n";
cn-pico,\n" # endif
#endif
#ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_FEATURE_HTTP
"\ u += " --daemon use daemon RPC instead of pool for solo mining\n";
rx/wow, rx/loki\n" u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n";
#endif # endif
"\
-o, --url=URL URL of mining server\n\ u += " -r, --retries=N number of times to retry before switch to backup server (default: 5)\n";
-O, --userpass=U:P username:password pair for mining server\n\ u += " -R, --retry-pause=N time to pause between retries (default: 5)\n";
-u, --user=USERNAME username for mining server\n\ u += " --user-agent set custom user-agent string for pool\n";
-p, --pass=PASSWORD password for mining server\n\ u += " --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n";
--rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\ u += " --donate-over-proxy=N control donate over xmrig-proxy feature\n";
-t, --threads=N number of miner threads\n\
-v, --av=N algorithm variation, 0 auto select\n\ u += "\nCPU backend:\n";
-k, --keepalive send keepalived packet for prevent timeout (needs pool support)\n\
--nicehash enable nicehash.com support\n" u += " --no-cpu disable CPU mining backend\n";
#ifdef XMRIG_FEATURE_TLS u += " -t, --threads=N number of CPU threads\n";
"\ u += " -v, --av=N algorithm variation, 0 auto select\n";
--tls enable SSL/TLS support (needs pool support)\n\ u += " --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n";
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n" u += " --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n";
#endif u += " --cpu-max-threads-hint=N maximum CPU threads count (in percentage) hint for autoconfig\n";
#ifdef XMRIG_FEATURE_HTTP u += " --no-huge-pages disable huge pages support\n";
"\ u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n";
--daemon use daemon RPC instead of pool for solo mining\n\
--daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n" # ifdef XMRIG_ALGO_RANDOMX
#endif u += " --randomx-init=N threads count to initialize RandomX dataset\n";
"\ u += " --randomx-no-numa disable NUMA support for RandomX\n";
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ # endif
-R, --retry-pause=N time to pause between retries (default: 5)\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ # ifdef XMRIG_FEATURE_HTTP
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\ u += "\nAPI:\n";
--no-huge-pages disable huge pages support\n\ u += " --api-worker-id=ID custom worker-id for API\n";
--no-color disable colored output\n\ u += " --api-id=ID custom instance ID for API\n";
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ u += " --http-host=HOST bind host for HTTP API (default: 127.0.0.1)\n";
--user-agent set custom user-agent string for pool\n\ u += " --http-port=N bind port for HTTP API\n";
-B, --background run the miner in the background\n\ u += " --http-access-token=T access token for HTTP API\n";
-c, --config=FILE load a JSON-format configuration file\n\ u += " --http-no-restricted enable full remote access to HTTP API (only if access token set)\n";
-l, --log-file=FILE log all output to a file\n" # endif
# ifdef HAVE_SYSLOG_H
"\ # ifdef XMRIG_FEATURE_OPENCL
-S, --syslog use system log for output messages\n" u += "\nOpenCL backend:\n";
# endif u += " --opencl enable OpenCL mining backend\n";
"\ u += " --opencl-devices=N list of OpenCL devices to use\n";
--asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer.\n\ u += " --opencl-platform=N OpenCL platform index or name\n";
--print-time=N print hashrate report every N seconds\n" u += " --opencl-loader=N path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so)\n";
#ifdef XMRIG_FEATURE_HTTP u += " --opencl-no-cache disable OpenCL cache\n";
"\ u += " --print-platforms print available OpenCL platforms and exit\n";
--api-worker-id=ID custom worker-id for API\n\ # endif
--api-id=ID custom instance ID for API\n\
--http-enabled enable HTTP API\n\ u += "\nLogging:\n";
--http-host=HOST bind host for HTTP API (default: 127.0.0.1)\n\
--http-port=N bind port for HTTP API\n\ # ifdef HAVE_SYSLOG_H
--http-access-token=T access token for HTTP API\n\ u += " -S, --syslog use system log for output messages\n";
--http-no-restricted enable full remote access to HTTP API (only if access token set)\n" # endif
#endif
#ifdef XMRIG_ALGO_RANDOMX u += " -l, --log-file=FILE log all output to a file\n";
"\ u += " --print-time=N print hashrate report every N seconds\n";
--randomx-init=N threads count to initialize RandomX dataset\n\ u += " --no-color disable colored output\n";
--randomx-no-numa disable NUMA support for RandomX\n"
#endif u += "\nMisc:\n";
#ifdef XMRIG_FEATURE_HWLOC
"\ u += " -c, --config=FILE load a JSON-format configuration file\n";
--export-topology export hwloc topology to a XML file and exit\n" u += " -B, --background run the miner in the background\n";
#endif u += " -V, --version output version information and exit\n";
"\ u += " -h, --help display this help and exit\n";
--dry-run test configuration and exit\n\ u += " --dry-run test configuration and exit\n";
-h, --help display this help and exit\n\
-V, --version output version information and exit\n\ # ifdef XMRIG_FEATURE_HWLOC
"; u += " --export-topology export hwloc topology to a XML file and exit\n";
# endif
return u;
}
} /* namespace xmrig */ } /* namespace xmrig */

View File

@@ -103,9 +103,8 @@ static AlgoName const algorithm_names[] = {
{ "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO_0 }, { "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO_0 },
# endif # endif
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "randomx/test", "rx/test", Algorithm::RX_0 }, { "randomx/test", "rx/test", Algorithm::RX_0 },
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "RandomX", "rx", Algorithm::RX_0 }, { "RandomX", "rx", Algorithm::RX_0 },
{ "randomx/wow", "rx/wow", Algorithm::RX_WOW }, { "randomx/wow", "rx/wow", Algorithm::RX_WOW },
{ "RandomWOW", nullptr, Algorithm::RX_WOW }, { "RandomWOW", nullptr, Algorithm::RX_WOW },

103
src/crypto/common/Coin.cpp Normal file
View File

@@ -0,0 +1,103 @@
/* 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 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>
*
* 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 "crypto/common/Coin.h"
#include "rapidjson/document.h"
#include <cstring>
#ifdef _MSC_VER
# define strcasecmp _stricmp
#endif
namespace xmrig {
struct CoinName
{
const char *name;
const Coin::Id id;
};
static CoinName const coin_names[] = {
{ "monero", Coin::MONERO },
{ "xmr", Coin::MONERO },
};
} /* namespace xmrig */
xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const
{
if (id() == MONERO) {
return (blobVersion >= 12) ? Algorithm::RX_0 : Algorithm::CN_R;
}
return Algorithm::INVALID;
}
const char *xmrig::Coin::name() const
{
for (const auto &i : coin_names) {
if (i.id == m_id) {
return i.name;
}
}
return nullptr;
}
rapidjson::Value xmrig::Coin::toJSON() const
{
using namespace rapidjson;
return isValid() ? Value(StringRef(name())) : Value(kNullType);
}
xmrig::Coin::Id xmrig::Coin::parse(const char *name)
{
if (name == nullptr || strlen(name) < 3) {
return INVALID;
}
for (const auto &i : coin_names) {
if (strcasecmp(name, i.name) == 0) {
return i.id;
}
}
return INVALID;
}

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