std::execution:: bulk, std::execution:: bulk_chunked, std::execution:: bulk_unchunked
|
Definiert im Header
<execution>
|
||
|
std
::
execution
::
sender
auto
bulk
(
std
::
execution
::
sender
auto
input,
|
(1) | (seit C++26) |
|
std
::
execution
::
sender
auto
bulk_chunked
(
std
::
execution
::
sender
auto
input,
|
(2) | (seit C++26) |
|
std
::
execution
::
sender
auto
bulk_unchunked
(
std
::
execution
::
sender
auto
input,
|
(3) | (seit C++26) |
Inhaltsverzeichnis |
Parameter
| input | - | Sender, der nach Ausführung die Werte sendet, auf denen die Funktion ausgeführt wird |
| policy | - | die Ausführungsrichtlinie angehängt an function / function2 |
| function | - |
Aufrufbares Objekt, das für jeden Index im Bereich
[
0
,
size
)
aufgerufen wird, wobei auch die vom Input-Sender produzierten Werte übergeben werden
|
| function2 | - |
wie
function
, aber aufgerufen mit einem Indexpaar
(
b
,
e
)
, mit
b < e
, sodass für jeden Index
i
im Bereich
[
[
0
,
size
)
genau ein Aufruf von
function2
erfolgt, sodass
b
<=
i
<
e
.
|
Rückgabewert
Gibt einen Sender zurück, der den durch den Eingabesender beschriebenen Task-Graphen beschreibt, mit einem zusätzlichen Knoten, der die bereitgestellte Funktion mit Indizes im Bereich
[
0
,
size
)
aufruft und dabei auch die vom Eingabesender gesendeten Werte als Argumente übergibt.
function / function2 wird garantiert erst ausgeführt, nachdem der zurückgegebene Sender gestartet wurde.
Fehlerabschlüsse
Alle Fehler, die durch input übergeben werden, werden weitergeleitet.
Zusätzlich darf der Absender mit einem std::exception_ptr Fehler abschließen, der Folgendes enthält:
- jede Ausnahme, die von function geworfen wird
- std::bad_alloc wenn die Implementierung die erforderlichen Ressourcen nicht allokieren kann
- eine von std::runtime_error abgeleitete Ausnahme für andere interne Fehler (z.B. kann die Ausnahme vom Ausführungskontext nicht an den Aufrufer propagiert werden).
Stornierung
Die unangepassten
std::execution::bulk
,
std::execution::bulk_chunk
und
std::execution::bulk_unchunked
leiten das gestoppte Abschlusssignal von
input
weiter. Sie bieten keinen zusätzlichen Mechanismus zur Erzeugung eines gestoppten Abschlussignals.
Hinweise
Beim Aufruf von
std::execution::bulk
und
std::execution::bulk_chunked
können verschiedene Aufrufe von
function
/
function2
auf demselben Ausführungsagenten stattfinden.
Beim Aufruf von
std::execution::bulk_unchunked
müssen verschiedene Aufrufe der
function
auf unterschiedlichen Ausführungsagenten erfolgen.
Die Standardimplementierung von
std::execution::bulk
basiert auf
std::execution::bulk_chunked
. Obwohl die Anpassung von
std::execution::bulk
möglich ist, wird erwartet, dass in den meisten Fällen nur
std::execution::bulk_chunked
angepasst wird.
Ohne eine Anpassung von
std::execution::bulk
und
std::execution::bulk_chunked
ist das Verhalten von
std::execution::bulk
und
std::execution::bulk_chunk
, die
function
seriell auszuführen, was nicht besonders nützlich ist. Von Implementierungen wird erwartet, dass sie Anpassungen bereitstellen, die die Ausführung von
std::execution::bulk
und
std::execution::bulk_chunked
auf verschiedenen Planern nützlicher machen.
std::execution::bulk_unchunked
ist dazu gedacht, verwendet zu werden, wenn
function
Abhängigkeiten zwischen verschiedenen Aufrufen haben kann und gleichzeitige Fortschrittsgarantien erfordert (paralleler Fortschritt reicht nicht aus). Das Ausführen von
std::execution::bulk_unchunked
mit einer Größe von 1000 erfordert 1000 Ausführungsagenten (z.B. Threads), die gleichzeitig laufen.
std::execution::bulk_unchunked
erfordert keine Ausführungsrichtlinie, da bereits erwartet wird, dass die
function
in der Lage ist, nebenläufig ausgeführt zu werden.
Beispiele
Mögliche Verwendung von
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 beschreibt die Arbeit, die durch den Aufruf einer Funktion zum // Abrufen eines Koeffizienten `a` beschrieben wird, und verwendet diesen, um // y[i] = a * x[i] + y[i] // für jedes `i` im Bereich [0, x.size()) auszuführen
Mögliche Verwendung von
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); }); // Das atomare Objekt wird nicht 100000 Mal berührt; wird schneller ausgeführt als bulk()