Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
Inkscape::dispatch_pool Class Reference

General-purpose, parallel thread dispatch mechanism. More...

#include <dispatch-pool.h>

Public Types

using global_id = int
 
using local_id = int
 
using dispatch_func = std::function< void(global_id, local_id)>
 

Public Member Functions

 dispatch_pool (int size)
 
 ~dispatch_pool ()
 
void dispatch (int count, dispatch_func function)
 
template<typename F >
void dispatch_threshold (int count, bool threshold, F &&function)
 
int size () const
 

Private Member Functions

void thread_func (local_id id)
 
void execute_batch (std::unique_lock< std::mutex > &lk, local_id id, int thread_count)
 

Private Attributes

global_id _available_work {}
 
global_id _completed_work {}
 
global_id _target_work {}
 
bool _shutdown {}
 
std::mutex _dispatch_lock
 
std::mutex _lock
 
std::condition_variable _available_cv
 
std::condition_variable _completed_cv
 
dispatch_func _function
 
std::vector< std::thread > _threads
 

Detailed Description

General-purpose, parallel thread dispatch mechanism.

A dispatch is a compute job which is parameterized by a counter. It can also be thought of as a way to parallelize a for loop. For example, the following single-threaded loop

for (int i = 0; i < count; ++i) {
    do_work(i);
}

can be rewritten to use a dispatch_pool and operate in parallel like this:

pool.dispatch(count, [&](int i, int local_id) {
    do_work(i);
});

Finally, it is also possible to perform all jobs on the calling thread unless a threshold condition is met (like dispatch size). This can be used if threading the operation would be less efficient unless the work is at least a certain size:

pool.dispatch_threshold(count, count > 1024, [&](int i, int local_id) {
    do_work(i);
});

Unlike boost's asio::thread_pool, which pushes work for threads onto a queue, this class only supports operation via a counter. The simpler design allows dispatching a very large amount of work (potentially millions of jobs, for every pixel in a megapixel image) with constant memory and space used.

A pool's thread count is fixed upon construction and cannot change during operation. If you allocate work buffers for each thread in the pool, you can use the size() method to determine how many threads it has been created with.

By design, only one dispatch may run at a time. It is safe to call dispatch() from multiple threads without extra locking.

Terminology used is designed to loosely follow that of OpenCL kernels or GL/VK compute shaders:

  • Global ID within a dispatch refers to the 0-based counter value for a given job.
  • Local ID within a dispatch refers to the 0-based index of thread which is processing the job. This will always be less than the pool's size().

The first parameter to the callback is global ID. The second parameter, which is unused in the example, is the local ID. The local ID is primarily useful if a work buffer is allocated for each thread in the dispatch_pool ahead of time.

Definition at line 64 of file dispatch-pool.h.

Member Typedef Documentation

◆ dispatch_func

Definition at line 69 of file dispatch-pool.h.

◆ global_id

Definition at line 67 of file dispatch-pool.h.

◆ local_id

Definition at line 68 of file dispatch-pool.h.

Constructor & Destructor Documentation

◆ dispatch_pool()

Inkscape::dispatch_pool::dispatch_pool ( int  size)
explicit

Definition at line 12 of file dispatch-pool.cpp.

References _threads, size(), and thread_func().

◆ ~dispatch_pool()

Inkscape::dispatch_pool::~dispatch_pool ( )

Definition at line 24 of file dispatch-pool.cpp.

References _available_cv, _lock, _shutdown, and _threads.

Member Function Documentation

◆ dispatch()

void Inkscape::dispatch_pool::dispatch ( int  count,
dispatch_func  function 
)

◆ dispatch_threshold()

template<typename F >
void Inkscape::dispatch_pool::dispatch_threshold ( int  count,
bool  threshold,
F &&  function 
)
inline

Definition at line 77 of file dispatch-pool.h.

References dispatch().

◆ execute_batch()

void Inkscape::dispatch_pool::execute_batch ( std::unique_lock< std::mutex > &  lk,
local_id  id,
int  thread_count 
)
private

◆ size()

int Inkscape::dispatch_pool::size ( ) const
inline

Definition at line 88 of file dispatch-pool.h.

References _threads.

Referenced by dispatch(), dispatch_pool(), and thread_func().

◆ thread_func()

void Inkscape::dispatch_pool::thread_func ( local_id  id)
private

Definition at line 60 of file dispatch-pool.cpp.

References _available_cv, _available_work, _lock, _shutdown, _target_work, execute_batch(), and size().

Referenced by dispatch_pool().

Member Data Documentation

◆ _available_cv

std::condition_variable Inkscape::dispatch_pool::_available_cv
private

Definition at line 106 of file dispatch-pool.h.

Referenced by execute_batch(), thread_func(), and ~dispatch_pool().

◆ _available_work

global_id Inkscape::dispatch_pool::_available_work {}
private

Definition at line 99 of file dispatch-pool.h.

Referenced by dispatch(), execute_batch(), and thread_func().

◆ _completed_cv

std::condition_variable Inkscape::dispatch_pool::_completed_cv
private

Definition at line 107 of file dispatch-pool.h.

Referenced by dispatch(), and execute_batch().

◆ _completed_work

global_id Inkscape::dispatch_pool::_completed_work {}
private

Definition at line 100 of file dispatch-pool.h.

Referenced by dispatch(), and execute_batch().

◆ _dispatch_lock

std::mutex Inkscape::dispatch_pool::_dispatch_lock
private

Definition at line 104 of file dispatch-pool.h.

Referenced by dispatch().

◆ _function

dispatch_func Inkscape::dispatch_pool::_function
private

Definition at line 108 of file dispatch-pool.h.

Referenced by dispatch(), and execute_batch().

◆ _lock

std::mutex Inkscape::dispatch_pool::_lock
private

Definition at line 105 of file dispatch-pool.h.

Referenced by dispatch(), thread_func(), and ~dispatch_pool().

◆ _shutdown

bool Inkscape::dispatch_pool::_shutdown {}
private

Definition at line 102 of file dispatch-pool.h.

Referenced by thread_func(), and ~dispatch_pool().

◆ _target_work

global_id Inkscape::dispatch_pool::_target_work {}
private

Definition at line 101 of file dispatch-pool.h.

Referenced by dispatch(), execute_batch(), and thread_func().

◆ _threads

std::vector<std::thread> Inkscape::dispatch_pool::_threads
private

Definition at line 109 of file dispatch-pool.h.

Referenced by dispatch_pool(), size(), and ~dispatch_pool().


The documentation for this class was generated from the following files: