dispatch_apply(3)
NAME
dispatch_apply -- schedule blocks for iterative execution
SYNOPSIS
#include <dispatch/dispatch.h> void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t)); void dispatch_apply_f(size_t iterations, dispatch_queue_t queue, void *context, void (*function)(void *, size_t));
DESCRIPTION
The dispatch_apply() function provides data-level concurrency through a
"for (;;)" loop like primitive:
dispatch_queue_t the_queue = dispatch_get_concurrent_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT);
size_t iterations = 10;
// 'idx' is zero indexed, just like:
// for (idx = 0; idx < iterations; idx++)
- dispatch_apply(iterations, the_queue, ^(size_t idx) {
- printf("%zu\n", idx);
- });
- Like a "for (;;)" loop, the dispatch_apply() function is synchronous. If
asynchronous behavior is desired, please wrap the call to
dispatch_apply() with a call to dispatch_async() against another queue. - Sometimes, when the block passed to dispatch_apply() is simple, the use
of striding can tune performance. Calculating the optimal stride is best
left to experimentation. Start with a stride of one and work upwards
until the desired performance is achieved (perhaps using a power of two
search): - #define STRIDE 3
- dispatch_apply(count / STRIDE, queue, ^(size_t idx) {
- size_t j = idx * STRIDE;
size_t j_stop = j + STRIDE;
do {printf("%zu\n", j++); - } while (j < j_stop);
- });
- size_t i;
for (i = count - (count % STRIDE); i < count; i++) { - printf("%zu\n", i);
- }
FUNDAMENTALS
Conceptually, dispatch_apply() is a convenient wrapper around
dispatch_async() and a semaphore to wait for completion. In practice,
the dispatch library optimizes this function.
The dispatch_apply() function is a wrapper around dispatch_apply_f().