Quantcast
Channel: GameDev.net
Viewing all articles
Browse latest Browse all 17825

What is wrong with my thread pool?

$
0
0
I have written a mathy simulation and introduced parallel computing using the available cpu cores - based on a simple thread pool written in C++/11. At the very start it seemed to work, but then it starts to freeze reproducable after some frames - but sometimes it works just fine. But i have absolutly no clue why it wont work... Can someone can look into that? Its not that much code. I looking at the code since hours and cannot figure out what is wrong... Here is the code: #include <thread> #include <mutex> #include <condition_variable> #include <vector> #include <deque> #include <atomic> struct ThreadPoolTask { size_t startIndex; size_t endIndex; float deltaTime; uint8_t padding0[4]; std::function<void(const size_t, const size_t, const float)> func; }; struct ThreadPool { std::atomic<bool> stopped; std::vector<std::thread> threads; std::atomic<int> pendingCount; std::deque<ThreadPoolTask> queue; std::mutex queueMutex; std::mutex completeMutex; std::condition_variable queueSignal; std::condition_variable completeSignal; ThreadPool(const size_t threadCount = std::thread::hardware_concurrency()); ~ThreadPool(); void AddTask(const ThreadPoolTask &task); void WaitUntilDone(); void WorkerThreadProc(); void CreateTasks(const size_t itemCount, const std::function<void(const size_t, const size_t, const float)> &function, const float deltaTime); }; ThreadPool::ThreadPool(const size_t threadCount) : stopped(false), pendingCount(0) { for (size_t workerIndex = 0; workerIndex < threadCount; ++workerIndex) { threads.push_back(std::thread(&ThreadPool::WorkerThreadProc, this)); } } ThreadPool::~ThreadPool() { stopped = true; queueSignal.notify_all(); for (size_t workerIndex = 0; workerIndex < threads.size(); ++workerIndex) threads[workerIndex].join(); } void ThreadPool::AddWork(const ThreadPoolTask &entry) { { std::unique_lock<std::mutex> lock(queueMutex); queue.push_back(entry); } pendingCount++; } void ThreadPool::WaitUntilDone() { queueSignal.notify_all(); std::unique_lock<std::mutex> lock(completeMutex); while (pendingCount > 0) { completeSignal.wait(lock); } } void ThreadPool::WorkerThreadProc() { ThreadPoolTask group; while (!stopped) { { std::unique_lock<std::mutex> lock(queueMutex); while (queue.empty()) { queueSignal.wait(lock); } group = queue.front(); queue.pop_front(); } group.func(group.startIndex, group.endIndex, group.deltaTime); if (--pendingCount == 0) { completeSignal.notify_one(); } } } void ThreadPool::CreateTasks(const size_t itemCount, const std::function<void(const size_t, const size_t, const float)> &function, const float deltaTime) { if (itemCount > 0) { const size_t itemsPerTask = std::max((size_t)1, itemCount / threads.size()); ThreadPoolTask task = {}; task.func = function; task.deltaTime = deltaTime; for (size_t itemIndex = 0; itemIndex < itemCount; itemIndex += itemsPerTask) { task.startIndex = itemIndex; task.endIndex = std::min(itemIndex + itemsPerTask - 1, itemCount - 1); AddTask(task); } } } void main() { workerPool.CreateTasks(itemCount, [=](const size_t startIndex, const size_t endIndex, const float deltaTime) { this->DoingSomeMathyWork(startIndex, endIndex, deltaTime); }, deltaTime); workerPool.WaitUntilDone(); }

Viewing all articles
Browse latest Browse all 17825

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>