std::execution:: bulk, std::execution:: bulk_chunked, std::execution:: bulk_unchunked
|
Défini dans l'en-tête
<execution>
|
||
|
std
::
execution
::
sender
auto
bulk
(
std
::
execution
::
sender
auto
input,
|
(1) | (depuis C++26) |
|
std
::
execution
::
sender
auto
bulk_chunked
(
std
::
execution
::
sender
auto
input,
|
(2) | (depuis C++26) |
|
std
::
execution
::
sender
auto
bulk_unchunked
(
std
::
execution
::
sender
auto
input,
|
(3) | (depuis C++26) |
Table des matières |
Paramètres
| input | - | expéditeur qui, une fois exécuté, envoie les valeurs sur lesquelles la fonction s'exécute |
| policy | - | la politique d'exécution attachée à function / function2 |
| function | - |
élément invocable à appeler pour chaque index dans l'intervalle
[
0
,
size
)
, en passant également les valeurs produites par l'expéditeur d'entrée
|
| function2 | - |
identique à
function
mais appelé avec une paire d'indices
(
b
,
e
)
, avec
b < e
, de sorte que, pour chaque index
i
dans l'intervalle
[
[
0
,
size
)
il y ait exactement un appel à
function2
tel que
b
<=
i
<
e
.
|
Valeur de retour
Retourne un expéditeur décrivant le graphe de tâches décrit par l'expéditeur d'entrée, avec un nœud supplémentaire invoquant la fonction fournie avec des indices dans l'intervalle
[
0
,
size
)
, en passant également les valeurs envoyées par l'expéditeur d'entrée comme arguments.
function / function2 est garanti de ne pas commencer à s'exécuter avant que l'expéditeur retourné ne soit démarré.
Completions d'erreur
Toutes les erreurs transmises par input sont redirigées.
De plus, l'émetteur est autorisé à compléter avec une std::exception_ptr erreur qui contient :
- toute exception levée par function
- std::bad_alloc si l'implémentation échoue à allouer les ressources requises
- une exception dérivée de std::runtime_error pour d'autres erreurs internes (par exemple, impossibilité de propager l'exception du contexte d'exécution à l'appelant).
Annulation
La version non personnalisée de
std::execution::bulk
,
std::execution::bulk_chunk
et
std::execution::bulk_unchunked
transmet le signal d'achèvement arrêté depuis
input
. Elles ne fournissent pas de mécanisme supplémentaire pour produire un signal d'achèvement arrêté.
Notes
Lors de l'appel de
std::execution::bulk
et
std::execution::bulk_chunked
, différents appels de
function
/
function2
peuvent se produire sur le même agent d'exécution.
Lors de l'appel à
std::execution::bulk_unchunked
, différentes invocations de la
function
doivent se produire sur différents agents d'exécution.
L'implémentation par défaut de
std::execution::bulk
est basée sur
std::execution::bulk_chunked
. Bien qu'il soit possible de personnaliser
std::execution::bulk
, il est prévu que la plupart du temps seule
std::execution::bulk_chunked
soit personnalisée.
Sans personnalisation de
std::execution::bulk
et
std::execution::bulk_chunked
, le comportement de
std::execution::bulk
et
std::execution::bulk_chunk
est d'exécuter la
function
de manière séquentielle, ce qui n'est pas particulièrement utile. On s'attend à ce que les implémentations disposent de personnalisations qui rendraient l'exécution de
std::execution::bulk
et
std::execution::bulk_chunked
sur différents ordonnanceurs plus utile.
std::execution::bulk_unchunked
est destiné à être utilisé lorsque
function
peut avoir des dépendances entre différentes invocations, et qu'il nécessite des garanties de progression concurrente (la progression parallèle ne suffit pas). L'exécution de
std::execution::bulk_unchunked
avec une taille de 1000 nécessitera 1000 agents d'exécution (par exemple, des threads) fonctionnant concurremment.
std::execution::bulk_unchunked
ne nécessite pas de politique d'exécution, car il est déjà attendu que la
fonction
puisse s'exécuter de manière concurrente.
Exemples
Utilisation possible de
execution::bulk
.
std::vector<double> x; std::vector<double> y; //... sender auto process_elements = just(get_coefficient()) | bulk(x.size(), [&](size_t i, double a) { y[i] = a * x[i] + y[i]; }); // process_elements décrit le travail décrit en appelant une fonction pour // obtenir un coefficient `a`, et en l'utilisant pour exécuter // y[i] = a * x[i] + y[i] // pour chaque `i` dans l'intervalle [0, x.size())
Utilisation possible de
execution::bulk_chunked
.
std::vector<std::uint32_t> data = ...; std::atomic<std::uint32_t> sum{0}; sender auto s = bulk_chunked(just(), par, 100000, [&sum, &data](int begin, int end) { auto partial_sum = std::accumulate(data.begin() + begin, data.begin() + end, 0U); sum.fetch_add(partial_sum); }); // l'objet atomique ne sera pas touché 100000 fois ; s'exécutera plus rapidement que bulk()