i think the silly little data races are fixed now
parent
821ffa3aa9
commit
c4cff07210
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(blt-gp VERSION 0.0.63)
|
project(blt-gp VERSION 0.0.64)
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace blt::gp
|
||||||
std::reference_wrapper<crossover_t> crossover;
|
std::reference_wrapper<crossover_t> crossover;
|
||||||
std::reference_wrapper<population_initializer_t> pop_initializer;
|
std::reference_wrapper<population_initializer_t> pop_initializer;
|
||||||
|
|
||||||
blt::size_t threads = std::thread::hardware_concurrency() - 1;
|
blt::size_t threads = std::thread::hardware_concurrency();
|
||||||
// number of elements each thread should pull per execution. this is for granularity performance and can be optimized for better results!
|
// number of elements each thread should pull per execution. this is for granularity performance and can be optimized for better results!
|
||||||
blt::size_t evaluation_size = 4;
|
blt::size_t evaluation_size = 4;
|
||||||
|
|
||||||
|
|
|
@ -283,9 +283,54 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
current_pop = config.pop_initializer.get().generate(
|
current_pop = config.pop_initializer.get().generate(
|
||||||
{*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size});
|
{*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size});
|
||||||
evaluate_fitness_func = [&fitness_function](tree_t& current_tree, fitness_t& fitness, blt::size_t index) {
|
thread_execution_service = new std::function([this, &fitness_function]() {
|
||||||
fitness_function(current_tree, fitness, index);
|
if (thread_helper.evaluation_left > 0)
|
||||||
};
|
{
|
||||||
|
std::cout << "Thread Incrementing " << thread_helper.threads_left << std::endl;
|
||||||
|
auto old_value_start = thread_helper.threads_left.load(std::memory_order::memory_order_acquire);
|
||||||
|
while (!thread_helper.threads_left.compare_exchange_weak(old_value_start, old_value_start + 1, std::memory_order_release,
|
||||||
|
std::memory_order_relaxed));
|
||||||
|
std::cout << "Thread beginning " << thread_helper.threads_left << std::endl;
|
||||||
|
while (thread_helper.evaluation_left > 0)
|
||||||
|
{
|
||||||
|
blt::size_t begin = 0;
|
||||||
|
blt::size_t end = 0;
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(thread_helper.evaluation_control);
|
||||||
|
end = thread_helper.evaluation_left;
|
||||||
|
auto size = std::min(thread_helper.evaluation_left.load(), config.evaluation_size);
|
||||||
|
begin = thread_helper.evaluation_left - size;
|
||||||
|
thread_helper.evaluation_left -= size;
|
||||||
|
}
|
||||||
|
//std::cout << "Processing " << begin << " to " << end << " with " << thread_helper.evaluation_left << " left" << std::endl;
|
||||||
|
for (blt::size_t i = begin; i < end; i++)
|
||||||
|
{
|
||||||
|
auto& ind = current_pop.get_individuals()[i];
|
||||||
|
|
||||||
|
fitness_function(ind.tree, ind.fitness, i);
|
||||||
|
|
||||||
|
auto old_best = current_stats.best_fitness.load();
|
||||||
|
while (ind.fitness.adjusted_fitness > old_best &&
|
||||||
|
!current_stats.best_fitness.compare_exchange_weak(old_best, ind.fitness.adjusted_fitness,
|
||||||
|
std::memory_order_release, std::memory_order_relaxed));
|
||||||
|
|
||||||
|
auto old_worst = current_stats.worst_fitness.load();
|
||||||
|
while (ind.fitness.adjusted_fitness < old_worst &&
|
||||||
|
!current_stats.worst_fitness.compare_exchange_weak(old_worst, ind.fitness.adjusted_fitness,
|
||||||
|
std::memory_order_release, std::memory_order_relaxed));
|
||||||
|
|
||||||
|
auto old_overall = current_stats.overall_fitness.load();
|
||||||
|
while (!current_stats.overall_fitness.compare_exchange_weak(old_overall, ind.fitness.adjusted_fitness + old_overall,
|
||||||
|
std::memory_order_release, std::memory_order_relaxed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "Thread Decrementing " << thread_helper.threads_left << std::endl;
|
||||||
|
auto old_value = thread_helper.threads_left.load(std::memory_order::memory_order_acquire);
|
||||||
|
while (!thread_helper.threads_left.compare_exchange_weak(old_value, old_value - 1, std::memory_order_release,
|
||||||
|
std::memory_order_relaxed));
|
||||||
|
std::cout << "Thread Ending " << thread_helper.threads_left << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
evaluate_fitness_internal();
|
evaluate_fitness_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,6 +474,9 @@ namespace blt::gp
|
||||||
if (thread->joinable())
|
if (thread->joinable())
|
||||||
thread->join();
|
thread->join();
|
||||||
}
|
}
|
||||||
|
auto* cpy = thread_execution_service.load(std::memory_order_acquire);
|
||||||
|
thread_execution_service = nullptr;
|
||||||
|
delete cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -454,7 +502,7 @@ namespace blt::gp
|
||||||
} thread_helper;
|
} thread_helper;
|
||||||
|
|
||||||
// for convenience, shouldn't decrease performance too much
|
// for convenience, shouldn't decrease performance too much
|
||||||
std::function<void(tree_t&, fitness_t&, blt::size_t)> evaluate_fitness_func;
|
std::atomic<std::function<void()>*> thread_execution_service = nullptr;
|
||||||
|
|
||||||
inline selector_args get_selector_args()
|
inline selector_args get_selector_args()
|
||||||
{
|
{
|
||||||
|
@ -475,40 +523,32 @@ namespace blt::gp
|
||||||
void evaluate_fitness_internal()
|
void evaluate_fitness_internal()
|
||||||
{
|
{
|
||||||
current_stats.clear();
|
current_stats.clear();
|
||||||
|
if (config.threads == 1)
|
||||||
|
{
|
||||||
|
(*thread_execution_service)();
|
||||||
|
} else
|
||||||
|
{
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(thread_helper.evaluation_control);
|
std::scoped_lock lock(thread_helper.evaluation_control);
|
||||||
thread_helper.evaluation_left = current_pop.get_individuals().size();
|
thread_helper.evaluation_left = current_pop.get_individuals().size();
|
||||||
thread_helper.threads_left = static_cast<blt::i64>(config.threads) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::cout << "Wait" << std::endl;
|
std::cout << "Func" << std::endl;
|
||||||
execute_thread();
|
while (thread_execution_service == nullptr)
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
std::cout << "Wait" << std::endl;
|
||||||
|
(*thread_execution_service)();
|
||||||
|
std::cout << "FINSIHED WAITING!!!!!!!! " << thread_helper.threads_left << std::endl;
|
||||||
while (thread_helper.threads_left > 0)
|
while (thread_helper.threads_left > 0)
|
||||||
std::this_thread::yield();
|
{
|
||||||
//std::cout << "Finished" << std::endl;
|
//std::cout << thread_helper.threads_left << std::endl;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
// for (auto& ind : current_pop.get_individuals())
|
}
|
||||||
// {
|
std::cout << "Finished" << std::endl;
|
||||||
// if (ind.fitness.adjusted_fitness > current_stats.best_fitness)
|
}
|
||||||
// {
|
|
||||||
// current_stats.best_fitness = ind.fitness.adjusted_fitness;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (ind.fitness.adjusted_fitness < current_stats.worst_fitness)
|
|
||||||
// {
|
|
||||||
// current_stats.worst_fitness = ind.fitness.adjusted_fitness;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// current_stats.overall_fitness = current_stats.overall_fitness + ind.fitness.adjusted_fitness;
|
|
||||||
// }
|
|
||||||
|
|
||||||
current_stats.average_fitness = current_stats.overall_fitness / static_cast<double>(config.population_size);
|
current_stats.average_fitness = current_stats.overall_fitness / static_cast<double>(config.population_size);
|
||||||
//
|
|
||||||
// BLT_INFO("Stats:");
|
|
||||||
// BLT_INFO("Average fitness: %lf", current_stats.average_fitness.load());
|
|
||||||
// BLT_INFO("Best fitness: %lf", current_stats.best_fitness.load());
|
|
||||||
// BLT_INFO("Worst fitness: %lf", current_stats.worst_fitness.load());
|
|
||||||
// BLT_INFO("Overall fitness: %lf", current_stats.overall_fitness.load());
|
|
||||||
|
|
||||||
/*current_stats = {};
|
/*current_stats = {};
|
||||||
for (const auto& ind : blt::enumerate(current_pop.get_individuals()))
|
for (const auto& ind : blt::enumerate(current_pop.get_individuals()))
|
||||||
|
|
|
@ -53,13 +53,16 @@ namespace blt::gp
|
||||||
void gp_program::create_threads()
|
void gp_program::create_threads()
|
||||||
{
|
{
|
||||||
if (config.threads == 0)
|
if (config.threads == 0)
|
||||||
config.set_thread_count(std::thread::hardware_concurrency() - 1);
|
config.set_thread_count(std::thread::hardware_concurrency());
|
||||||
for (blt::size_t i = 0; i < config.threads; i++)
|
// main thread is thread0
|
||||||
|
for (blt::size_t i = 1; i < config.threads; i++)
|
||||||
{
|
{
|
||||||
thread_helper.threads.emplace_back(new std::thread([this]() {
|
thread_helper.threads.emplace_back(new std::thread([this]() {
|
||||||
while (!should_thread_terminate())
|
while (!should_thread_terminate())
|
||||||
{
|
{
|
||||||
execute_thread();
|
if (thread_execution_service != nullptr)
|
||||||
|
(*thread_execution_service)();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -69,7 +72,7 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
if (thread_helper.evaluation_left > 0)
|
if (thread_helper.evaluation_left > 0)
|
||||||
{
|
{
|
||||||
//std::cout << "Thread beginning" << std::endl;
|
std::cout << "Thread beginning" << std::endl;
|
||||||
while (thread_helper.evaluation_left > 0)
|
while (thread_helper.evaluation_left > 0)
|
||||||
{
|
{
|
||||||
blt::size_t begin = 0;
|
blt::size_t begin = 0;
|
||||||
|
@ -81,12 +84,12 @@ namespace blt::gp
|
||||||
begin = thread_helper.evaluation_left - size;
|
begin = thread_helper.evaluation_left - size;
|
||||||
thread_helper.evaluation_left -= size;
|
thread_helper.evaluation_left -= size;
|
||||||
}
|
}
|
||||||
//std::cout << "Processing " << begin << " to " << end << " with " << thread_helper.evaluation_left << " left" << std::endl;
|
std::cout << "Processing " << begin << " to " << end << " with " << thread_helper.evaluation_left << " left" << std::endl;
|
||||||
for (blt::size_t i = begin; i < end; i++)
|
for (blt::size_t i = begin; i < end; i++)
|
||||||
{
|
{
|
||||||
auto& ind = current_pop.get_individuals()[i];
|
auto& ind = current_pop.get_individuals()[i];
|
||||||
|
|
||||||
evaluate_fitness_func(ind.tree, ind.fitness, i);
|
//evaluate_fitness_func(ind.tree, ind.fitness, i);
|
||||||
|
|
||||||
auto old_best = current_stats.best_fitness.load();
|
auto old_best = current_stats.best_fitness.load();
|
||||||
while (ind.fitness.adjusted_fitness > old_best &&
|
while (ind.fitness.adjusted_fitness > old_best &&
|
||||||
|
@ -104,7 +107,7 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thread_helper.threads_left--;
|
thread_helper.threads_left--;
|
||||||
//std::cout << "thread finished!" << std::endl;
|
std::cout << "thread finished!" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue