]> git.saurik.com Git - apple/libdispatch.git/blame - man/dispatch_apply.3
libdispatch-913.30.4.tar.gz
[apple/libdispatch.git] / man / dispatch_apply.3
CommitLineData
6b746eb4 1.\" Copyright (c) 2008-2017 Apple Inc. All rights reserved.
0ab74447
A
2.Dd May 1, 2009
3.Dt dispatch_apply 3
4.Os Darwin
5.Sh NAME
6.Nm dispatch_apply
7.Nd schedule blocks for iterative execution
8.Sh SYNOPSIS
9.Fd #include <dispatch/dispatch.h>
10.Ft void
11.Fo dispatch_apply
12.Fa "size_t iterations" "dispatch_queue_t queue" "void (^block)(size_t)"
13.Fc
14.Ft void
15.Fo dispatch_apply_f
16.Fa "size_t iterations" "dispatch_queue_t queue" "void *context" "void (*function)(void *, size_t)"
17.Fc
18.Sh DESCRIPTION
19The
20.Fn dispatch_apply
21function provides data-level concurrency through a "for (;;)" loop like primitive:
22.Bd -literal
0ab74447
A
23size_t iterations = 10;
24
25// 'idx' is zero indexed, just like:
26// for (idx = 0; idx < iterations; idx++)
27
6b746eb4 28dispatch_apply(iterations, DISPATCH_APPLY_AUTO, ^(size_t idx) {
0ab74447
A
29 printf("%zu\\n", idx);
30});
31.Ed
32.Pp
6b746eb4
A
33Although any queue can be used, it is strongly recommended to use
34.Vt DISPATCH_APPLY_AUTO
35as the
36.Vt queue
37argument to both
38.Fn dispatch_apply
39and
40.Fn dispatch_apply_f ,
41as shown in the example above, since this allows the system to automatically use worker threads
42that match the configuration of the current thread as closely as possible.
43No assumptions should be made about which global concurrent queue will be used.
44.Pp
0ab74447
A
45Like a "for (;;)" loop, the
46.Fn dispatch_apply
47function is synchronous.
6b746eb4 48If asynchronous behavior is desired, wrap the call to
0ab74447
A
49.Fn dispatch_apply
50with a call to
51.Fn dispatch_async
52against another queue.
53.Pp
54Sometimes, when the block passed to
55.Fn dispatch_apply
56is simple, the use of striding can tune performance.
57Calculating the optimal stride is best left to experimentation.
58Start with a stride of one and work upwards until the desired performance is
59achieved (perhaps using a power of two search):
60.Bd -literal
e85f4437 61#define STRIDE 3
0ab74447 62
6b746eb4 63dispatch_apply(count / STRIDE, DISPATCH_APPLY_AUTO, ^(size_t idx) {
0ab74447
A
64 size_t j = idx * STRIDE;
65 size_t j_stop = j + STRIDE;
66 do {
67 printf("%zu\\n", j++);
68 } while (j < j_stop);
69});
70
71size_t i;
72for (i = count - (count % STRIDE); i < count; i++) {
73 printf("%zu\\n", i);
74}
75.Ed
e85f4437
A
76.Sh IMPLIED REFERENCES
77Synchronous functions within the dispatch framework hold an implied reference
78on the target queue. In other words, the synchronous function borrows the
79reference of the calling function (this is valid because the calling function
80is blocked waiting for the result of the synchronous function, and therefore
81cannot modify the reference count of the target queue until after the
82synchronous function has returned).
83.Pp
84This is in contrast to asynchronous functions which must retain both the block
85and target queue for the duration of the asynchronous operation (as the calling
86function may immediately release its interest in these objects).
0ab74447 87.Sh FUNDAMENTALS
0ab74447 88.Fn dispatch_apply
6b746eb4
A
89and
90.Fn dispatch_apply_f
91attempt to quickly create enough worker threads to efficiently iterate work in parallel.
92By contrast, a loop that passes work items individually to
0ab74447 93.Fn dispatch_async
6b746eb4
A
94or
95.Fn dispatch_async_f
96will incur more overhead and does not express the desired parallel execution semantics to
97the system, so may not create an optimal number of worker threads for a parallel workload.
98For this reason, prefer to use
99.Fn dispatch_apply
100or
101.Fn dispatch_apply_f
102when parallel execution is important.
0ab74447
A
103.Pp
104The
105.Fn dispatch_apply
106function is a wrapper around
107.Fn dispatch_apply_f .
e85f4437
A
108.Sh CAVEATS
109Unlike
110.Fn dispatch_async ,
111a block submitted to
112.Fn dispatch_apply
113is expected to be either independent or dependent
114.Em only
115on work already performed in lower-indexed invocations of the block. If
116the block's index dependency is non-linear, it is recommended to
117use a for-loop around invocations of
118.Fn dispatch_async .
0ab74447 119.Sh SEE ALSO
e85f4437 120.Xr dispatch 3 ,
0ab74447 121.Xr dispatch_async 3 ,
6b746eb4 122.Xr dispatch_queue_create 3