You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: affinity/cpp-20/d0796r2.md
+36-14Lines changed: 36 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,7 @@
16
16
17
17
### P0796r2 (RAP)
18
18
19
+
* Introduced a free function for retrieving the execution resource underlying the current thread of execution.
19
20
* Introduce `this_thread::bind` & `this_thread::unbind` for binding and unbinding a thread of execution to an execution resource.
20
21
* Introduce high-level interface for execution binding via executor properties.
21
22
@@ -24,7 +25,7 @@
24
25
* Introduce proposed wording.
25
26
* Based on feedback from SG1, introduced a pair-wise interface for querying the relative affinity between execution resources.
26
27
* Introduce an interface for retrieving an allocator or polymorphic memory resource.
27
-
* Based on feedback from SG1, remove requirement for a hierarchical system topology structure, which doesn't require a root resouce.
28
+
* Based on feedback from SG1, remove requirement for a hierarchical system topology structure, which doesn't require a root resource.
28
29
29
30
### P0796r0 (ABQ)
30
31
@@ -224,12 +225,12 @@ An `execution_resource` is a light weight structure which acts as an identifier
224
225
225
226
### System topology
226
227
227
-
The system topology is made up of a number of system level `execution_resource`s, which can be queried through `this_system::resource` which returns a `std::vector`. The `execution_resources` available within the system can be initialized dynamically by a runtime library, however must be done so before `main` is called, given that after that point the system topology cannot change.
228
+
The system topology is made up of a number of system level `execution_resource`s, which can be queried through `this_system::get_resources` which returns a `std::vector`. The `execution_resources` available within the system can be initialized dynamically by a runtime library, however must be done so before `main` is called, given that after that point the system topology cannot change.
228
229
229
230
Below *(Listing 3)* is an example of iterating over the system level resources and printing out it's capabilities.
230
231
231
232
```cpp
232
-
for (auto res : execution::this_system::resources()) {
233
+
for (auto res : execution::this_system::get_resources()) {
233
234
std::cout << res.name() `\n`;
234
235
std::cout << res.can_place_memory() << `\n`;
235
236
std::cout << res.can_place_agents() << `\n`;
@@ -238,14 +239,18 @@ for (auto res : execution::this_system::resources()) {
238
239
```
239
240
*Listing 3: Example of querying all the system level execution resources*
240
241
242
+
### Current resource
243
+
244
+
The `execution_resource` which underlies the current thread of execution can be queried through `this_thread::get_resource`.
245
+
241
246
### Querying relative affinity
242
247
243
248
The `affinity_query` class template provides an abstraction for a relative affinity value between two `execution_resource`s, derived from a particular `affinity_operation` and `affinity_metric`. The `affinity_query` is templated by `affinity_operation` and `affinity_metric` and is constructed from two `execution_resource`s. An `affinity_query` does not mean much on it's own, instead a relative magnitude of affinity can be queried by using comparison operators. If necessary the value of an `affinity_query` can also be queried through `native_affinity`, though the return value of this is implementation defined.
244
249
245
250
Below *(listing 4)* is an example of how you can query the relative affinity between two `execution_resource`s.
246
251
247
252
```cpp
248
-
auto systemLevelResources = execution::this_system::resources();
253
+
auto systemLevelResources = execution::this_system::get_resources();
249
254
auto memberResources = systemLevelResources.resources();
250
255
251
256
auto relativeLatency01 = execution::affinity_query<execution::affinity_operation::read,
@@ -267,15 +272,15 @@ The `execution_context` class provides an abstraction for managing a number of l
267
272
Below *(Listing 5)* is an example of how this extended interface could be used to construct an *execution context* from an *execution resource* which is retrieved from the *system’s resource topology*. Once an *execution context* is constructed it can then still be queried for its *execution resource* and then that *execution resource* can be further partitioned.
268
273
269
274
```cpp
270
-
auto &resources = execution::this_system::resources();
275
+
auto &resources = execution::this_system::get_resources();
auto &systelLevelResource = execContext.resource();
279
+
auto &systemLevelResource = execContext.resource();
275
280
276
281
// resource[0] should be equal to execResource
277
282
278
-
for (auto res : systelLevelResource.resources()) {
283
+
for (auto res : systemLevelResource.resources()) {
279
284
std::cout << res.name() << `\n`;
280
285
}
281
286
```
@@ -284,11 +289,11 @@ for (auto res : systelLevelResource.resources()) {
284
289
When creating an `execution_context` from a given `execution_resource`, the executors and allocators associated with it are bound to that `execution_resource`. For example: when creating an `execution_resource` from a CPU socket resource, all executors associated with the given socket will spawn execution agents with affinity to the socket partition of the system *(Listing 6)*.
285
290
286
291
```cpp
287
-
auto cList = std::execution::this_system::resources();
292
+
auto cList = std::execution::this_system::get_resources();
288
293
// FindASocketResource is a user-defined function that finds a
289
294
// resource that is a CPU socket in the given resource list
290
295
auto& socket = findASocketResource(cList);
291
-
execution_contexteC{socket} // Associated with the socket
296
+
execution_contextC{socket} // Associated with the socket
292
297
auto executor = eC.executor(); // By transitivity, associated with the socket too
293
298
auto socketAllocator = eC.allocator(); // Retrieve an allocator to the closest memory node
@@ -558,16 +568,20 @@ The `affinity_query` class template provides an abstraction for a relative affin
558
568
559
569
## Free functions
560
570
561
-
The free function `this_system::resources` is provided for retrieving the `execution_resource`s which encapsulate the hardware platforms available within the system, these are referred to as the *system level resources*.
571
+
### `this_system::get_resources`
572
+
573
+
The free function `this_system::get_resources` is provided for retrieving the `execution_resource`s which encapsulate the hardware platforms available within the system, these are referred to as the *system level resources*.
*Returns:* A std::vector containing all *system level resources*.
566
578
567
-
*Requires:* If `this_system::resources().size() > 0`, `this_system::resources()[0]` be the `execution_resource` use by `std::thread`. The value returned by `this_system::resources()` be the same at any point after the invocation of `main`.
579
+
*Requires:* If `this_system::get_resources().size() > 0`, `this_system::get_resources()[0]` be the `execution_resource` use by `std::thread`. The value returned by `this_system::get_resources()` be the same at any point after the invocation of `main`.
568
580
569
581
> [*Note:* Returning a `std::vector` allows users to potentially manipulate the container of `execution_resource`s after it is returned, we may want to replace this with an alternative type which is more restrictive at a later date such as a range. *--end note*]
570
582
583
+
### `this_thread::bind` & `this_thread::unbind`
584
+
571
585
The free functions `this_thread::bind` and `this_thread::unbind` are provided for binding / unbinding the current *thread of execution* to / from a particular `execution_resource`.
572
586
573
587
bool bind(execution_resource eR) noexcept;
@@ -586,6 +600,14 @@ The free functions `this_thread::bind` and `this_thread::unbind` are provided fo
586
600
587
601
*Effects:* If successful, unbinds the current *thread of execution* from the specified `execution_resource`.
588
602
603
+
### `this_thread::get_resource`
604
+
605
+
The free function `this_thread::get_resource` is provided for retrieving the `execution_resource` underlying the current thread of execution.
0 commit comments