.\" Copyright (c) 2008-2009 Apple Inc. All rights reserved. .Dd May 1, 2009 .Dt dispatch_apply 3 .Os Darwin .Sh NAME .Nm dispatch_apply .Nd schedule blocks for iterative execution .Sh SYNOPSIS .Fd #include .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 .Sh DESCRIPTION The .Fn dispatch_apply function provides data-level concurrency through a "for (;;)" loop like primitive: .Bd -literal 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); }); .Ed .Pp 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. .Pp 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): .Bd -literal #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); } .Ed .Sh FUNDAMENTALS 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. .Pp The .Fn dispatch_apply function is a wrapper around .Fn dispatch_apply_f . .Sh SEE ALSO .Xr dispatch 3 , .Xr dispatch_async 3 , .Xr dispatch_queue_create 3 , .Xr dispatch_semaphore_create 3