首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++11 async<>,具有未知数目的可用核

c++11 async<>,具有未知数目的可用核
EN

Stack Overflow用户
提问于 2013-01-28 19:29:55
回答 5查看 869关注 0票数 0

我的C++代码对timeseries数据(t2 >> t1)上的非常大的积分进行了评估。积分是固定长度的,目前存储在mx2列双列数组中。第一栏是时间。第二列是正在整合的信号。代码运行在四核或八核机器上。

对于一台具有k核的机器,我想:

  • 分离k-1工作进程(每个剩余核心一个),以评估积分的部分(梯形积分),并将其结果返回给等待的主线程。
  • 实现上述目标而不需要对原始数组的部分进行深度复制。
  • 实现C++11异步模板的可移植性

在不硬编码可用核数的情况下,如何实现上述目标?

我目前正在使用VS 2012。

为清晰起见更新

例如,下面是粗略的psuedo代码

代码语言:javascript
复制
data is [100000,2] double

result = MyIntegrator(data[1:50000,1:2]) + MyIntegrator(data[50001:100000, 1:2]); 

我需要在单独的线程中计算MyIntegrator()函数。主线程等待这两个结果。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-01-28 21:01:39

这里是对问题进行多线程集成的源代码。

代码语言:javascript
复制
#include <vector>
#include <memory>
#include <future>
#include <iterator>
#include <iostream>

struct sample {
  double duration;
  double value;
};
typedef std::pair<sample*, sample*> data_range;
sample* begin( data_range const& r ) { return r.first; }
sample* end( data_range const& r ) { return r.second; }

typedef std::unique_ptr< std::future< double > > todo_item;

double integrate( data_range r ) {
  double total = 0.;
  for( auto&& s:r ) {
    total += s.duration * s.value;
  }
  return total;
}

todo_item threaded_integration( data_range r ) {
  return todo_item( new std::future<double>( std::async( integrate, r )) );
}
double integrate_over_threads( data_range r, std::size_t threads ) {
  if (threads > std::size_t(r.second-r.first))
    threads = r.second-r.first;
  if (threads == 0)
    threads = 1;
  sample* begin = r.first;
  sample* end = r.second;

  std::vector< std::unique_ptr< std::future< double > > > todo_list;

  sample* highwater = begin;

  while (highwater != end) {
    sample* new_highwater = (end-highwater)/threads+highwater;
    --threads;
    todo_item item = threaded_integration( data_range(highwater, new_highwater) );
    todo_list.push_back( std::move(item) );
    highwater = new_highwater;
  }
  double total = 0.;
  for (auto&& item: todo_list) {
    total += item->get();
  }
  return total;
}

sample data[5] = {
  {1., 1.},
  {1., 2.},
  {1., 3.},
  {1., 4.},
  {1., 5.},
};
int main() {
  using std::begin; using std::end;
  double result = integrate_over_threads( data_range( begin(data), end(data) ), 2 );
  std::cout << result << "\n";
}

它需要进行一些修改才能以您指定的格式读取数据。

但是您可以使用std::thread::hardware_concurrency()作为线程的数量来调用它,并且它应该可以工作。

(特别是,为了保持简单,我有一对(持续时间、值)而不是(时间、值),但这只是一个次要的细节)。

票数 2
EN

Stack Overflow用户

发布于 2013-01-28 19:35:07

std::thread::hardware_concurrency()

票数 2
EN

Stack Overflow用户

发布于 2013-01-28 19:42:07

获取运行的核数,通常可以在std::thread::hardware_concurrency()中找到

返回实现支持的并发线程数。这个值应该只被看作是一个提示。

如果这是零,那么您可以尝试运行特定的命令,基于操作系统。This似乎是一个很好的方法来找出核的数量。

您仍然需要进行测试,以确定多线程是否会给您带来实实在在的好处,请记住不要过早地优化:)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14569662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档