Skip to content

Commit ea2ccd7

Browse files
author
Gordon Brown
committed
Merge branch 'master' into issue-33
2 parents 312a75c + 70b5cbd commit ea2ccd7

File tree

1 file changed

+36
-14
lines changed

1 file changed

+36
-14
lines changed

affinity/cpp-20/d0796r2.md

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
### P0796r2 (RAP)
1818

19+
* Introduced a free function for retrieving the execution resource underlying the current thread of execution.
1920
* Introduce `this_thread::bind` & `this_thread::unbind` for binding and unbinding a thread of execution to an execution resource.
2021
* Introduce high-level interface for execution binding via executor properties.
2122

@@ -24,7 +25,7 @@
2425
* Introduce proposed wording.
2526
* Based on feedback from SG1, introduced a pair-wise interface for querying the relative affinity between execution resources.
2627
* 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.
2829

2930
### P0796r0 (ABQ)
3031

@@ -224,12 +225,12 @@ An `execution_resource` is a light weight structure which acts as an identifier
224225
225226
### System topology
226227

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.
228229

229230
Below *(Listing 3)* is an example of iterating over the system level resources and printing out it's capabilities.
230231

231232
```cpp
232-
for (auto res : execution::this_system::resources()) {
233+
for (auto res : execution::this_system::get_resources()) {
233234
std::cout << res.name() `\n`;
234235
std::cout << res.can_place_memory() << `\n`;
235236
std::cout << res.can_place_agents() << `\n`;
@@ -238,14 +239,18 @@ for (auto res : execution::this_system::resources()) {
238239
```
239240
*Listing 3: Example of querying all the system level execution resources*
240241

242+
### Current resource
243+
244+
The `execution_resource` which underlies the current thread of execution can be queried through `this_thread::get_resource`.
245+
241246
### Querying relative affinity
242247

243248
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.
244249

245250
Below *(listing 4)* is an example of how you can query the relative affinity between two `execution_resource`s.
246251

247252
```cpp
248-
auto systemLevelResources = execution::this_system::resources();
253+
auto systemLevelResources = execution::this_system::get_resources();
249254
auto memberResources = systemLevelResources.resources();
250255

251256
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
267272
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.
268273

269274
```cpp
270-
auto &resources = execution::this_system::resources();
275+
auto &resources = execution::this_system::get_resources();
271276

272277
execution::execution_context execContext(resources[0]);
273278

274-
auto &systelLevelResource = execContext.resource();
279+
auto &systemLevelResource = execContext.resource();
275280

276281
// resource[0] should be equal to execResource
277282

278-
for (auto res : systelLevelResource.resources()) {
283+
for (auto res : systemLevelResource.resources()) {
279284
std::cout << res.name() << `\n`;
280285
}
281286
```
@@ -284,11 +289,11 @@ for (auto res : systelLevelResource.resources()) {
284289
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)*.
285290
286291
```cpp
287-
auto cList = std::execution::this_system::resources();
292+
auto cList = std::execution::this_system::get_resources();
288293
// FindASocketResource is a user-defined function that finds a
289294
// resource that is a CPU socket in the given resource list
290295
auto& socket = findASocketResource(cList);
291-
execution_contexteC{socket} // Associated with the socket
296+
execution_contextC{socket} // Associated with the socket
292297
auto executor = eC.executor(); // By transitivity, associated with the socket too
293298
auto socketAllocator = eC.allocator(); // Retrieve an allocator to the closest memory node
294299
std::vector<int, decltype(socketAllocator)> v1(100, socketAllocator);
@@ -391,18 +396,23 @@ A *thread of execution* can be requested to bind to a particular `execution_reso
391396

392397
};
393398

399+
} // execution
400+
394401
/* This system */
395402

396403
namespace this_system {
397404
std::vector<execution_resource> resources() noexcept;
398405
}
399406

407+
/* This thread */
408+
400409
namespace this_thread {
401-
bool bind(execution_resource eR) noexcept;
402-
bool unbind(execution_resource eR) noexcept;
410+
std::experimental::execution::execution_resource get_resource() noexcept;
411+
412+
bool bind(execution_resource eR) noexcept;
413+
bool unbind(execution_resource eR) noexcept;
403414
}
404415

405-
} // execution
406416
} // experimental
407417
} // std
408418

@@ -558,16 +568,20 @@ The `affinity_query` class template provides an abstraction for a relative affin
558568
559569
## Free functions
560570

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*.
562574

563575
std::vector<execution_resource> resources() noexcept;
564576

565577
*Returns:* A std::vector containing all *system level resources*.
566578

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`.
568580

569581
> [*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*]
570582
583+
### `this_thread::bind` & `this_thread::unbind`
584+
571585
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`.
572586

573587
bool bind(execution_resource eR) noexcept;
@@ -586,6 +600,14 @@ The free functions `this_thread::bind` and `this_thread::unbind` are provided fo
586600

587601
*Effects:* If successful, unbinds the current *thread of execution* from the specified `execution_resource`.
588602

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.
606+
607+
std::experimental::execution::execution_resource get_resource() noexcept;
608+
609+
*Returns:* The `execution_resource` underlying the current thread of execution.
610+
589611
# Future Work
590612

591613
## Migrating data from memory allocated in one partition to another

0 commit comments

Comments
 (0)