Home DEVELOPER C++ Programming Language: cstd::execute: Asynchronous Algorithms

C++ Programming Language: cstd::execute: Asynchronous Algorithms

0


According to the general idea of std::execution In my previous blog post I dedicated myself to adaptive asynchronous algorithms.

Advertisement




It’s not easy, offer P2300R10 introduce. Firstly it is powerful and secondly it is very long. Therefore, I focus on a few aspects.




Rainer Grimm has been working as a software architect, team and training manager for many years. He enjoys writing articles on the programming languages ​​C++, Python, and Haskell, but also frequently speaks at expert conferences. On his blog Modern C++ he discusses his passion C++ in depth.

C++ Programming Language: cstd::execute: Asynchronous Algorithms

Several priorities apply to the proposal. Must have C++ model for asynchronous code

  • Be composable and generic, allowing users to write code that can be used with many different types of execution resources.
  • Summarize common asynchronous patterns into customizable and reusable algorithms so that users don’t have to invent everything themselves.
  • Making it easier to get right by construction.
  • Support a diversity of execution resources and execution agents, as not all execution agents are the same; Some are less powerful than others, but no less important.
  • Allow everything to be optimized by an execution resource, including transfer to other execution resources, but do not require execution resources to optimize everything –
    Take into account all sensible use cases, domains and platforms.
  • Make sure errors are passed through but error handling doesn’t become a burden.
  • Support termination which is not an error.
  • Have clear and precise answers about where things are done.
  • Be able to manage and terminate object lifetimes asynchronously.

The terms execution resource, execution agent and scheduler are important to understand. std::execution Necessary. Here are the first simplified definitions.

One execution resource A program is a resource unit that manages a set of execution agents. Examples of execution resources include active threads, thread pools, or additional hardware accelerators.

every function call is in one execution agent execute.

A scheduler Execution is an abstraction of a resource with a unified, common interface for scheduling work on that resource. That’s a transmitter factory.

From here is the “Hello World” program std::executionThis time this program can happen… compiler explorer Play on, and my analysis will go deeper.

// HelloWorldExecution.cpp

#include 
#include 
#include 


int main() {
  exec::static_thread_pool pool(8);
  auto sch = pool.get_scheduler();

  auto begin = stdexec::schedule(sch);
  auto hi = stdexec::then(begin, () {
    std::cout << "Hello world! Have an int.\n";
    return 13;
  });
  auto add_42 = stdexec::then(hi, ()(int arg) { return arg + 42; });

  auto (i) = stdexec::sync_wait(add_42).value();

  std::cout << "i = " << i << '\n';
}

First, here is the output of the program:



The program starts by including the required headers:exec/static_thread_pool.hpp>To create thread pool andstdexec/execution.hpp>For performance-related utilities.

In main the function will continue static_thread_pool pool Made of eight threads.

member work get_scheduler The thread pool is called to provide a lightweight handle to the execution resource scheduler. sch Which is used to schedule dispatchers in the thread pool. In this case, the execution resource is a thread pool, but it can also be the main thread, the GPU, or a task framework.

The program then creates a series of dispatchers that are executed by execution agents.

first station begin will work with the function stdexec::schedule Created a dispatcher on the specified scheduler sch Plans. stdexec::schedule There is a so-called transmitter factory. There are other transmitter factories as well. I am using the namespaces of the upcoming standard:

next station hi Uses transmitter adapter stdexec::thenwhich is transmitter begin And used lambda function. This lambda function returns “Hello world! Have an int.” on the console and returns an integer value 13 Back. third station add_42 The transmitter also comes with an adapter stdexec::then created. sequel takes over hi function and another lambda that has an integer argument arg Receives and adds result 42 Return. Dispatchers run asynchronously and are generally composable.

std::execution Additional transmitter adapters provide:

execution::continues_on
execution::then
execution::upon_*
execution::let_*
execution::starts_on
execution::into_variant
execution::stopped_as_optional
execution::stopped_as_error
execution::bulk
execution::split
execution::when_all

Unlike the sender, the sender-consumer runs synchronously. stdexec::sync_wait-Waiting for call to complete add_42-transmitter. valueThe method is used for the result of sync_wait Called by the sender to get the value generated, which is passed to the variable i Unpacked.

this_thread::sync_wait The only sender in the execution framework is the consumer.

In my next article I will analyze a more sophisticated algorithm.


(rme)

C++ Programming Language: cstd::execute: Asynchronous Algorithms

NO COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exit mobile version