Spec-Zone.ru › C++

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

Определён в заголовочном файле <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) (начиная с 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) (начиная с 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) (начиная с C++26)

Параметры

input - отправитель, который при запуске отправляет значения, с которыми выполняется функция
policy - политика выполнения, связанная с function/function2
function - вызываемый объект, который вызывается для каждого индекса в диапазоне [0, size), передавая также значения, созданные входным отправителем
function2 - то же, что и function, но вызывается с парой индексов (b, e), при этом b < e, так что для каждого индекса i в диапазоне [[0, size) выполняется ровно один вызов function2, такой что b <= i < e.

Возвращаемое значение

Возвращает отправитель, описывающий граф задач, задаваемый входным отправителем, с добавленным узлом, вызывающим предоставленную функцию для индексов в диапазоне [0, size) и передающим в качестве аргументов значения, отправленные входным отправителем.

Гарантируется, что function/function2 не начнёт выполняться, пока не будет запущен возвращённый отправитель.

Завершения с ошибкой

Все ошибки, переданные через input, пересылаются дальше.

Кроме того, отправитель может завершиться с ошибкой std::exception_ptr, содержащей:

  • любое исключение, выброшенное function
  • std::bad_alloc, если реализации не удалось выделить необходимые ресурсы
  • исключение, производное от std::runtime_error, для других внутренних ошибок (например, если не удаётся передать исключение из контекста выполнения вызывающей стороне).

Отмена

Ненастроенные std::execution::bulk, std::execution::bulk_chunk и std::execution::bulk_unchunked передают сигнал завершения остановкой от input. Они не предоставляют дополнительного механизма для создания сигнала завершения остановкой.

Примечания

При вызове std::execution::bulk и std::execution::bulk_chunked разные вызовы function/function2 могут выполняться одним и тем же исполнительным агентом.

При вызове std::execution::bulk_unchunked разные вызовы function должны выполняться разными исполнительными агентами.

Реализация std::execution::bulk по умолчанию основана на std::execution::bulk_chunked. Хотя настройка std::execution::bulk возможна, предполагается, что в большинстве случаев настраивается только std::execution::bulk_chunked.

Без настройки std::execution::bulk и std::execution::bulk_chunked поведение std::execution::bulk и std::execution::bulk_chunk заключается в последовательном выполнении function, что не особенно полезно. Ожидается, что реализации будут предоставлять настройки, позволяющие эффективнее запускать std::execution::bulk и std::execution::bulk_chunked на разных планировщиках.

std::execution::bulk_unchunked предназначен для использования в случаях, когда между разными вызовами function могут существовать зависимости; для него требуются гарантии конкурентного продвижения вперёд (параллельного продвижения вперёд недостаточно). Для выполнения std::execution::bulk_unchunked с размером 1000 потребуется 1000 исполнительных агентов (например, потоков), работающих одновременно.

Для std::execution::bulk_unchunked не требуется политика выполнения, поскольку от function и так ожидается возможность одновременного выполнения.

Примеры

Возможное использование 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 describes the work described by calling a function to
// get a coefficient `a`, and using it to execute
//   y[i] = a * x[i] + y[i]
// for each `i` in range [0, x.size())

Возможное использование 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);
    });
// the atomic object will not be touched 100000 times; will execute faster than bulk()

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/execution/bulk

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API