* Implement --max-cpu-usage.
* Fix L2 cache size detect. * Add test for get_optimal_threads_count.
This commit is contained in:
parent
719601f92b
commit
c4bccf410b
26
cpu.c
26
cpu.c
@ -24,11 +24,17 @@
|
||||
#include <cpuid.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <libcpuid.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef BUILD_TEST
|
||||
# include <libcpuid.h>
|
||||
#endif
|
||||
|
||||
#include "cpu.h"
|
||||
#include "utils/applog.h"
|
||||
|
||||
|
||||
#ifndef BUILD_TEST
|
||||
void cpu_init_common() {
|
||||
struct cpu_raw_data_t raw = { 0 };
|
||||
struct cpu_id_t data = { 0 };
|
||||
@ -41,7 +47,7 @@ void cpu_init_common() {
|
||||
cpu_info.total_logical_cpus = data.total_logical_cpus;
|
||||
cpu_info.sockets = data.total_logical_cpus / data.num_logical_cpus;
|
||||
cpu_info.total_cores = data.num_cores * cpu_info.sockets;
|
||||
cpu_info.l2_cache = data.l2_cache > 0 ? data.l2_cache * cpu_info.sockets : 0;
|
||||
cpu_info.l2_cache = data.l2_cache > 0 ? data.l2_cache * cpu_info.total_cores * cpu_info.sockets : 0;
|
||||
cpu_info.l3_cache = data.l3_cache > 0 ? data.l3_cache * cpu_info.sockets : 0;
|
||||
|
||||
# ifdef __x86_64__
|
||||
@ -56,21 +62,31 @@ void cpu_init_common() {
|
||||
cpu_info.flags |= CPU_FLAG_BMI2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int get_optimal_threads_count() {
|
||||
int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage) {
|
||||
if (cpu_info.total_logical_cpus == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cache = cpu_info.l3_cache ? cpu_info.l3_cache : cpu_info.l2_cache;
|
||||
int count = 0;
|
||||
const int size = (algo ? 1024 : 2048) * (double_hash ? 2 : 1);
|
||||
|
||||
if (cache) {
|
||||
count = cache / 2048;
|
||||
count = cache / size;
|
||||
}
|
||||
else {
|
||||
count = cpu_info.total_logical_cpus / 2;
|
||||
}
|
||||
|
||||
if (count > cpu_info.total_logical_cpus) {
|
||||
return cpu_info.total_logical_cpus;
|
||||
count = cpu_info.total_logical_cpus;
|
||||
}
|
||||
|
||||
if (((float) count / cpu_info.total_logical_cpus * 100) > max_cpu_usage) {
|
||||
count = ceil((float) cpu_info.total_logical_cpus * (max_cpu_usage / 100.0));
|
||||
}
|
||||
|
||||
return count < 1 ? 1 : count;
|
||||
|
4
cpu.h
4
cpu.h
@ -24,6 +24,8 @@
|
||||
#ifndef __CPU_H__
|
||||
#define __CPU_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct cpu_info {
|
||||
int total_cores;
|
||||
int total_logical_cpus;
|
||||
@ -45,7 +47,7 @@ enum cpu_flags {
|
||||
|
||||
|
||||
void cpu_init();
|
||||
int get_optimal_threads_count();
|
||||
int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage);
|
||||
int affine_to_cpu_mask(int id, unsigned long mask);
|
||||
|
||||
#endif /* __CPU_H__ */
|
||||
|
@ -101,7 +101,7 @@ void cpu_init_common() {
|
||||
}
|
||||
|
||||
|
||||
int get_optimal_threads_count() {
|
||||
int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage) {
|
||||
int count = cpu_info.total_logical_cpus / 2;
|
||||
return count < 1 ? 1 : count;
|
||||
}
|
||||
|
@ -447,16 +447,16 @@ void parse_cmdline(int argc, char *argv[]) {
|
||||
sprintf(opt_userpass, "%s:%s", opt_user, opt_pass);
|
||||
}
|
||||
|
||||
if (!opt_n_threads) {
|
||||
opt_n_threads = get_optimal_threads_count();
|
||||
}
|
||||
|
||||
opt_algo_variant = get_algo_variant(opt_algo, opt_algo_variant);
|
||||
|
||||
if (!cryptonight_init(opt_algo_variant)) {
|
||||
applog(LOG_ERR, "Cryptonight hash self-test failed. This might be caused by bad compiler optimizations.");
|
||||
proper_exit(1);
|
||||
}
|
||||
|
||||
if (!opt_n_threads) {
|
||||
opt_n_threads = get_optimal_threads_count(opt_algo, opt_double_hash, opt_max_cpu_usage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,4 +5,5 @@ include(CTest)
|
||||
|
||||
add_subdirectory(unity)
|
||||
add_subdirectory(cryptonight)
|
||||
add_subdirectory(cryptonight_lite)
|
||||
add_subdirectory(cryptonight_lite)
|
||||
add_subdirectory(autoconf)
|
16
test/autoconf/CMakeLists.txt
Normal file
16
test/autoconf/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
set(SOURCES
|
||||
autoconf.c
|
||||
../../cpu.h
|
||||
../../cpu.c
|
||||
)
|
||||
|
||||
add_executable(autoconf_app ${SOURCES})
|
||||
target_link_libraries(autoconf_app unity)
|
||||
|
||||
include_directories(../..)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2")
|
||||
add_definitions(-DBUILD_TEST)
|
||||
|
||||
add_test(autoconf_test autoconf_app)
|
152
test/autoconf/autoconf.c
Normal file
152
test/autoconf/autoconf.c
Normal file
@ -0,0 +1,152 @@
|
||||
#include <unity.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "options.h"
|
||||
|
||||
struct cpu_info cpu_info = { 0 };
|
||||
|
||||
|
||||
static void set_cpu_info(int total_logical_cpus, int l2_cache, int l3_cache) {
|
||||
cpu_info.total_cores = total_logical_cpus;
|
||||
cpu_info.total_logical_cpus = total_logical_cpus;
|
||||
cpu_info.l2_cache = l2_cache;
|
||||
cpu_info.l3_cache = l3_cache;
|
||||
}
|
||||
|
||||
|
||||
void test_autoconf_should_GetOptimalThreadsCounti7(void) {
|
||||
set_cpu_info(8, 1024, 8192); // 4C/8T 8 MB (Generic i7 CPU)
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(5, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 60));
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 50));
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 35));
|
||||
TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 20));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 5));
|
||||
}
|
||||
|
||||
|
||||
void test_autoconf_should_GetOptimalThreadsCounti5(void) {
|
||||
set_cpu_info(4, 1024, 6144); // 2C/4T 6 MB (Generic i5 CPU)
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75));
|
||||
}
|
||||
|
||||
|
||||
void test_autoconf_should_GetOptimalThreadsCounti3(void) {
|
||||
set_cpu_info(4, 512, 3072); // 2C/4T 3 MB (Generic i3 CPU)
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75));
|
||||
}
|
||||
|
||||
|
||||
void test_autoconf_should_GetOptimalThreadsCountR7(void) {
|
||||
set_cpu_info(16, 4096, 16384); // 8C/16T 16 MB (AMD Ryzen 7)
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(16, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75));
|
||||
}
|
||||
|
||||
|
||||
void test_autoconf_should_GetOptimalThreadsCountTwoE5620(void) {
|
||||
set_cpu_info(16, 2048, 24576); // 8C/16T 24 MB (Two E5620)
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(16, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75));
|
||||
}
|
||||
|
||||
|
||||
void test_autoconf_should_GetOptimalThreadsCountVCPU(void) {
|
||||
set_cpu_info(1, 1024, 15360); // 1C/1T 15 MB (Single core Virtual CPU)
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75));
|
||||
}
|
||||
|
||||
|
||||
void test_autoconf_should_GetOptimalThreadsCountNoL3(void) {
|
||||
set_cpu_info(8, 8192, 0); // 4C/8T (Multi core Virtual CPU without L3 cache)
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100));
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75));
|
||||
TEST_ASSERT_EQUAL_INT(5, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 60));
|
||||
TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 50));
|
||||
TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 35));
|
||||
TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 20));
|
||||
TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 5));
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti7);
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti5);
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti3);
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCountR7);
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCountR7);
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCountTwoE5620);
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCountVCPU);
|
||||
RUN_TEST(test_autoconf_should_GetOptimalThreadsCountNoL3);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
@ -54,10 +54,10 @@ static void print_cpu() {
|
||||
|
||||
# ifndef XMRIG_NO_LIBCPUID
|
||||
if (opt_colors) {
|
||||
applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU L2/L3: %dK/%dK", cpu_info.l2_cache, cpu_info.l3_cache);
|
||||
applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU L2/L3: %.1f MB/%.1f MB", cpu_info.l2_cache / 1024.0, cpu_info.l3_cache / 1024.0);
|
||||
}
|
||||
else {
|
||||
applog_notime(LOG_INFO, " * CPU L2/L3: %dK/%dK", cpu_info.l2_cache, cpu_info.l3_cache);
|
||||
applog_notime(LOG_INFO, " * CPU L2/L3: %.1f MB/%.1f MB", cpu_info.l2_cache / 1024.0, cpu_info.l3_cache / 1024.0);
|
||||
}
|
||||
# endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user