nvidia-texture-tools/src/nvthread/ParallelFor.cpp

62 lines
1.3 KiB
C++
Raw Normal View History

2011-09-27 17:48:46 +00:00
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
#include "ParallelFor.h"
#include "Thread.h"
#include "Atomic.h"
#include "ThreadPool.h"
2011-10-11 18:52:24 +00:00
#include "nvcore/Utils.h" // toI32
2011-09-27 17:48:46 +00:00
using namespace nv;
2012-02-14 16:35:42 +00:00
#define ENABLE_PARALLEL_FOR 1
2011-09-27 17:48:46 +00:00
2015-10-29 06:53:08 +00:00
static void worker(void * arg, int tid) {
2011-09-27 17:48:46 +00:00
ParallelFor * owner = (ParallelFor *)arg;
while(true) {
2015-10-29 06:53:08 +00:00
uint new_idx = atomicFetchAndAdd(&owner->idx, owner->step);
if (new_idx >= owner->count) {
2011-09-27 17:48:46 +00:00
break;
}
2015-10-29 06:53:08 +00:00
const uint count = min(owner->count, new_idx + owner->step);
for (uint i = new_idx; i < count; i++) {
owner->task(owner->context, /*tid, */i);
}
}
2011-09-27 17:48:46 +00:00
}
ParallelFor::ParallelFor(ForTask * task, void * context) : task(task), context(context) {
#if ENABLE_PARALLEL_FOR
pool = ThreadPool::acquire();
#endif
}
ParallelFor::~ParallelFor() {
#if ENABLE_PARALLEL_FOR
ThreadPool::release(pool);
#endif
}
2015-10-29 06:53:08 +00:00
void ParallelFor::run(uint count, uint step/*= 1*/) {
2011-09-27 17:48:46 +00:00
#if ENABLE_PARALLEL_FOR
storeRelease(&this->count, count);
2015-10-29 06:53:08 +00:00
storeRelease(&this->step, step);
2011-09-27 17:48:46 +00:00
// Init atomic counter to zero.
storeRelease(&idx, 0);
// Start threads.
2015-10-29 06:53:08 +00:00
pool->run(worker, this);
2011-09-27 17:48:46 +00:00
nvDebugCheck(idx >= count);
#else
2011-10-11 18:52:24 +00:00
for (int i = 0; i < toI32(count); i++) {
2011-09-27 17:48:46 +00:00
task(context, i);
}
#endif
}