Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::async copy its const & arguments?

I'm trying to speed up a program by using std::async. Let's say I have a function

T* f (const T& t1, const T& t2, const T& t3)

Where T is a type that is expensive to copy. I have several independent calls of f with different arguments and I try to parallelize them with std::async approximately like this: (where m_futures is a std::vector of futures of the correct type).

for (...) {
   m_futures.push_back (
       std::async(
           std::launch::async,
           f,
           a,b,c));
}

I observed that the above code slows down the execution of my program. I stepped through it with gdb and when the future is created, the copy constructor of T is called three times. Why is that? The arguments a,b,c are heap allocated, but maybe the compiler does not know about it? Can I make it explicit somehow?

Is it always the case that std::async creates copies of the arguments, even if they should be passed by const reference? Can I avoid this somehow? In my naive mind, there should just be a pointer passed around to the different invocations of the function (which only reads from the memory anyway.) I'm using gcc-4.6.3 on Linux if that matters.

like image 566
Thomas Avatar asked Feb 13 '13 10:02

Thomas


People also ask

Does STD async start a new thread?

If the async flag is set, then a callable function will be executed in a separate thread. If the deferred flag is set, a callable function will be stored together with its arguments, but the std::async function will not launch a new thread.

What does STD async return?

std::async returns a std::future<T>, that stores the value returned by function object executed by std::async().

How does C++ async work?

As the name indicates, C++ async is a function template fn, which takes functions or function objects as arguments (basically called callbacks) and runs them asynchronously. It returns the std:: the future object which is used to keep the result of the above function. The result is stored in the shared state.


1 Answers

It wouldn't be safe to store references only, since there's nothing to guarantee the absence of data races (and more profoundly, the mere existence of objects, as @utapistim said in her sadly deleted post).

If you actually want a reference rather than a copy, and you're willing to bet your life on this being correct, then you can simply use a reference wrapper:

std::async(std::launch::async, f, std::cref(a), std::cref(b), std::cref(c))
like image 187
Kerrek SB Avatar answered Oct 04 '22 11:10

Kerrek SB