Kon*_*lph 9 c++ parallel-processing multithreading asynchronous c++11
有没有办法明确设置/限制std::async和相关类使用的并行度(=单独线程数)?
仔细阅读线程支持库并没有发现任何有希望的东西.
尽可能接近,std::async实现(通常是?)在内部使用线程池.是否有标准化的API来控制这个?
对于后台:我在一个设置(共享集群)中,我必须手动限制使用的核心数.如果我没有这样做,负载共享调度程序会抛出一个拟合,我会受到惩罚.特别是,std::thread::hardware_concurrency()没有有用的信息,因为物理核心的数量与我所受的约束无关.
这是一段相关的代码(在C++ 17中使用并行TS,可能会使用并行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;
}
Run Code Online (Sandbox Code Playgroud)
从设计的角度来看,我已经期望这个std::execution::parallel_policy类(来自并行性TS)允许指定(事实上,这就是我在我为硕士论文设计的框架中所做的那样).但事实似乎并非如此.
理想情况下,我想要一个C++ 11的解决方案,但是如果有一个用于更高版本的解决方案,我仍然想知道它(尽管我不能使用它).
No.std::async是不透明的,您无法控制它对线程、线程池或其他任何东西的使用。事实上,您甚至无法保证它会使用一个线程——它也可能在同一个线程中执行(可能,注意下面的@TC 注释),并且这样的实现仍然是一致的。
C++ 线程库从来不应该处理线程管理的操作系统/硬件细节的微调,所以我担心,在你的情况下,你必须自己编码以获得适当的支持,可能使用操作系统提供的线程控制原语。
正如其他人所指出的,std::async不允许您这样做。
然而(但请参阅答案末尾的 2022 年 5 月更新)
\n您正在描述Executors的一个更简单的用例,该用例目前仍在 C++ 标准化的设计空间中活跃,特别是现在在研究组 1:并发性中。
\n由于阅读 WG21 标准提案可能会很困难,因此它们的作者已链接到仅包含原型标头的参考实现和一些示例代码。
\n它甚至包括一个静态线程池,以及几乎正是您想要的示例:\n async_1.cpp
\n#include <experimental/thread_pool>\n#include <iostream>\n#include <tuple>\n\nnamespace execution = std::experimental::execution;\nusing std::experimental::static_thread_pool;\n\ntemplate <class Executor, class Function>\nauto async(Executor ex, Function f)\n{\n return execution::require(ex, execution::twoway).twoway_execute(std::move(f));\n}\n\nint main()\n{\n static_thread_pool pool{1};\n auto f = async(pool.executor(), []{ return 42; });\n std::cout << "result is " << f.get() << "\\n";\n}\nRun Code Online (Sandbox Code Playgroud)\n感谢 @jared-hoberock 向我指出P0668R0作为P0443R1的更简单的后续版本,我在这个答案的早期版本中引用了 P0443R1。
\n这种简化已经得到应用,现在既有一篇描述其基本原理的论文 ( P0761R0 ),也有P0443R2中标准措辞的简单得多的版本。
\n截至 2017 年 7 月,我看到的对此的唯一实际猜测是:Concurrency TS(执行器的标准化工具)的编辑 Michael Wong 感到“有信心它将进入 C+” +20”。
\n我仍在获取 Stack Overflow Points\xe2\x84\xa2 来获取此答案,因此这里是 2022 年 5 月的更新:
\n执行器没有登陆 C++20。
\n“A Unified Executors Proposal for C++”于 2020 年达到修订版 14 ( P0443R14 ),并提出了一篇新论文std::execution( P2300R5 ) 作为后续;关于新论文的原因以及与 P0443 的差异,请参见第 1.8和1.9节。
尤其:
\n\n\n根据 LEWG 的指示,省略了特定的线程池实现。
\n
“在线程池中执行”示例std::execution如下所示:
#include <experimental/thread_pool>\n#include <iostream>\n#include <tuple>\n\nnamespace execution = std::experimental::execution;\nusing std::experimental::static_thread_pool;\n\ntemplate <class Executor, class Function>\nauto async(Executor ex, Function f)\n{\n return execution::require(ex, execution::twoway).twoway_execute(std::move(f));\n}\n\nint main()\n{\n static_thread_pool pool{1};\n auto f = async(pool.executor(), []{ return 42; });\n std::cout << "result is " << f.get() << "\\n";\n}\nRun Code Online (Sandbox Code Playgroud)\n这里有很多事情需要处理。过去十年的工作几乎已经放弃了“std::async和相关类”,所以也许这个问题的实际答案不再是
\n\n然而
\n
但
\n\n\n\n不,而且永远不会有。将会有一个不同的模型可供您替代。
\n
\n\n\n
std::async//std::future,std::promiseC++11\xe2\x80\x99s 旨在暴露异步性,效率低下,难以正确使用,并且严重缺乏通用性,使其在许多上下文中无法使用。
P2453R0记录了 LEWG 参与者对当前方法的粗略感受,以及它如何与现有的 Networking TS(即 Asio)交互,Asio 有自己的并发模型。我对民意调查和评论的阅读表明,两者都不太可能出现在 C++23 中。
\n我仍在获取 Stack Overflow Points\xe2\x84\xa2 来获取此答案,因此这里是 2023 年 6 月的更新:
\n执行器没有登陆 C++23。
\nP2300 看起来越来越受欢迎,一直到P2300R7,并且有一个实验性参考实现和基于它的进一步标准化探索,例如P2882R0和P2500R1 + P2690R1。后一个链接表明 P2300 是针对 C++26 的,这也是LEWG 去年的弱共识,尽管只有一半的参与者和较少的评论。
\n| 归档时间: |
|
| 查看次数: |
797 次 |
| 最近记录: |