Skip to content

Commit eb3a447

Browse files
committed
Add material for clause 2 of N3960
1 parent d99c8cd commit eb3a447

File tree

2 files changed

+318
-0
lines changed

2 files changed

+318
-0
lines changed

execution_policies.html

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
<cxx-clause id="parallel.execpol">
2+
<h1>Execution policies</h1>
3+
<cxx-section id="parallel.execpol.general">
4+
<h1>In general</h1>
5+
<p>This subclause describes classes that represent <dfn>execution policies</dfn>. An
6+
<dfn>execution policy</dfn> is an object that expresses the requirements on the ordering
7+
of functions invoked as a consequence of the invocation of a standard
8+
algorithm. Execution policies afford standard algorithms the discretion to
9+
execute in parallel.</p>
10+
11+
<cxx-example>
12+
<pre>std::vector&lt;int&gt; v = ...
13+
14+
// standard sequential sort
15+
std::sort(vec.begin(), vec.end());
16+
17+
using namespace std::experimental::parallel;
18+
19+
// explicitly sequential sort
20+
sort(seq, v.begin(), v.end());
21+
22+
// permitting parallel execution
23+
sort(par, v.begin(), v.end());
24+
25+
// permitting vectorization as well
26+
sort(vec, v.begin(), v.end());
27+
28+
// sort with dynamically-selected execution
29+
size_t threshold = ...
30+
execution_policy exec = seq;
31+
if(v.size() &gt; threshold)
32+
{
33+
exec = par;
34+
}
35+
36+
sort(exec, v.begin(), v.end());</pre>
37+
</cxx-example><pre>
38+
</pre>
39+
<cxx-note>
40+
Because different parallel architectures may require idiosyncratic
41+
parameters for efficient execution, implementations of the Standard Library
42+
should provide additional execution policies to those described in this
43+
Technical Specification as extensions.
44+
</cxx-note>
45+
</cxx-section>
46+
<cxx-section id="parallel.execpol.synop">
47+
<h1>Header <code>&lt;experimental/execution_policy&gt;</code> synopsis</h1>
48+
49+
<pre>
50+
namespace std {
51+
namespace experimental {
52+
namespace parallel {
53+
<cxx-ref insynopsis="" to="parallel.execpol.type"></cxx-ref>
54+
template&lt;class T&gt; struct is_execution_policy;
55+
56+
<cxx-ref insynopsis="" to="parallel.execpol.seq"></cxx-ref>
57+
class sequential_execution_policy;
58+
59+
<cxx-ref insynopsis="" to="parallel.execpol.par"></cxx-ref>
60+
class parallel_execution_policy;
61+
62+
<cxx-ref insynopsis="" to="parallel.execpol.vec"></cxx-ref>
63+
class vector_execution_policy;
64+
65+
<cxx-ref insynopsis="" to="parallel.execpol.dynamic"></cxx-ref>
66+
class execution_policy;
67+
}
68+
}
69+
}
70+
</pre>
71+
</cxx-section>
72+
<cxx-section id="parallel.execpol.type">
73+
<h1>Execution policy type trait</h1>
74+
75+
<pre>
76+
namespace std {
77+
namespace experimental {
78+
namespace parallel {
79+
template&lt;class T&gt; struct is_execution_policy
80+
: integral_constant&lt;bool, <em>see below</em>&gt; { };
81+
}
82+
}
83+
}
84+
</pre>
85+
86+
<p><code>is_execution_policy</code> can be used to detect parallel execution policies for the purpose of excluding function signatures from otherwise ambiguous overload resolution participation.</p>
87+
88+
<p>If <code>T</code> is the type of a standard or implementation-defined execution policy, <code>is_execution_policy&lt;T&gt;</code> shall be publicly derived from <code>integral_constant&lt;bool,true&gt;</code>,
89+
otherwise from <code>integral_constant&lt;bool,false&gt;</code>.</p>
90+
91+
<p>The behavior of a program that adds specializations for <code>is_execution_policy</code> is undefined.</p>
92+
</cxx-section>
93+
<cxx-section id="parallel.execpol.seq">
94+
<h1>Sequential execution policy</h1>
95+
96+
<pre>
97+
namespace std {
98+
namespace experimental {
99+
namespace parallel {
100+
<del> class sequential_execution_policy
101+
{
102+
void swap(sequential_execution_policy& other);
103+
};</del>
104+
<ins> class sequential_execution_policy{};</ins>
105+
}
106+
}
107+
}
108+
</pre>
109+
110+
<p>The class <code>sequential_execution_policy</code> is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and require that a parallel algorithm's execution may not be parallelized.</p>
111+
112+
<del>
113+
<cxx-function>
114+
<cxx-signature><del>void swap(sequential_execution_policy& other);</del></cxx-signature>
115+
116+
<cxx-effects>Swaps the state of <code>*this</code> and <code>other</code>.</cxx-effects>
117+
</cxx-function>
118+
</del>
119+
</cxx-section>
120+
<cxx-section id="parallel.execpol.par">
121+
<h1>Parallel execution policy</h1>
122+
123+
<pre>
124+
namespace std {
125+
namespace experimental {
126+
namespace parallel {
127+
128+
<del> class parallel_execution_policy
129+
{
130+
void swap(parallel_execution_policy& other);
131+
};</del>
132+
<ins> class parallel_execution_policy{};</ins>
133+
}
134+
}
135+
}
136+
</pre>
137+
138+
<p>The class <code>parallel_execution_policy</code> is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm's execution may be parallelized.</p>
139+
140+
<del>
141+
<cxx-function>
142+
<cxx-signature><del>void swap(parallel_execution_policy& other);</del></cxx-signature>
143+
144+
<cxx-effects>Swaps the state of <code>*this</code> and <code>other</code>.</cxx-effects>
145+
</cxx-function>
146+
</del>
147+
</cxx-section>
148+
<cxx-section id="parallel.execpol.vec">
149+
<h1>Vector execution policy</h1>
150+
151+
<pre>
152+
namespace std {
153+
namespace experimental {
154+
namespace parallel {
155+
156+
<del> class vector_execution_policy
157+
{
158+
void swap(vector_execution_policy& other);
159+
};</del>
160+
<ins> class vector_execution_policy{};</ins>
161+
}
162+
}
163+
}
164+
</pre>
165+
166+
<p>The class <code>vector_execution_policy</code> is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm's execution may be vectorized.</p>
167+
168+
<del>
169+
<cxx-function>
170+
<cxx-signature><del>void swap(vector_execution_policy& other);</del></cxx-signature>
171+
172+
<cxx-effects>Swaps the state of <code>*this</code> and <code>other</code>.</cxx-effects>
173+
</cxx-function>
174+
</del>
175+
</cxx-section>
176+
177+
<cxx-section id="parallel.execpol.dynamic">
178+
<h1>Dynamic execution policy</h1>
179+
180+
<pre>
181+
namespace std {
182+
namespace experimental {
183+
namespace parallel {
184+
185+
class execution_policy
186+
{
187+
public:
188+
<cxx-ref insynopsis="" to="parallel.execpol.con"></cxx-ref>
189+
template&lt;class T&gt; execution_policy(const T& exec);
190+
template&lt;class T&gt; execution_policy& operator=(const T& exec);
191+
<del> void swap(execution_policy& other);</del>
192+
193+
<cxx-ref insynopsis="" to="parallel.execpol.access"></cxx-ref>
194+
<del> template&lt;class T&gt; T* target();</del>
195+
<del> template&lt;class T&gt; const T* target() const noexcept;</del>
196+
<ins> template&lt;class T&gt; T* get() noexcept;</ins>
197+
<ins> template&lt;class T&gt; const T* get() const noexcept;</ins>
198+
};
199+
}
200+
}
201+
}
202+
</pre>
203+
204+
<p>The class <code>execution_policy</code> is a dynamic container for execution policy objects.
205+
<code>execution_policy</code> allows dynamic control over standard algorithm execution.</p>
206+
207+
<cxx-example>
208+
<pre>std::vector&lt;float&gt; sort_me = ...
209+
210+
std::execution_policy exec = std::seq;
211+
212+
if(sort_me.size() &gt; threshold)
213+
{
214+
exec = std::par;
215+
}
216+
217+
std::sort(exec, sort_me.begin(), sort_me.end());</pre>
218+
</cxx-example>
219+
220+
<p>Objects of type <code>execution_policy</code> shall be constructible and assignable from objects of
221+
type <code>T</code> for which <code>is_execution_policy&lt;T&gt;::value</code> is <code>true</code>.</p>
222+
223+
<cxx-section id="parallel.execpol.con">
224+
<h1><code>execution_policy</code> construct/assign</h1>
225+
226+
<cxx-function>
227+
<cxx-signature>template&lt;class T&gt; execution_policy(const T& exec);</cxx-signature>
228+
229+
<cxx-effects>Constructs an <code>execution_policy</code> object with a copy of <code>exec</code>'s state.</cxx-effects>
230+
231+
<cxx-requires><code>is_execution_policy&lt;T&gt;::value</code> is <code>true</code>.</cxx-requires>
232+
</cxx-function>
233+
234+
<cxx-function>
235+
<cxx-signature>template&lt;class T&gt; execution_policy& operator=(const T& exec);</cxx-signature>
236+
237+
<cxx-effects>Assigns a copy of <code>exec</code>'s state to <code>*this</code>.</cxx-effects>
238+
239+
<cxx-returns><code>*this</code>.
240+
241+
<cxx-requires><code>is_execution_policy&lt;T&gt;::value</code> is <code>true</code>.</cxx-requires>
242+
</cxx-function>
243+
244+
<del>
245+
<cxx-function>
246+
<cxx-signature><del>void swap(execution_policy& other);</del></cxx-signature>
247+
248+
<cxx-effects>Swaps the stored object of <code>*this</code> with that of <code>other</code>.</cxx-effects>
249+
</cxx-function>
250+
</del>
251+
</cxx-section>
252+
253+
<cxx-section id="parallel.execpol.access">
254+
<h1><code>execution_policy</code> object access</h1>
255+
256+
<cxx-function>
257+
<cxx-signature>
258+
<del>const type_info& target_type() const;</del>
259+
<ins>const type_info& type() const noexcept;</ins>
260+
</cxx-signature>
261+
262+
<cxx-returns><code>typeid(T)</code>, such that <code>T</code> is the type of the execution policy object contained by <code>*this</code>.</cxx-returns>
263+
</cxx-function>
264+
265+
<cxx-function>
266+
<cxx-signature>
267+
<del>template&lt;class T&gt; T* target();</del>
268+
<del>template&lt;class T&gt; const T* target() const;</del>
269+
<ins>template&lt;class T&gt; T* get() noexcept;</ins>
270+
<ins>template&lt;class T&gt; const T* get() noexcept;</ins>
271+
</cxx-signature>
272+
273+
<cxx-returns>If <code>target_type() == typeid(T)</code>, a pointer to the stored execution policy object; otherwise a null pointer.</cxx-returns>
274+
275+
<cxx-requires><code>is_execution_policy&lt;T&gt;</code> is <code>true</code>.</cxx-requires>
276+
</cxx-function>
277+
278+
</cxx-section>
279+
</cxx-section>
280+
281+
<del>
282+
<cxx-section id="parallel.execpol.algorithms">
283+
<h1>Execution policy specialized algorithms</h1>
284+
285+
<cxx-function>
286+
<cxx-signature>
287+
<del>
288+
void swap(sequential_execution_policy& a, sequential_execution_policy& b);
289+
void swap(parallel_execution_policy& a, parallel_execution_policy& b);
290+
void swap(vector_execution_policy& a, vector_execution_policy& b);
291+
void swap(execution_policy& a, execution_policy& b);
292+
</del>
293+
</cxx-signature>
294+
295+
<cxx-effects><code>a.swap(b)</code>.</cxx-effects>
296+
</cxx-function>
297+
</cxx-section>
298+
</del>
299+
300+
<cxx-section id="parallel.execpol.objects">
301+
<h1>Execution policy objects</h1>
302+
303+
<pre>
304+
namespace std {
305+
namespace experimental {
306+
namespace parallel {
307+
constexpr sequential_execution_policy seq = sequential_execution_policy();
308+
constexpr parallel_execution_policy par = parallel_execution_policy();
309+
constexpr vector_execution_policy vec = vector_execution_policy();
310+
}
311+
}
312+
}
313+
</pre>
314+
315+
<p>The header <code>&lt;execution_policy&gt;</code> declares a global object associated with each type of execution policy defined by this Technical Specification.</p>
316+
</cxx-section>
317+
</cxx-clause>

main.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
<cxx-include href="front_matter.html"></cxx-include>
1111
<cxx-include href="general.html"></cxx-include>
12+
<cxx-include href="execution_policies.html"></cxx-include>
1213

1314
</body>
1415
</html>

0 commit comments

Comments
 (0)