为什么std :: async会复制它的const和参数?

Tho*_*mas 15 c++ gcc asynchronous std c++11

我正在尝试使用std :: async来加速程序.假设我有一个功能

T* f (const T& t1, const T& t2, const T& t3)
Run Code Online (Sandbox Code Playgroud)

其中T是一种复制成本昂贵的类型.我有几个独立的f调用不同的参数,我尝试将它们与std :: async并行化,如下所示:(其中m_futures是正确类型的期货的std :: vector).

for (...) {
   m_futures.push_back (
       std::async(
           std::launch::async,
           f,
           a,b,c));
}
Run Code Online (Sandbox Code Playgroud)

我发现上面的代码减慢了程序的执行速度.我使用gdb逐步完成它,当创建未来时,T的复制构造函数被调用三次.这是为什么?参数a,b,c是堆分配的,但编译器可能不知道它?我能以某种方式明确表达吗?

是否始终是std :: async创建参数的副本,即使它们应该由const引用传递?能以某种方式避免这种情况吗?在我天真的想法中,应该只有一个指针传递给函数的不同调用(无论如何只能从内存中读取.)如果重要的话,我在Linux上使用gcc-4.6.3.

Ker*_* SB 19

仅仅存储引用是不安全的,因为没有什么可以保证数据竞争的缺失(更深刻的是,仅仅是对象的存在,正如@utapistim在她遗弃的帖子中所说的那样).

如果你真的想要一个引用而不是一个副本,并且愿意在这方面打赌你的生活是正确的,那么你可以简单地使用一个参考包装器:

std::async(std::launch::async, f, std::cref(a), std::cref(b), std::cref(c))
Run Code Online (Sandbox Code Playgroud)

  • @ChristianRau,你是对的,它是为'std :: bind`发明的,但是我看不出完美转发与它有什么关系,能够区分左值和右值并不能帮助调用包装器知道它是否有效应该通过值或引用转发参数,只有调用者才能知道哪个适合于给定的调用. (3认同)