diff --git a/CMakeLists.txt b/CMakeLists.txt index 70ddf99..2732297 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,17 @@ cmake_minimum_required(VERSION 3.3) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_FLAGS "-Wall -Wextra") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_RELEASE "-O3") +#set(CMAKE_CXX_FLAGS_RELEASE "-march=native") + +find_package(Threads REQUIRED) + add_executable(main main.cpp) +target_link_libraries(main Threads::Threads) set(SOURCE_EXE main.cpp ) diff --git a/main.cpp b/main.cpp index 48c731d..1fd98e1 100644 --- a/main.cpp +++ b/main.cpp @@ -11,7 +11,10 @@ #include #include #include - +#include +#include +#include +#include #include "finite_function.hpp" @@ -254,54 +257,39 @@ set> generate_function_class(FiniteFunction base_func return set>(func_class.begin(), func_class.end()); } -int main() { - auto FiniteFunctionHasher = [](const FiniteFunction &f) -> uint32_t { - return f.get_hash(); - }; +vector > possible_functions; +size_t total_possible_functions; +atomic current_function; +mutex possible_functions_mutex; - auto funcs = get_funcs(); - cout << "Removing permutations " << funcs.size() << " functions" << endl; - /*vector> permutations; - get_permutations<3>(permutations); - string function_to_str("000 112 212"); - cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[1]) << endl; - cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[2]) << endl; - cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[3]) << endl; - cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[4]) << endl; - cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[5]) << endl; - */ - //cout << "022_210_002 -> " << FiniteFunction<3>(string("022 210 002")) << endl; - - //set> allowed_functions(funcs.begin(), funcs.end()); - list< set> > function_classes; - unordered_set< - FiniteFunction, - decltype(FiniteFunctionHasher) - > allowed_functions(funcs.begin(), funcs.end(), 128, FiniteFunctionHasher); +list< set> > shared_function_classes; +mutex shared_functions_mutex; +void do_work() { + list< set> > local_function_classes; + FiniteFunction identical_x(string("000 111 222")); FiniteFunction identical_y(string("012 012 012")); - - allowed_functions.erase(identical_x); - allowed_functions.erase(identical_y); - - cout << "Total " << allowed_functions.size() << " functions" << endl; - std::ofstream f_all_out("all_classes.txt"); - while ( allowed_functions.size() > 0 ) { - //if (allowed_functions.size() % 10 == 0) - //cout << 100 - allowed_functions.size() * 100. / funcs.size() << "%" << endl; - auto base_function = *allowed_functions.begin(); - - allowed_functions.erase(base_function); + + while ( true ) { + possible_functions_mutex.lock(); + if ( current_function >= total_possible_functions ) { + possible_functions_mutex.unlock(); + break; + } + FiniteFunction base_function = possible_functions.at( + current_function + ); + ++current_function; + possible_functions_mutex.unlock(); + set< FiniteFunction > func_class = generate_function_class(base_function); func_class.erase(identical_x); func_class.erase(identical_y); - //f_all_out << base_function << " -> "; - //write_function_class(f_all_out, func_class.begin(), func_class.end()); bool is_need_append = true; - vector functions_to_remove; - for (auto it = function_classes.begin(); it != function_classes.end(); ++it) { + vector functions_to_remove; + for (auto it = local_function_classes.begin(); it != local_function_classes.end(); ++it) { if ( func_class.size() < it->size() ) { if (includes( it->begin(), @@ -328,15 +316,111 @@ int main() { } } if ( is_need_append ) - function_classes.push_back(func_class); + local_function_classes.push_back(func_class); for (auto&& to_remove: functions_to_remove) - function_classes.erase(to_remove); + local_function_classes.erase(to_remove); } - cout << function_classes.size() << " functions!" << endl; + + cout << "local " << this_thread::get_id() << ": " + << local_function_classes.size() << " functions" << endl; + + // Сливаем всё вметсе + shared_functions_mutex.lock(); + for (auto it_local = local_function_classes.begin(); it_local != local_function_classes.end(); ++it_local) { + auto func_class = *it_local; + bool is_need_append = true; + vector functions_to_remove; + for (auto it = shared_function_classes.begin(); it != shared_function_classes.end(); ++it) { + if ( func_class.size() < it->size() ) { + if (includes( + it->begin(), + it->end(), + func_class.begin(), + func_class.end() + ) + ) { + // новый класс функций часть уже существующего + functions_to_remove.push_back(it); + } + } else { + if (includes( + func_class.begin(), + func_class.end(), + it->begin(), + it->end() + ) + ) { + // новый класс функций надмножество существующего + is_need_append = false; + break; + } + } + } + if ( is_need_append ) + shared_function_classes.push_back(func_class); + for (auto&& to_remove: functions_to_remove) + shared_function_classes.erase(to_remove); + } + shared_functions_mutex.unlock(); + cout << "shared_functions_mutex unlocked" << endl; +} + +int main() { + auto FiniteFunctionHasher = [](const FiniteFunction &f) -> uint32_t { + return f.get_hash(); + }; + + auto THREADS_COUNT = thread::hardware_concurrency(); + cout << "Using " << THREADS_COUNT << " threads" << endl; + + auto funcs = get_funcs(); + cout << "Removing permutations " << funcs.size() << " functions" << endl; + /*vector> permutations; + get_permutations<3>(permutations); + string function_to_str("000 112 212"); + cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[1]) << endl; + cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[2]) << endl; + cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[3]) << endl; + cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[4]) << endl; + cout << FiniteFunction<3>(function_to_str).apply_permutation(permutations[5]) << endl; + */ + //cout << "022_210_002 -> " << FiniteFunction<3>(string("022 210 002")) << endl; + + list< set> > function_classes; + unordered_set< + FiniteFunction, + decltype(FiniteFunctionHasher) + > allowed_functions(funcs.begin(), funcs.end(), 128, FiniteFunctionHasher); + + FiniteFunction identical_x(string("000 111 222")); + FiniteFunction identical_y(string("012 012 012")); + + allowed_functions.erase(identical_x); + allowed_functions.erase(identical_y); + cout << "Total allowed " << allowed_functions.size() << " functions" << endl; + + copy( + allowed_functions.begin(), + allowed_functions.end(), + back_inserter(possible_functions) + ); + + total_possible_functions = possible_functions.size(); + current_function = 0; + + vector< thread > thread_pool; + + for (size_t i = 0; i < THREADS_COUNT; ++i) + thread_pool.push_back(thread(do_work)); + + for (auto&& t: thread_pool) + t.join(); + + cout << "Shared " << shared_function_classes.size() << " functions!" << endl; // перегоняем список с классами в массив с классами vector< set> > vector_classes( - function_classes.begin(), - function_classes.end() + shared_function_classes.begin(), + shared_function_classes.end() ); /*// фильтруем перестановки vector> permutations;