Multihtreading added

This commit is contained in:
2018-04-19 18:08:43 +03:00
parent 3a8916e0fc
commit 23f18e9e15
2 changed files with 143 additions and 45 deletions

View File

@@ -1,3 +1,17 @@
cmake_minimum_required(VERSION 3.3) 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) add_executable(main main.cpp)
target_link_libraries(main Threads::Threads)
set(SOURCE_EXE main.cpp ) set(SOURCE_EXE main.cpp )

168
main.cpp
View File

@@ -11,7 +11,10 @@
#include <functional> #include <functional>
#include <list> #include <list>
#include <cctype> #include <cctype>
#include <thread>
#include <mutex>
#include <atomic>
#include <iterator>
#include "finite_function.hpp" #include "finite_function.hpp"
@@ -254,54 +257,39 @@ set<FiniteFunction<BASE>> generate_function_class(FiniteFunction<BASE> base_func
return set<FiniteFunction<BASE>>(func_class.begin(), func_class.end()); return set<FiniteFunction<BASE>>(func_class.begin(), func_class.end());
} }
int main() { vector <FiniteFunction<CUR_BASE>> possible_functions;
auto FiniteFunctionHasher = [](const FiniteFunction<CUR_BASE> &f) -> uint32_t { size_t total_possible_functions;
return f.get_hash(); atomic<long> current_function;
}; mutex possible_functions_mutex;
auto funcs = get_funcs<CUR_BASE>(); list< set<FiniteFunction<CUR_BASE>> > shared_function_classes;
cout << "Removing permutations " << funcs.size() << " functions" << endl; mutex shared_functions_mutex;
/*vector<array<int, 3>> 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<FiniteFunction<3>> allowed_functions(funcs.begin(), funcs.end()); void do_work() {
list< set<FiniteFunction<CUR_BASE>> > function_classes; list< set<FiniteFunction<CUR_BASE>> > local_function_classes;
unordered_set<
FiniteFunction<CUR_BASE>,
decltype(FiniteFunctionHasher)
> allowed_functions(funcs.begin(), funcs.end(), 128, FiniteFunctionHasher);
FiniteFunction<CUR_BASE> identical_x(string("000 111 222")); FiniteFunction<CUR_BASE> identical_x(string("000 111 222"));
FiniteFunction<CUR_BASE> identical_y(string("012 012 012")); FiniteFunction<CUR_BASE> identical_y(string("012 012 012"));
allowed_functions.erase(identical_x); while ( true ) {
allowed_functions.erase(identical_y); possible_functions_mutex.lock();
if ( current_function >= total_possible_functions ) {
possible_functions_mutex.unlock();
break;
}
FiniteFunction<CUR_BASE> base_function = possible_functions.at(
current_function
);
++current_function;
possible_functions_mutex.unlock();
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);
set< FiniteFunction<CUR_BASE> > func_class = generate_function_class(base_function); set< FiniteFunction<CUR_BASE> > func_class = generate_function_class(base_function);
func_class.erase(identical_x); func_class.erase(identical_x);
func_class.erase(identical_y); 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; bool is_need_append = true;
vector<decltype(function_classes)::iterator> functions_to_remove; vector<decltype(local_function_classes)::iterator> functions_to_remove;
for (auto it = function_classes.begin(); it != function_classes.end(); ++it) { for (auto it = local_function_classes.begin(); it != local_function_classes.end(); ++it) {
if ( func_class.size() < it->size() ) { if ( func_class.size() < it->size() ) {
if (includes( if (includes(
it->begin(), it->begin(),
@@ -328,15 +316,111 @@ int main() {
} }
} }
if ( is_need_append ) if ( is_need_append )
function_classes.push_back(func_class); local_function_classes.push_back(func_class);
for (auto&& to_remove: functions_to_remove) 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<decltype(local_function_classes)::iterator> 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<CUR_BASE> &f) -> uint32_t {
return f.get_hash();
};
auto THREADS_COUNT = thread::hardware_concurrency();
cout << "Using " << THREADS_COUNT << " threads" << endl;
auto funcs = get_funcs<CUR_BASE>();
cout << "Removing permutations " << funcs.size() << " functions" << endl;
/*vector<array<int, 3>> 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<FiniteFunction<CUR_BASE>> > function_classes;
unordered_set<
FiniteFunction<CUR_BASE>,
decltype(FiniteFunctionHasher)
> allowed_functions(funcs.begin(), funcs.end(), 128, FiniteFunctionHasher);
FiniteFunction<CUR_BASE> identical_x(string("000 111 222"));
FiniteFunction<CUR_BASE> 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<FiniteFunction<CUR_BASE>> > vector_classes( vector< set<FiniteFunction<CUR_BASE>> > vector_classes(
function_classes.begin(), shared_function_classes.begin(),
function_classes.end() shared_function_classes.end()
); );
/*// фильтруем перестановки /*// фильтруем перестановки
vector<array<int, CUR_BASE>> permutations; vector<array<int, CUR_BASE>> permutations;