dispatch_apply(3) schedule blocks for iterative execution


Fd #include <dispatch/dispatch.h> Ft void Fo dispatch_apply Fa size_t iterations dispatch_queue_t queue void (^block)(size_t) Fc Ft void Fo dispatch_apply_f Fa size_t iterations dispatch_queue_t queue void *context void (*function)(void *, size_t) Fc


The Fn 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 Fn dispatch_apply function is synchronous. If asynchronous behavior is desired, please wrap the call to Fn dispatch_apply with a call to Fn dispatch_async against another queue.

Sometimes, when the block passed to Fn 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);


Conceptually, Fn dispatch_apply is a convenient wrapper around Fn dispatch_async and a semaphore to wait for completion. In practice, the dispatch library optimizes this function.

The Fn dispatch_apply function is a wrapper around Fn dispatch_apply_f .