The project provides high-performance concurrency, enabling highly parallel computation.
C++
311
426 commits
updated Oct 19, 2026
A high-performance C++ thread pool and parallel algorithms library
Dispenso is a modern C++ parallel computing library that provides work-stealing thread pools, parallel for loops, futures, task graphs, and concurrent containers. It serves as a powerful alternative to OpenMP and Intel TBB, offering better nested parallelism, sanitizer-clean code, and explicit thread pool control. Dispenso is used in hundreds of projects at Meta (formerly Facebook) and has been heavily tested and iterated on in production.
Key advantages over OpenMP and TBB:
std::experimental::shared_future-like API that TBB lacks, safe for multiple concurrent waiters, with much better performance than std::futureparallel_for)Dispenso provides a comprehensive set of parallel programming primitives:
Core runtime:
ThreadPool — work-stealing thread pool backing all dispenso parallelismTaskSet / ConcurrentTaskSet — task grouping with wait, cancellation, and recursive schedulingParallel algorithms:
parallel_for — parallel loops over indices, blocking or non-blocking (cascaded), with static or adaptive (work-stealing) chunking; cascading parallel_for enables overlapping independent loops without oversubscriptionparallel_invoke — fork-join invocation of heterogeneous tasks; composes naturally with recursive divide-and-conquerfor_each — parallel std::for_each / std::for_each_nFuture — high-performance thread-safe shared futures with then(), when_all(), when_any(), and an API matching std::experimental::shared_futureGraph — task graph execution with subgraph support and incremental re-evaluationpipeline — parallel pipelining of streaming workloadsConcurrent containers and synchronization:
ConcurrentVector — concurrent growable vector, superset of TBB concurrent_vector APIChaseLevDeque — lock-free SPMC work-stealing dequeMpmcRingBuffer — bounded multi-producer multi-consumer ring bufferSPSCRingBuffer — lock-free single-producer single-consumer ring bufferLatch — one-shot barrier for thread synchronizationRWLock — reader-writer spin lock, outperforms std::shared_mutex under low write contentionGeneral-purpose utilities:
CpuSet — portable CPU affinity, NUMA topology, and cache-aware thread group buildingSmallVector — inline-storage vector (not thread-aware; similar to folly::small_vector)OnceFunction — lightweight move-only void() callablePoolAllocator — pool allocator with pluggable backing allocation (e.g. CUDA)SmallBufferAllocator — fast concurrent allocation for temporary objectsResourcePool — semaphore-like guard around pooled resourcesCompletionEvent — notifiable event with wait and timed waitAsyncRequest — lightweight constrained message passingConcurrentObjectArena — fast same-type object arenaParallel for loop - the most common use case:
#include <dispenso/parallel_for.h>
// Sequential
for (size_t i = 0; i < N; ++i) {
process(data[i]);
}
// Parallel with dispenso - just wrap it!
dispenso::parallel_for(0, N, [&](size_t i) {
process(data[i]);
});
Try it live - no install, no build: run dispenso on Compiler Explorer. Compiler Explorer is a shared sandbox with very few cores, so treat the timings there as illustrative rather than measured.
Install via your favorite package manager:
# Conda
conda install -c conda-forge dispenso
# Fedora/RHEL
sudo dnf install dispenso-devel
# Or build from source (see below)
TBB has more functionality overall, but we built dispenso for three reasons:
std::experimental::shared_future-like futures safe for multiple concurrent waitersPerformance: Dispenso tends to be faster for small and medium parallel loops, and on par for large ones. When many loops run independently, dispenso's cascading parallel_for avoids oversubscription and has delivered 32-50% speedups in production workloads after porting from TBB at Meta. TBB lacks an equivalent mechanism.
See Migrating from TBB for a step-by-step porting guide.
OpenMP has simple syntax for basic loops but grows complex for advanced constructs. Nested #pragma omp parallel for inside threaded code risks thread explosion and machine exhaustion. Dispenso outperforms OpenMP for medium and large loops. OpenMP has an advantage for very small loops due to direct compiler support, though dispenso's minItemsPerChunk option can close this gap by tuning the parallelism threshold for small/fast loops.
See Migrating from OpenMP for a step-by-step porting guide.
Folly excels at asynchronous I/O with coroutine support. Dispenso is designed for compute-bound work. Dispenso's futures are lighter-weight and faster for compute workloads; Folly is the better choice for I/O-heavy applications.
TaskFlow focuses on task graph execution. Dispenso has faster graph construction, faster full and partial graph execution, much lower parallel_for overhead (10-100x in benchmarks), and simpler/faster pipeline construction. TaskFlow does offer CUDA graph mappings, which dispenso does not currently provide.
GCD is Apple-specific with ports to other platforms. C++ parallel algorithms are still evolving — we are interested in enabling dispenso as a backend for std::execution and C++ coroutines. Contributions and benchmarks are welcome.
#pragma omp with dispenso equivalents, handling reductions and nested parallelismDispenso is benchmarked across Linux (x64), macOS (ARM64), Windows (x64), and Android (ARM64),
comparing against OpenMP, TBB, TaskFlow, folly, and std::async across thread pools, parallel
loops, futures, graphs, concurrent containers, and more.
Interactive Benchmark Dashboard — explore all results with platform switching, dark/light theme, and detailed per-benchmark charts.
Binary builds of Dispenso are available through several package managers:
conda install -c conda-forge dispensoconan install --requires=dispenso/1.6.2vcpkg install dispensobrew install dispensosudo port install dispensosudo dnf install dispenso-develIf your platform is not on the list, see the next section for instructions to build from source.
Linux and macOS:
mkdir build && cd build
cmake PATH_TO_DISPENSO_ROOT
make -j
FreeBSD:
mkdir build && cd build
cmake PATH_TO_DISPENSO_ROOT
cmake --build . --parallel $(sysctl -n hw.ncpu)
Windows (from Developer Command Prompt):
mkdir build && cd build
cmake PATH_TO_DISPENSO_ROOT
cmake --build . --config Release
For detailed instructions including CMake prerequisites, installation, testing, and benchmarking, see docs/building.md.
parallel_for with per-thread state accumulation (see Getting Started). A dedicated reduction API is planned.CpuSet::bindCurrentThread() is a no-op on macOS — the OS does not support explicit CPU pinning. Topology queries work.Dispenso itself is released under the MIT license (see LICENSE).
It also bundles the (excellent) moodycamel concurrentqueue library, under
dispenso/third-party/moodycamel/, which carries its own terms:
concurrentqueue.h and blockingconcurrentqueue.h are dual-licensed under
the Simplified BSD license or the Boost Software License 1.0, at your
option.lightweightsemaphore.h additionally embeds Jeff Preshing's semaphore
implementation, which is under the Zlib license.The full text is in dispenso/third-party/moodycamel/LICENSE.md, which is
installed alongside the headers, so it travels with a packaged copy rather
than only existing in the source tree. Building with
-DDISPENSO_USE_SYSTEM_CONCURRENTQUEUE=ON uses an external concurrentqueue
instead and installs none of it.
145 followers · starred Jan 2025
1,746 followers · starred Mar 2026
170 followers · starred May 2022
162 followers · starred Dec 2023
The project provides high-performance concurrency, enabling highly parallel computation.
C++
311
426 commits
updated Oct 19, 2026
A high-performance C++ thread pool and parallel algorithms library
Dispenso is a modern C++ parallel computing library that provides work-stealing thread pools, parallel for loops, futures, task graphs, and concurrent containers. It serves as a powerful alternative to OpenMP and Intel TBB, offering better nested parallelism, sanitizer-clean code, and explicit thread pool control. Dispenso is used in hundreds of projects at Meta (formerly Facebook) and has been heavily tested and iterated on in production.
Key advantages over OpenMP and TBB:
std::experimental::shared_future-like API that TBB lacks, safe for multiple concurrent waiters, with much better performance than std::futureparallel_for)Dispenso provides a comprehensive set of parallel programming primitives:
Core runtime:
ThreadPool — work-stealing thread pool backing all dispenso parallelismTaskSet / ConcurrentTaskSet — task grouping with wait, cancellation, and recursive schedulingParallel algorithms:
parallel_for — parallel loops over indices, blocking or non-blocking (cascaded), with static or adaptive (work-stealing) chunking; cascading parallel_for enables overlapping independent loops without oversubscriptionparallel_invoke — fork-join invocation of heterogeneous tasks; composes naturally with recursive divide-and-conquerfor_each — parallel std::for_each / std::for_each_nFuture — high-performance thread-safe shared futures with then(), when_all(), when_any(), and an API matching std::experimental::shared_futureGraph — task graph execution with subgraph support and incremental re-evaluationpipeline — parallel pipelining of streaming workloadsConcurrent containers and synchronization:
ConcurrentVector — concurrent growable vector, superset of TBB concurrent_vector APIChaseLevDeque — lock-free SPMC work-stealing dequeMpmcRingBuffer — bounded multi-producer multi-consumer ring bufferSPSCRingBuffer — lock-free single-producer single-consumer ring bufferLatch — one-shot barrier for thread synchronizationRWLock — reader-writer spin lock, outperforms std::shared_mutex under low write contentionGeneral-purpose utilities:
CpuSet — portable CPU affinity, NUMA topology, and cache-aware thread group buildingSmallVector — inline-storage vector (not thread-aware; similar to folly::small_vector)OnceFunction — lightweight move-only void() callablePoolAllocator — pool allocator with pluggable backing allocation (e.g. CUDA)SmallBufferAllocator — fast concurrent allocation for temporary objectsResourcePool — semaphore-like guard around pooled resourcesCompletionEvent — notifiable event with wait and timed waitAsyncRequest — lightweight constrained message passingConcurrentObjectArena — fast same-type object arenaParallel for loop - the most common use case:
#include <dispenso/parallel_for.h>
// Sequential
for (size_t i = 0; i < N; ++i) {
process(data[i]);
}
// Parallel with dispenso - just wrap it!
dispenso::parallel_for(0, N, [&](size_t i) {
process(data[i]);
});
Try it live - no install, no build: run dispenso on Compiler Explorer. Compiler Explorer is a shared sandbox with very few cores, so treat the timings there as illustrative rather than measured.
Install via your favorite package manager:
# Conda
conda install -c conda-forge dispenso
# Fedora/RHEL
sudo dnf install dispenso-devel
# Or build from source (see below)
TBB has more functionality overall, but we built dispenso for three reasons:
std::experimental::shared_future-like futures safe for multiple concurrent waitersPerformance: Dispenso tends to be faster for small and medium parallel loops, and on par for large ones. When many loops run independently, dispenso's cascading parallel_for avoids oversubscription and has delivered 32-50% speedups in production workloads after porting from TBB at Meta. TBB lacks an equivalent mechanism.
See Migrating from TBB for a step-by-step porting guide.
OpenMP has simple syntax for basic loops but grows complex for advanced constructs. Nested #pragma omp parallel for inside threaded code risks thread explosion and machine exhaustion. Dispenso outperforms OpenMP for medium and large loops. OpenMP has an advantage for very small loops due to direct compiler support, though dispenso's minItemsPerChunk option can close this gap by tuning the parallelism threshold for small/fast loops.
See Migrating from OpenMP for a step-by-step porting guide.
Folly excels at asynchronous I/O with coroutine support. Dispenso is designed for compute-bound work. Dispenso's futures are lighter-weight and faster for compute workloads; Folly is the better choice for I/O-heavy applications.
TaskFlow focuses on task graph execution. Dispenso has faster graph construction, faster full and partial graph execution, much lower parallel_for overhead (10-100x in benchmarks), and simpler/faster pipeline construction. TaskFlow does offer CUDA graph mappings, which dispenso does not currently provide.
GCD is Apple-specific with ports to other platforms. C++ parallel algorithms are still evolving — we are interested in enabling dispenso as a backend for std::execution and C++ coroutines. Contributions and benchmarks are welcome.
#pragma omp with dispenso equivalents, handling reductions and nested parallelismDispenso is benchmarked across Linux (x64), macOS (ARM64), Windows (x64), and Android (ARM64),
comparing against OpenMP, TBB, TaskFlow, folly, and std::async across thread pools, parallel
loops, futures, graphs, concurrent containers, and more.
Interactive Benchmark Dashboard — explore all results with platform switching, dark/light theme, and detailed per-benchmark charts.
Binary builds of Dispenso are available through several package managers:
conda install -c conda-forge dispensoconan install --requires=dispenso/1.6.2vcpkg install dispensobrew install dispensosudo port install dispensosudo dnf install dispenso-develIf your platform is not on the list, see the next section for instructions to build from source.
Linux and macOS:
mkdir build && cd build
cmake PATH_TO_DISPENSO_ROOT
make -j
FreeBSD:
mkdir build && cd build
cmake PATH_TO_DISPENSO_ROOT
cmake --build . --parallel $(sysctl -n hw.ncpu)
Windows (from Developer Command Prompt):
mkdir build && cd build
cmake PATH_TO_DISPENSO_ROOT
cmake --build . --config Release
For detailed instructions including CMake prerequisites, installation, testing, and benchmarking, see docs/building.md.
parallel_for with per-thread state accumulation (see Getting Started). A dedicated reduction API is planned.CpuSet::bindCurrentThread() is a no-op on macOS — the OS does not support explicit CPU pinning. Topology queries work.Dispenso itself is released under the MIT license (see LICENSE).
It also bundles the (excellent) moodycamel concurrentqueue library, under
dispenso/third-party/moodycamel/, which carries its own terms:
concurrentqueue.h and blockingconcurrentqueue.h are dual-licensed under
the Simplified BSD license or the Boost Software License 1.0, at your
option.lightweightsemaphore.h additionally embeds Jeff Preshing's semaphore
implementation, which is under the Zlib license.The full text is in dispenso/third-party/moodycamel/LICENSE.md, which is
installed alongside the headers, so it travels with a packaged copy rather
than only existing in the source tree. Building with
-DDISPENSO_USE_SYSTEM_CONCURRENTQUEUE=ON uses an external concurrentqueue
instead and installs none of it.
145 followers · starred Jan 2025
1,746 followers · starred Mar 2026
170 followers · starred May 2022
162 followers · starred Dec 2023