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

3 Commits

Author SHA1 Message Date
Barak Shoshany 910f7cd95b Updated to v1.7 2021-06-02 10:38:24 -04:00
Barak Shoshany bc66b8a222 Updated to v1.6 2021-05-26 09:00:51 -04:00
Barak Shoshany 31efea058c Updated to v1.5 2021-05-07 22:03:49 -04:00
3 changed files with 570 additions and 528 deletions
+46 -9
View File
@@ -1,10 +1,20 @@
[![DOI:10.5281/zenodo.4742687](https://zenodo.org/badge/DOI/10.5281/zenodo.4742687.svg)](https://doi.org/10.5281/zenodo.4742687)
[![arXiv:2105.00613](https://img.shields.io/badge/arXiv-2105.00613-b31b1b.svg)](https://arxiv.org/abs/2105.00613)
[![License: MIT](https://img.shields.io/github/license/bshoshany/thread-pool)](https://github.com/bshoshany/thread-pool/blob/master/LICENSE.txt)
![Language: C++17](https://img.shields.io/badge/Language-C%2B%2B17-yellow)
![File size in bytes](https://img.shields.io/github/size/bshoshany/thread-pool/thread_pool.hpp)
![GitHub last commit](https://img.shields.io/github/last-commit/bshoshany/thread-pool)
[![GitHub repo stars](https://img.shields.io/github/stars/bshoshany/thread-pool?style=social)](https://github.com/bshoshany/thread-pool)
[![Twitter @BarakShoshany](https://img.shields.io/twitter/follow/BarakShoshany?style=social)](https://twitter.com/BarakShoshany)
# A C++17 Thread Pool for High-Performance Scientific Computing # A C++17 Thread Pool for High-Performance Scientific Computing
**Barak Shoshany**\ **Barak Shoshany**\
Department of Physics, Brock University,\ Department of Physics, Brock University,\
1812 Sir Isaac Brock Way, St. Catharines, Ontario, L2S 3A1, Canada\ 1812 Sir Isaac Brock Way, St. Catharines, Ontario, L2S 3A1, Canada\
[baraksh@gmail.com](mailto:baraksh@gmail.com) | [https://baraksh.com/](https://baraksh.com/)\ [bshoshany@brocku.ca](mailto:bshoshany@brocku.ca) | [https://baraksh.com/](https://baraksh.com/)\
Companion paper: [arXiv:2105.00613](https://arxiv.org/abs/2105.00613) Companion paper: [arXiv:2105.00613](https://arxiv.org/abs/2105.00613)\
DOI: [doi:10.5281/zenodo.4742687](https://doi.org/10.5281/zenodo.4742687)
<!-- TOC depthFrom:2 --> <!-- TOC depthFrom:2 -->
@@ -33,7 +43,7 @@ Companion paper: [arXiv:2105.00613](https://arxiv.org/abs/2105.00613)
- [Dual Intel Xeon Gold 6148 (80 threads)](#dual-intel-xeon-gold-6148-80-threads) - [Dual Intel Xeon Gold 6148 (80 threads)](#dual-intel-xeon-gold-6148-80-threads)
- [Version history](#version-history) - [Version history](#version-history)
- [Feedback](#feedback) - [Feedback](#feedback)
- [Author and copyright](#author-and-copyright) - [Copyright and citing](#copyright-and-citing)
<!-- /TOC --> <!-- /TOC -->
@@ -65,12 +75,12 @@ As demonstrated in the performance tests [below](#performance-tests), using our
* **Fast:** * **Fast:**
* Built from scratch with maximum performance in mind. * Built from scratch with maximum performance in mind.
* Suitable for use in high-performance computing clusters with a very large number of CPU cores. * Suitable for use in high-performance computing nodes with a very large number of CPU cores.
* Compact code, to reduce both compilation time and binary size. * Compact code, to reduce both compilation time and binary size.
* Reusing threads avoids the overhead of creating and destroying them for individual tasks. * Reusing threads avoids the overhead of creating and destroying them for individual tasks.
* A task queue ensures that there are never more threads running in parallel than allowed by the hardware. * A task queue ensures that there are never more threads running in parallel than allowed by the hardware.
* **Lightweight:** * **Lightweight:**
* Only ~160 lines of code, excluding comments, blank lines, and the two optional helper classes. * Only ~180 lines of code, excluding comments, blank lines, and the two optional helper classes.
* Single header file: simply `#include "thread_pool.hpp"`. * Single header file: simply `#include "thread_pool.hpp"`.
* Header-only: no need to install or build the library. * Header-only: no need to install or build the library.
* Self-contained: no external requirements or dependencies. Does not require OpenMP or any other multithreading APIs. Only uses the C++ standard library, and works with any C++17-compliant compiler. * Self-contained: no external requirements or dependencies. Does not require OpenMP or any other multithreading APIs. Only uses the C++ standard library, and works with any C++17-compliant compiler.
@@ -691,6 +701,13 @@ An interesting point to notice is that for **single-threaded** calculations (1 b
<a id="markdown-version-history" name="version-history"></a> <a id="markdown-version-history" name="version-history"></a>
## Version history ## Version history
* Version 1.7 (2021-06-02)
* Fixed a bug in `parallelize_loop()` which prevented it from actually running loops in parallel, see [this issue](https://github.com/bshoshany/thread-pool/issues/11).
* Version 1.6 (2021-05-26)
* Since MSVC does not interpret `and` as `&&` by default, the previous release did not compile with MSVC unless the `/permissive-` or `/Za` compiler flags were used. This has been fixed in this version, and the code now successfully compiles with GCC, Clang, and MSVC. See [this pull request](https://github.com/bshoshany/thread-pool/pull/10).
* Version 1.5 (2021-05-07)
* This library now has a DOI for citation purposes. Information on how to cite it in publications has been added to the source code and to `README.md`.
* Added GitHub badges to `README.md`.
* Version 1.4 (2021-05-05) * Version 1.4 (2021-05-05)
* Added three new public member functions to monitor the tasks submitted to the pool: * Added three new public member functions to monitor the tasks submitted to the pool:
* `get_tasks_queued()` gets the number of tasks currently waiting in the queue to be executed by the threads. * `get_tasks_queued()` gets the number of tasks currently waiting in the queue to be executed by the threads.
@@ -725,9 +742,29 @@ An interesting point to notice is that for **single-threaded** calculations (1 b
If you would like a request any additional features, or if you encounter any bugs, please feel free to [open a new issue](https://github.com/bshoshany/thread-pool/issues)! If you would like a request any additional features, or if you encounter any bugs, please feel free to [open a new issue](https://github.com/bshoshany/thread-pool/issues)!
<a id="markdown-author-and-copyright" name="author-and-copyright"></a> <a id="markdown-copyright-and-citing" name="copyright-and-citing"></a>
## Author and copyright ## Copyright and citing
Copyright (c) 2021 [Barak Shoshany](http://baraksh.com). Licensed under the [MIT license](LICENSE.txt). 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): Copyright (c) 2021 [Barak Shoshany](http://baraksh.com). Licensed under the [MIT license](LICENSE.txt).
* Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", [arXiv:2105.00613](https://arxiv.org/abs/2105.00613) (May 2021) If you use this library in published research, please cite it as follows:
* Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", [doi:10.5281/zenodo.4742687](https://doi.org/10.5281/zenodo.4742687), [arXiv:2105.00613](https://arxiv.org/abs/2105.00613) (May 2021)
You can use the following BibTeX entry:
```none
@article{Shoshany2021_ThreadPool,
archiveprefix = {arXiv},
author = {Barak Shoshany},
doi = {10.5281/zenodo.4742687},
eid = {arXiv:2105.00613},
eprint = {2105.00613},
journal = {arXiv e-prints},
keywords = {Computer Science - Distributed, Parallel, and Cluster Computing, D.1.3, D.1.5},
month = {May},
primaryclass = {cs.DC},
title = {{A C++17 Thread Pool for High-Performance Scientific Computing}},
year = {2021}
}
```
+24 -19
View File
@@ -3,9 +3,10 @@
/** /**
* @file thread_pool.hpp * @file thread_pool.hpp
* @author Barak Shoshany (baraksh@gmail.com) (http://baraksh.com) * @author Barak Shoshany (baraksh@gmail.com) (http://baraksh.com)
* @version 1.4 * @version 1.7
* @date 2021-05-05 * @date 2021-06-02
* @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 * @copyright Copyright (c) 2021 Barak Shoshany. Licensed under the MIT license. If you use this library in published research, please cite it as follows:
* - Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.5281/zenodo.4742687, arXiv:2105.00613 (May 2021)
* *
* @brief A C++17 thread pool for high-performance scientific computing. * @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. * @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.
@@ -135,15 +136,16 @@ public:
T start = (T)(t * block_size + first_index); T start = (T)(t * block_size + first_index);
T end = (t == num_tasks - 1) ? last_index : (T)((t + 1) * block_size + first_index - 1); T end = (t == num_tasks - 1) ? last_index : (T)((t + 1) * block_size + first_index - 1);
blocks_running++; blocks_running++;
push_task([start, end, &loop, &blocks_running] { push_task([start, end, &loop, &blocks_running]
for (T i = start; i <= end; i++) {
loop(i); for (T i = start; i <= end; i++)
blocks_running--; loop(i);
}); blocks_running--;
while (blocks_running != 0) });
{ }
sleep_or_yield(); while (blocks_running != 0)
} {
sleep_or_yield();
} }
} }
@@ -175,7 +177,8 @@ public:
template <typename F, typename... A> template <typename F, typename... A>
void push_task(const F &task, const A &...args) void push_task(const F &task, const A &...args)
{ {
push_task([task, args...] { task(args...); }); push_task([task, args...]
{ task(args...); });
} }
/** /**
@@ -211,10 +214,11 @@ public:
{ {
std::shared_ptr<std::promise<bool>> promise(new std::promise<bool>); std::shared_ptr<std::promise<bool>> promise(new std::promise<bool>);
std::future<bool> future = promise->get_future(); std::future<bool> future = promise->get_future();
push_task([task, args..., promise] { push_task([task, args..., promise]
task(args...); {
promise->set_value(true); task(args...);
}); promise->set_value(true);
});
return future; return future;
} }
@@ -233,7 +237,8 @@ public:
{ {
std::shared_ptr<std::promise<R>> promise(new std::promise<R>); std::shared_ptr<std::promise<R>> promise(new std::promise<R>);
std::future<R> future = promise->get_future(); 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; return future;
} }
@@ -338,7 +343,7 @@ private:
while (running) while (running)
{ {
std::function<void()> task; std::function<void()> task;
if (!paused and pop_task(task)) if (!paused && pop_task(task))
{ {
task(); task();
tasks_total--; tasks_total--;