table of contents
dispatch_apply(3) | Library Functions Manual | 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
().
SEE ALSO¶
dispatch(3), dispatch_async(3), dispatch_queue_create(3), dispatch_semaphore_create(3)
May 1, 2009 | Darwin |