Skip to content

Instantly share code, notes, and snippets.

@borisbat
Last active August 29, 2015 14:22
Show Gist options
  • Save borisbat/f24e906694510ab35200 to your computer and use it in GitHub Desktop.
Save borisbat/f24e906694510ab35200 to your computer and use it in GitHub Desktop.
// this will split the work between all available threads
// if chunk_count is -1, default number of chunks will be computed
void JobQue::parallel_for ( int from, int to, const JobChunk & chunk, int chunk_count, int step )
{
if ( from >= to )
return;
// so the idea here is that if say 1 thread is busy
// we don't pay 2x time. smaller chunks are more evenly distributed
if ( chunk_count==-1 )
chunk_count = mThreadCount * 4;
// adjust step
step = max ( ( to - from + 1 ) / chunk_count, step );
int numChunks = (to - from + step) / step;
// if only one chunk
if ( numChunks==1 )
{
chunk(from, to);
return;
}
// results
int onMainThread = max ( (numChunks + mThreadCount) / (mThreadCount+1), 1 );
int onThreads = numChunks - onMainThread;
vector<JobStatus> status(onThreads);
// que parallel ones
for ( int ch = 0; ch < onThreads; ++ch )
{
int i0 = from + ch * step;
int i1 = min(i0 + step, to);
push([=,&chunk,&status](){
PROFILE_BLOCKI("Main","PFor",0xff3f3f3f);
chunk(i0, i1);
status[ch].Notify();
});
}
// run the tail
for ( int ch = onThreads; ch < numChunks; ++ch )
{
int i0 = from + ch * step;
int i1 = min(i0 + step, to);
chunk(i0, i1);
}
// and wait for them (but last one)
{
PROFILE_BLOCKI("Main","WaitForPFor",0xffff0000);
for ( int i=0; i<onThreads; ++i)
status[i].Wait();
}
}
@borisbat
Copy link
Author

borisbat commented Jun 6, 2015

parallel_for take 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment