]> git.saurik.com Git - apple/libdispatch.git/blame_incremental - man/dispatch_apply.3
libdispatch-913.30.4.tar.gz
[apple/libdispatch.git] / man / dispatch_apply.3
... / ...
CommitLineData
1.\" Copyright (c) 2008-2017 Apple Inc. All rights reserved.
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
23size_t iterations = 10;
24
25// 'idx' is zero indexed, just like:
26// for (idx = 0; idx < iterations; idx++)
27
28dispatch_apply(iterations, DISPATCH_APPLY_AUTO, ^(size_t idx) {
29 printf("%zu\\n", idx);
30});
31.Ed
32.Pp
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
45Like a "for (;;)" loop, the
46.Fn dispatch_apply
47function is synchronous.
48If asynchronous behavior is desired, wrap the call to
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
61#define STRIDE 3
62
63dispatch_apply(count / STRIDE, DISPATCH_APPLY_AUTO, ^(size_t idx) {
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
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).
87.Sh FUNDAMENTALS
88.Fn dispatch_apply
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
93.Fn dispatch_async
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.
103.Pp
104The
105.Fn dispatch_apply
106function is a wrapper around
107.Fn dispatch_apply_f .
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 .
119.Sh SEE ALSO
120.Xr dispatch 3 ,
121.Xr dispatch_async 3 ,
122.Xr dispatch_queue_create 3