1
0
mirror of https://github.com/bshoshany/thread-pool.git synced 2026-07-30 07:23:01 +04:00

Updated to v1.3

This commit is contained in:
Barak Shoshany
2021-05-03 21:33:43 -04:00
parent 27b2dbc130
commit b448742337
2 changed files with 189 additions and 53 deletions
+21 -20
View File
@@ -3,12 +3,12 @@
/**
* @file thread_pool.hpp
* @author Barak Shoshany (baraksh@gmail.com) (http://baraksh.com)
* @version 1.2
* @date 2021-04-29
* @copyright Copyright (c) 2021 Barak Shoshany. Licensed under the MIT license. If you use this class in your code, please acknowledge the author and provide a link to the GitHub repository. Thank you!
* @version 1.3
* @date 2021-05-03
* @copyright Copyright (c) 2021 Barak Shoshany. Licensed under the MIT license. If you found this code useful, please consider providing a link to the GitHub repository: https://github.com/bshoshany/thread-pool and/or citing the companion paper: https://arxiv.org/abs/2105.00613
*
* @brief A simple but powerful C++17 thread pool class.
* @details This class was built from scratch with maximum performance in mind, and is suitable for use in high-performance computing clusters with a very large number of CPU cores. It is compact and self-contained, and includes features such as automatic generation of futures and easy parallelization of loops. Two helper classes enable synchronizing printing to an output stream by different threads and measuring execution time for benchmarking purposes. Please visit the GitHub repository at https://github.com/bshoshany/thread-pool for documentation and updates, or to submit feature requests and bug reports.
* @brief A C++17 thread pool for high-performance scientific computing.
* @details A modern C++17-compatible thread pool implementation, built from scratch with high-performance scientific computing in mind. The thread pool is implemented as a single lightweight and self-contained class, and does not have any dependencies other than the C++17 standard library, thus allowing a great degree of portability. In particular, this implementation does not utilize OpenMP or any other high-level multithreading APIs, and thus gives the programmer precise low-level control over the details of the parallelization, which permits more robust optimizations. The thread pool was extensively tested on both AMD and Intel CPUs with up to 40 cores and 80 threads. Other features include automatic generation of futures and easy parallelization of loops. Two helper classes enable synchronizing printing to an output stream by different threads and measuring execution time for benchmarking purposes. Please visit the GitHub repository for documentation and updates, or to submit feature requests and bug reports.
*/
#include <algorithm> // std::max
@@ -103,13 +103,13 @@ public:
{
T start = (T)(t * block_size + first_index);
T end = (t == num_tasks - 1) ? last_index : (T)((t + 1) * block_size + first_index - 1);
std::cout << start << '-' << end << '\n';
blocks_running++;
push_task([&start, &end, &loop, &blocks_running] {
for (T i = start; i <= end; i++)
loop(i);
blocks_running--;
});
push_task([start, end, &loop, &blocks_running]
{
for (T i = start; i <= end; i++)
loop(i);
blocks_running--;
});
while (blocks_running != 0)
{
std::this_thread::yield();
@@ -129,7 +129,7 @@ public:
tasks_waiting++;
{
const std::scoped_lock lock(queue_mutex);
tasks.push(std::move(std::function<void()>(task)));
tasks.push(std::function<void()>(task));
}
}
@@ -145,7 +145,8 @@ public:
template <typename F, typename... A>
void push_task(const F &task, const A &...args)
{
push_task([task, args...] { task(args...); });
push_task([task, args...]
{ task(args...); });
}
/**
@@ -178,10 +179,11 @@ public:
{
std::shared_ptr<std::promise<bool>> promise(new std::promise<bool>);
std::future<bool> future = promise->get_future();
push_task([task, args..., promise] {
task(args...);
promise->set_value(true);
});
push_task([task, args..., promise]
{
task(args...);
promise->set_value(true);
});
return future;
}
@@ -200,9 +202,8 @@ public:
{
std::shared_ptr<std::promise<R>> promise(new std::promise<R>);
std::future<R> future = promise->get_future();
push_task([task, args..., promise] {
promise->set_value(task(args...));
});
push_task([task, args..., promise]
{ promise->set_value(task(args...)); });
return future;
}