GCC与std :: async(std :: launch :: async)的行为与Clang的行为

Bou*_*ner 10 c++ policy gcc clang c++11

有没有人有相当新的经验std::async?我们目前正在实现并行文件解析器,它读取文件块并将此块传递给异步函数.

使用Clang(v3.0)这种方式可以很好地使用默认std::async策略(取决于实现).在一台双核机器上,它最多可以激活4个线程,效果非常好.

但是使用GCC(v4.7),文件读取线程不会产生任何新线程,使程序最终完全顺序.

使用std::launch::async,两个版本几乎都在做同样的事情(应该是这样).

有谁知道GCC的c ++ 11线程功能的当前状态?或者这可能是我们实施中的错误?

短代码:

while (readNewChunk()) {
    Chunk &chunk = fileReader_.getChunk(); //reading the file
    ChunkLoader *chunkLoader = new ChunkLoader();
    auto ftr = std::async(std::launch::async, &ChunkLoader::createDictionaries, chunkLoader);
    dictCreationFutures_.push_back(std::move(ftr));
}
Run Code Online (Sandbox Code Playgroud)

eph*_*ent 17

行为在规范内,即使它不是你想要的.如果您没有指定启动策略,那么它将被视为async|deferred,这意味着由实现来决定哪个.deferred如果给出选择,GCC总是会选择.

  • 我不同意.这就是标准所说的(强调我的):"如果这个策略与其他策略一起指定,例如当使用`launch :: async | launch :: deferred`的策略值时,实现应该推迟调用或选择当没有更多的并发可以被有效利用时,政策_." 这与启动任何延迟的新线程有很大不同. (4认同)

std*_*ave 5

EDIT2:我会再解释一下。

std::async 承诺“未来”;那就是:当你想要它时,它就会出现。它可能现在就计算出来,也可能在您要求时计算出来,我们只是承诺它会发生。

就像我下面的海报指出的那样,GCC 默认为延迟(这意味着,它会在被要求时履行该承诺,而且可能不会提前)。这种默认设置的原因是因为 GCC 还没有提供适当的 C++11 线程支持。它没有一个很好的内部线程调度程序,等等。这有点像黑客。不,更像是一堆黑客。事实上,如果你在 GCC 上用 C++11 编写线程代码,更重要的是当它们确实实现特性时,它会正常工作;现在,它主要工作正常。我的意思是,你最终得到了结果,对吧?

如果你告诉它启动一个线程,它会,因为它太愚蠢了(目前)意识到它可以而且应该自己(不像 CLang,它目前有一个更好的内部线程调度程序)。

编辑:认真的?误导向下改装!

这是我的参考! http://gcc.gnu.org/projects/cxx0x.html。请注意,包括“内存模型”在内的“并发”下的几乎所有内容都标记为 NO 。GCC.GNU.org。你知道,他们是 GCC 的权威。

从我的评论中稍微编辑:

我真的会推荐使用 Boost。当 GCC 准备就绪时,对适当的 C++11 支持不会有太大的飞跃。C++11 中的新线程模型需要与 GCC 或 MSVC 使用的内存布局不同的内存布局,并且它们还没有真正实现。

  • 是的,但这并不能解释“内存*布局*”发生了什么变化。布局是关于事物相对于其他事物的位置。内存 *model* 解释了有关何时访问的变量在其他线程中可见的规则等。 (6认同)
  • C++11 在“内存布局”方面发生了什么变化? (3认同)
  • 我投了赞成票。我认为 GCC 的行为是完全错误的。请参阅我在另一个答案下的评论。 (3认同)