std::execution:: bulk, std::execution:: bulk_chunked, std::execution:: bulk_unchunked
|
Определено в заголовочном файле
<execution>
|
||
|
std
::
execution
::
sender
auto
bulk
(
std
::
execution
::
sender
auto
input,
|
(1) | (начиная с C++26) |
|
std
::
execution
::
sender
auto
bulk_chunked
(
std
::
execution
::
sender
auto
input,
|
(2) | (начиная с C++26) |
|
std
::
execution
::
sender
auto
bulk_unchunked
(
std
::
execution
::
sender
auto
input,
|
(3) | (начиная с C++26) |
Содержание |
Параметры
| input | - | отправитель, который после выполнения передает значения, на которых выполняется функция |
| policy | - | политика выполнения, присоединенная к execution policy attached to function / function2 |
| function | - |
вызываемый объект, который будет вызываться для каждого индекса в диапазоне
[
0
,
size
)
, передавая также значения, произведенные отправителем input
|
| 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 описывает работу, заключающуюся в вызове функции для // получения коэффициента `a` и его использовании для выполнения // y[i] = a * x[i] + y[i] // для каждого `i` в диапазоне [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); }); // атомный объект не будет обрабатываться 100000 раз; выполнится быстрее чем bulk()