提升线程概念化/问题
Boost Threading Conceptualization / Questions
我有一个函数,通常运行50次(运行50次模拟)。通常这是按顺序单线程完成的,但我想使用多线程来加快速度。线程不需要访问彼此的内存或数据,所以我不认为比赛是一个问题。从本质上讲,线程应该完成它的任务,并返回到main,它已经完成了,也返回一个双精度值。
首先,查看所有的boost文档和示例真的让我很困惑,我不确定我在寻找什么了。boost::线程吗?提高未来?有人能给我举个例子吗?此外,我不明白如何指定运行多少线程,它更像是我将运行50个线程和操作系统处理何时执行它们?
如果您的代码完全是cpu限制的(没有网络/磁盘IO),那么您将受益于启动尽可能多的后台线程。使用Boost的hardware_concurrency()函数来确定这个数字和/或允许用户设置它。仅仅启动一堆线程是没有帮助的,因为这会增加创建、切换和终止线程所造成的开销。
启动线程的代码是一个简单的循环,后面跟着另一个等待线程完成的循环。您也可以使用thread_group类。如果作业的数量不知道,并且不能在线程启动时分配,可以考虑使用一个线程池,在这个线程池中启动一个合理数量的线程,然后在它们出现时给它们分配作业。
读取Boost。线程期货文档提供了使用期货和async
来实现这一目标的想法。它还展示了如何使用thread
对象手动完成(困难的方式)。
给定这个序列代码:
double run_sim(Data*);
int main()
{
const unsigned ntasks = 50;
double results[ntasks];
Data data[ntasks];
for (unsigned i=0; i<ntasks; ++i)
results[i] = run_sim(data[i]);
}
一个简单的平行版本是:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <boost/bind.hpp>
double run_task(Data*);
int main()
{
const unsigned nsim = 50;
Data data[nsim];
boost::future<int> futures[nsim];
for (unsigned i=0; i<nsim; ++i)
futures[i] = boost::async(boost::bind(&run_sim, &data[i]));
double results[nsim];
for (unsigned i=0; i<nsim; ++i)
results[i] = futures[i].get();
}
因为boost::async
还不支持延迟函数,每个异步调用将创建一个新线程,所以这将一次产生50个线程。这可能执行得很差,所以您可以将它分成更小的块:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
double run_sim(Data*);
int main()
{
const unsigned nsim = 50;
unsigned nprocs = boost::thread::hardware_concurrency();
if (nprocs == 0)
nprocs = 2; // cannot determine number of cores, let's say 2
Data data[nsim];
boost::future<int> futures[nsim];
double results[nsim];
for (unsigned i=0; i<nsim; ++i)
{
if ( ((i+1) % nprocs) != 0 )
futures[i] = boost::async(boost::bind(&run_sim, &data[i]));
else
results[i] = run_sim(&data[i]);
}
for (unsigned i=0; i<nsim; ++i)
if ( ((i+1) % nprocs) != 0 )
results[i] = futures[i].get();
}
如果hardware_concurrency()
返回4,这将创建三个新线程然后在main()
线程中同步调用run_sim
,然后创建另外三个新线程然后同步调用run_sim
。这将防止同时创建50个线程,因为主线程停止做一些工作,这将允许一些其他线程完成。
上面的代码需要一个最新版本的Boost,如果你能使用c++ 11,使用标准c++会稍微容易一些:
#include <future>
double run_sim(Data*);
int main()
{
const unsigned nsim = 50;
Data data[nsim];
std::future<int> futures[nsim];
double results[nsim];
unsigned nprocs = std::thread::hardware_concurrency();
if (nprocs == 0)
nprocs = 2;
for (unsigned i=0; i<nsim; ++i)
{
if ( ((i+1) % nprocs) != 0 )
futures[i] = std::async(boost::launch::async, &run_sim, &data[i]);
else
results[i] = run_sim(&data[i]);
}
for (unsigned i=0; i<nsim; ++i)
if ( ((i+1) % nprocs) != 0 )
results[i] = futures[i].get();
}
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- 提升线程概念化/问题