(C++ : Concurrency-1-4) Thread의 유용한 함수

Posted by : at

Category : Cpp



Some useful operations on thread

#include <iostream>
#include <thread>
#include <chrono>

void run_code1()
{
	std::cout << "Allowed max number of parallel threads : "
		<< std::thread::hardware_concurrency() << std::endl;
}

void func_1()
{
	std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	std::cout << "new  thread id : " << std::this_thread::get_id() << std::endl;
}

void run_code2()
{
	std::thread thread_1(func_1);

	std::cout << "thread_1 id before joining : " << thread_1.get_id() << std::endl;
	thread_1.join();

	std::thread thread_2;

	std::cout << "default consturcted thread id : " << thread_2.get_id() << std::endl;
	std::cout << "thread_1 id after joining : " << thread_1.get_id() << std::endl;
	std::cout << "Main thread id : " << std::this_thread::get_id() << std::endl;

	std::cout << "\n\nAllowed max number of parallel threads : "
		<< std::thread::hardware_concurrency() << std::endl;
}

int main()
{
	run_code1();	 // example 1
	//run_code2();	 // example 2
}


Parallel accumulate - algorithm explanation

// std::accumulate 역할
void sequntial_accumulate_test()
{
	std::vector<int> v{1,2,3,4,5,6,7,8,9,10};
	int sum = std::accumulate(v.begin(), v.end(), 0);		// 덧셈 가능(함수를 별도로 기입안할경우 더하기)
	int product = std::accumulate(v.begin(), v.end(), 1, 
									std::multiplies<int>());	// 함수는 이걸써달라(곱셈)

	auto dash_fold = [](std::string a, int b)
	{
		return std::move(a) + "-" + std::to_string(b);
	};

	std::string s = std::accumulate(std::next(v.begin()), v.end(), // 여기서 여기까지
									std::to_string(v[0]), // 이 시작숫자로
									dash_fold);			  // 이 함수를 통해 accumulate

	std::cout << "sum - " << sum << "\n";
	std::cout << "product - " << product << "\n";
	std::cout << "dash fold - " << s << "\n";
}
sum - 55
product - 3628800
dash fold - 1-2-3-4-5-6-7-8-9-10

accumulate를 parrallel로 구현
사용가능한 최대 Thread를 찾고 더하기 진행하는 코드라 생각

#include <iostream>
#include <thread>
#include <stdexcept>

#include "parallel_accumulate.h"

int  main()
{
	int result = 0;
	std::vector<int> vec(10000);
	for (int i = 0; i < 10000; i++)
		vec[i] = 2;

	parallel_accumulate(vec.begin(), vec.end(), result);

	std::cout << "final result = " << result << std::endl;
}
#pragma once

#include <thread>
#include <numeric>
#include <algorithm>
#include <vector>
#include <functional>

template<typename iterator, typename T>
void accumulate(iterator first, iterator last, T& val)
{
	val = std::accumulate(first, last, val);
}

template<typename iterator, typename T>
void parallel_accumulate(iterator start, iterator end, T& ref)
{
	unsigned MIN_BLOCK_SIZE = 1000;

	unsigned distance = std::distance(start, end);
	unsigned allowed_threads_by_elements = (distance + 1) / MIN_BLOCK_SIZE;
	unsigned allowed_threads_by_hardware = std::thread::hardware_concurrency();

	// this is due to the fact that some operating system may 
	// return 0 to indicate that this has not implemented
	if (allowed_threads_by_hardware < 1)
		allowed_threads_by_hardware = 2;

	unsigned allowed_threads = std::min(allowed_threads_by_elements,
		allowed_threads_by_hardware);

	//caculating the block size 
	unsigned block_size = (distance + 1) / allowed_threads;

	std::vector<T> results(allowed_threads);
	std::vector<std::thread> threads(allowed_threads - 1);

	//iterate and craeting new threads to calculate sum for each blocks
	iterator last;
	for (unsigned i = 0; i < allowed_threads - 1; i++)
	{
		last = start;
		std::advance(last, block_size);
		threads[i] = std::thread(accumulate<iterator, T>, start, last,
			std::ref(results[i]));
		start = last;
	}

	//final block will be calculated from this thread
	results[allowed_threads - 1] =
		std::accumulate(start, end, results[allowed_threads - 1]);

	//calling join on the newly craeted threads
	for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
	ref = std::accumulate(results.begin(), results.end(), ref);
}


About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links