1- .\" Copyright (c) 2008-2010 Apple Inc. All rights reserved.
1+ .\" Copyright (c) 2008-2017 Apple Inc. All rights reserved.
22.Dd May 1, 2009
33.Dt dispatch_apply 3
44.Os Darwin
2020.Fn dispatch_apply
2121function provides data-level concurrency through a "for (;;)" loop like primitive:
2222.Bd -literal
23- dispatch_queue_t the_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2423size_t iterations = 10;
2524
2625// 'idx' is zero indexed, just like:
2726// for (idx = 0; idx < iterations; idx++)
2827
29- dispatch_apply(iterations, the_queue , ^(size_t idx) {
28+ dispatch_apply(iterations, DISPATCH_APPLY_AUTO , ^(size_t idx) {
3029 printf("%zu\\n " , idx);
3130});
3231.Ed
3332.Pp
33+ Although any queue can be used, it is strongly recommended to use
34+ .Vt DISPATCH_APPLY_AUTO
35+ as the
36+ .Vt queue
37+ argument to both
38+ .Fn dispatch_apply
39+ and
40+ .Fn dispatch_apply_f ,
41+ as shown in the example above, since this allows the system to automatically use worker threads
42+ that match the configuration of the current thread as closely as possible.
43+ No assumptions should be made about which global concurrent queue will be used.
44+ .Pp
3445Like a "for (;;)" loop, the
3546.Fn dispatch_apply
3647function is synchronous.
37- If asynchronous behavior is desired, please wrap the call to
48+ If asynchronous behavior is desired, wrap the call to
3849.Fn dispatch_apply
3950with a call to
4051.Fn dispatch_async
@@ -49,7 +60,7 @@ achieved (perhaps using a power of two search):
4960.Bd -literal
5061#define STRIDE 3
5162
52- dispatch_apply(count / STRIDE, queue , ^(size_t idx) {
63+ dispatch_apply(count / STRIDE, DISPATCH_APPLY_AUTO , ^(size_t idx) {
5364 size_t j = idx * STRIDE;
5465 size_t j_stop = j + STRIDE;
5566 do {
@@ -74,12 +85,21 @@ This is in contrast to asynchronous functions which must retain both the block
7485and target queue for the duration of the asynchronous operation (as the calling
7586function may immediately release its interest in these objects).
7687.Sh FUNDAMENTALS
77- Conceptually,
7888.Fn dispatch_apply
79- is a convenient wrapper around
89+ and
90+ .Fn dispatch_apply_f
91+ attempt to quickly create enough worker threads to efficiently iterate work in parallel.
92+ By contrast, a loop that passes work items individually to
8093.Fn dispatch_async
81- and a semaphore to wait for completion.
82- In practice, the dispatch library optimizes this function.
94+ or
95+ .Fn dispatch_async_f
96+ will incur more overhead and does not express the desired parallel execution semantics to
97+ the system, so may not create an optimal number of worker threads for a parallel workload.
98+ For this reason, prefer to use
99+ .Fn dispatch_apply
100+ or
101+ .Fn dispatch_apply_f
102+ when parallel execution is important.
83103.Pp
84104The
85105.Fn dispatch_apply
@@ -99,5 +119,4 @@ use a for-loop around invocations of
99119.Sh SEE ALSO
100120.Xr dispatch 3 ,
101121.Xr dispatch_async 3 ,
102- .Xr dispatch_queue_create 3 ,
103- .Xr dispatch_semaphore_create 3
122+ .Xr dispatch_queue_create 3
0 commit comments