Namespaces
Variants

std::execution:: bulk, std::execution:: bulk_chunked, std::execution:: bulk_unchunked

From cppreference.net
Definiert im Header <execution>
std :: execution :: sender

auto bulk ( std :: execution :: sender auto input,
std:: integral auto size,
auto && policy,
std:: invocable < decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function ) ;
(1) (seit C++26)
std :: execution :: sender

auto bulk_chunked ( std :: execution :: sender auto input,
std:: integral auto size,
auto && policy,
std:: invocable < decltype ( size ) , decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function2 ) ;
(2) (seit C++26)
std :: execution :: sender

auto bulk_unchunked ( std :: execution :: sender auto input,
std:: integral auto size,
std:: invocable < decltype ( size ) , decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function ) ;
(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()