Commit 4ad7df2b authored by Ruben Laso Rodríguez's avatar Ruben Laso Rodríguez
Browse files

Modified balancing algorithm. Processes with CPU usage under 0.01 are not considered.

parent e0d31fc4
......@@ -144,7 +144,8 @@ namespace migration {
std::vector<migration_cell> migrations;
if (details::strategy != RM3D) {
migrations = strategy::balance_CPUs();
// migrations = strategy::balance_CPUs();
migrations = strategy::balance_CPUs_by_non_idle();
}
if (!migrations.empty()) {
......
......@@ -298,6 +298,16 @@ namespace migration {
}
if (tid_under_perf_.empty()) {
// Take a random thread
// const auto idx = rand() % perf_table.table_.size();
// auto iter = perf_table.table_.begin();
// std::advance(iter, idx);
// const auto & [tid, data] = *iter;
//
// const auto perf = perf_table.rel_performance(tid);
//
// tid_under_perf_.emplace_back(perf, tid);
if (VERBOSE_LVL >= DEFAULT_VERB) {
std::cout << "NO SUITABLE THREADS, NO MIGRATIONS" << '\n';
}
......
......@@ -105,11 +105,14 @@ namespace migration {
std::vector<migration_cell> migrations_done;
for (size_t cpu = 0; cpu < system_info::num_of_cpus(); cpu++) {
const auto & tids = system_info::tids_from_cpu(cpu);
if (tids.size() < 2) {
continue;
}
// If the CPU has more than 1 thread running, try to move threads to free cores
bool migrated;
do {
const auto & tid = *(tids.begin());
migrated = false;
......@@ -118,6 +121,10 @@ namespace migration {
size_t min = tids.size() - 1;
for (size_t dst_cpu = 0; dst_cpu < system_info::num_of_cpus(); dst_cpu++) {
if (cpu == dst_cpu) {
continue;
}
const auto dst_tids = system_info::tids_from_cpu(dst_cpu).size();
if (dst_tids == 0) {
......@@ -152,6 +159,67 @@ namespace migration {
return migrations_done;
}
static std::vector<migration_cell> balance_CPUs_by_non_idle () {
std::vector<migration_cell> migrations_done;
for (size_t cpu = 0; cpu < system_info::num_of_cpus(); cpu++) {
const auto & initial_tids = system_info::non_idle_tids_from_cpu(cpu);
if (initial_tids.size() < 2) {
continue;
}
// If the CPU has more than 1 thread running, try to move threads to free cores
bool migrated;
do {
const auto & tids = system_info::non_idle_tids_from_cpu(cpu);
const auto & tid = *(tids.begin());
migrated = false;
cpu_t min_cpu = cpu;
size_t min = tids.size() - 1;
for (size_t dst_cpu = 0; dst_cpu < system_info::num_of_cpus(); dst_cpu++) {
if (cpu == dst_cpu) {
continue;
}
const auto dst_tids = system_info::non_idle_tids_from_cpu(dst_cpu).size();
if (dst_tids == 0) {
min_cpu = dst_cpu;
min = 0;
break;
} else if (dst_tids < min) { // To balance (not only move to free cores)
min_cpu = dst_cpu;
min = dst_tids;
}
}
if (min < tids.size() - 1) {
simple_migration_cell mc(tid, system_info::pid_from_tid(tid), min_cpu, cpu,
perf_table.performance(tid));
migration_cell migration({mc}, TICKETS_FREE_CORE, 0);
if (VERBOSE_LVL >= DEFAULT_VERB) {
std::cout << "Balancing: " << migration << '\n';
}
if (!migration.migrate()) {
if (VERBOSE_LVL >= DEFAULT_VERB) {
std::cerr << "Error balancing threads" << '\n';
}
} else {
migrations_done.push_back(migration);
migrated = true;
}
}
} while (system_info::non_idle_tids_from_cpu(cpu).size() > 1 && migrated);
}
return migrations_done;
}
virtual void migrate () = 0;
};
}
......
......@@ -133,7 +133,7 @@ namespace system_info {
}
inline bool pin_thread_to_node (process & proc, const bool print = true) {
if (proc.pin(print)) {
if (proc.pin_node(print)) {
const auto node = details::cpu_node_map[proc.cpu()];
details::node_tid_map[node].insert(proc.pid());
return true;
......@@ -322,6 +322,22 @@ namespace system_info {
return details::cpu_tid_map.at(cpu);
}
inline const auto non_idle_tids_from_cpu (const cpu_t cpu) {
const auto & tids = details::cpu_tid_map.at(cpu);
std::vector<pid_t> non_idle_tids;
for (const auto & tid : tids) {
const auto & tid_struct = details::proc_tree.retrieve(tid);
if (tid_struct.percent_cpu() > 0.01) {
non_idle_tids.push_back(tid);
}
}
return std::move(non_idle_tids);
}
inline const auto & tids_from_node (const node_t node) {
return details::node_tid_map.at(node);
}
......@@ -374,6 +390,26 @@ namespace system_info {
return ret;
}
inline bool pin_all_threads_if_CPU_free () {
bool ret = true;
process & root_proc = details::proc_tree.retrieve();
if (is_cpu_free(root_proc.cpu())) {
ret &= auxiliary_functions::pin_thread_to_cpu(root_proc);
}
auto children = root_proc.all_children();
for (auto & child : children) {
if (is_cpu_free(child->cpu())) {
ret &= auxiliary_functions::pin_thread_to_cpu(*child);
}
}
return ret;
}
inline bool pin_all_threads_node () {
bool ret = true;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment