Here is my attempt to perform the sum of elements between two iterators, with n threads , using C++11 std::thread `s.
It appears to work correctly, with odd, even or zero length of input.
Code:
namespace mm
{
template<typename Iterator, typename T>
T sum(Iterator begin, Iterator end, T& t) // It could do without the reference..added for easy thread operations below
{
while(begin!=end)
{
t+=*begin++;
}
return t;
}
template<typename Iterator, typename T >
T threaded_sum(Iterator begin, Iterator end,T& t,short int n = std::thread::hardware_concurrency())
{
if(n<1)n=2;//n == no. of threads
int span = (end-begin)/n; //Length of the array handled by all but the nth thread
std::vector<std::pair<Iterator,Iterator>> work;//Begin,end iterators for each thread
Iterator temp;//for retaining the begin iterator for the last thread
for(int i=0; i< n-1 ; ++i)
{
static Iterator x(begin),y;
y = x+span;
work.push_back({x,y});
x = y;
temp = y;
}
work.push_back({temp,end}); //Done out of the loop to include remainders
std::vector<T> results(n);
std::vector<std::thread> threads;
for(int i=0;i<n;++i)
{
threads.push_back
(
std::thread
(
sum<Iterator,T>,
work[i].first,
work[i].second,
std::ref(results[i])
)
);
}
for(auto& x:threads)x.join();
sum(results.begin(),results.end(),t);
return t;
}
}
Usage:
Code:
int main()
{
std::vector<int> foo = {1,2,3,4,5,6,7,8,9,10};
int x(0);
std::cout<<mm::threaded_sum(foo.begin(),foo.end(),x);
return 0;
}
[Edit]Don't forget the C++11 and pthread flags if any of you want to compile the code.[/Edit]
I'm seriously starting to learn about concurrent programming from scratch after some half-hearted attempts for the past months and realizing that it is a whole new paradigm for me and not just another API.
(Some library/Language independent book recommendations would be great !)