Degree of control of parallelism with std :: async

Is there a way to explicitly set / limit the degree of parallelism (= number of separate threads) used by std::async and related classes?

Listening to the thread support library has nothing to do with it.

As I understand it, the std::async implementation (usually?) Uses the thread pool inside. Is there a standardized API to manage this?

For the background: Im in the setup (shared cluster), where I need to manually limit the number of cores used. If I can’t do this, the load balancer will push and I will be fined. In particular, std::thread::hardware_concurrency() does not contain any useful information, since the number of physical cores does not matter for Im restrictions.

Here is a piece of code (which in C ++ 17 with parallelism TS is likely to be written using parallel std::transform ):

 auto read_data(std::string const&) -> std::string; auto multi_read_data(std::vector<std::string> const& filenames, int ncores = 2) -> std::vector<std::string> { auto futures = std::vector<std::future<std::string>>{}; // Haha, I wish. std::thread_pool::set_max_parallelism(ncores); for (auto const& filename : filenames) { futures.push_back(std::async(std::launch::async, read_data, filename)); } auto ret = std::vector<std::string>(filenames.size()); std::transform(futures.begin(), futures.end(), ret.begin(), [](std::future<std::string>& f) {return f.get();}); return ret; } 

From a design point of view, Id expected the class std::execution::parallel_policy (from parallelism TS) to indicate that (in fact, this is what I did in the framework developed for my master's thesis). But this does not seem to be the case.

Ideal Id as a solution for C ++ 11, but if it is for later versions, I would still like to know about it (although I can not use it).

+8
c ++ multithreading asynchronous parallel-processing c ++ 11
source share
2 answers

Not. std::async opaque and you do not control its use of threads, thread pools, or anything else. In fact, you don’t even have a guarantee that it will use the stream at all - it can also be executed in the same stream (maybe pay attention to the comment @TC below), and such an implementation will still be consistent.

The C ++ streaming library should never handle fine-tuning OS / hardware flow control features, so I'm afraid that in your case you will have to program the correct support yourself, potentially using OS-based flow control primitives.

+4
source share

As other people have noted, std::async does not allow you to do this.

But

You describe one of the simpler use cases for Executors , who are currently still bouncing around the C ++ Standardization project space, right now at Study Group 1: Concurrency .

Since reading the proposals of the RG21 standards can be a word, the authors are usually tied to both the prototype of the indicative implementation only for headers and some example code .

It even includes a static thread pool and an example of almost what you want: async_1.cpp

 #include <experimental/thread_pool> #include <iostream> #include <tuple> namespace execution = std::experimental::execution; using std::experimental::static_thread_pool; template <class Executor, class Function> auto async(Executor ex, Function f) { return execution::require(ex, execution::twoway).twoway_execute(std::move(f)); } int main() { static_thread_pool pool{1}; auto f = async(pool.executor(), []{ return 42; }); std::cout << "result is " << f.get() << "\n"; } 

Thanks @ jared-hoberock for pointing me to P0668R0 , since it is much easier to follow the P0443R1 that I referred to in an earlier version of this answer.

This simplification has been applied, and now there is both an article describing the rationale ( P0761R0 ) and a much simpler version of the standard wording in P0443R2 .


As of July 2017, the only factual assumption I saw on delivery was: Michael Wong, Concurrency TS editor --- a standardization machine for performers --- feels " sure that it will switch to C ++ 20" .

+2
source share

All Articles