Last active
January 18, 2021 20:33
-
-
Save codemonkey-uk/03888e9e752af4f28b7934beeab37aba to your computer and use it in GitHub Desktop.
quickly thrown together parallel_for.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <thread> | |
#include <mutex> | |
#include <algorithm> | |
// | |
// my sketchy parallel_for | |
// use: | |
// | |
// parallel_for(your_container, [&](auto & i) | |
// { | |
// remember to use a critical section around your result collection | |
// dont change the container or its contents in the loop | |
// return false == break - but be warned you only break out of one chunk | |
// return true == continue | |
// }); | |
// | |
template< typename Container, typename Func > | |
void parallel_for(const Container& c, Func f) | |
{ | |
if (!c.empty()) | |
{ | |
const size_t nthreads = std::min<size_t>( | |
c.size(), | |
std::thread::hardware_concurrency() | |
); | |
std::thread threads[nthreads-1]; | |
auto loop = [&] | |
(typename Container::const_iterator first, typename Container::const_iterator last) | |
{ | |
// loop over subset of items | |
for(auto i = first; i!=last; i++) | |
{ | |
if (!f(i)) break; | |
} | |
}; | |
auto itr = c.begin(); | |
if (nthreads>1) | |
{ | |
// divide work int chunks over n cores (including this one) | |
const int chunksize = c.size()/nthreads; | |
const int remainder = c.size()%nthreads; | |
// kick of threads for all other cores | |
int t = 0; | |
for(;t<remainder;t++) | |
{ | |
auto first = itr; | |
std::advance(itr, chunksize+1); | |
threads[t] = std::thread(std::bind(loop, first, itr)); | |
} | |
for(;t<nthreads-1;t++) | |
{ | |
auto first = itr; | |
std::advance(itr, chunksize); | |
threads[t] = std::thread(std::bind(loop, first, itr)); | |
} | |
assert(std::distance(itr ,c.end())>=1); | |
assert(std::distance(itr ,c.end())<=chunksize); | |
} | |
// finish in current thread | |
loop(itr ,c.end()); | |
// wait for all the other threads to complete | |
for(auto& x : threads) | |
{ | |
x.join(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment