我的C ++代码评估时间序列数据上的非常大的积分(t2> t1)。积分是固定长度的,并且当前存储在[m×2]列双精度数组中。第1列是时间。第2列是正在整合的信号。代码在四核或八核机器上运行。
对于具有 k 核心的计算机,我想:
如何在不对可用内核数量进行硬编码的情况下实现上述目标?
我目前正在使用VS 2012。
更新Clarity:
例如,这里是粗糙的伪代码
data is [100000,2] double
result = MyIntegrator(data[1:50000,1:2]) + MyIntegrator(data[50001:100000, 1:2]);
我需要在单独的线程中评估MyIntegrator()
函数。主线程等待两个结果。
答案 0 :(得分:2)
std::thread::hardware_concurrency()
怎么样?
答案 1 :(得分:2)
获取正在运行的核心数,通常可以使用std::thread::hardware_concurrency()
返回实现支持的并发线程数。该值应仅被视为提示。
如果为零,则可以尝试根据操作系统运行特定命令。 This似乎是查找核心数量的好方法。
您仍然需要进行测试以确定多线程是否会给您带来实实在在的好处,请记住不要过早优化:)
答案 2 :(得分:2)
这是执行问题的多线程集成的源。
#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()
作为线程数来调用它,它应该可以工作。
(特别是,为了保持简单,我有(持续时间,值)对而不是(时间,值),但这只是一个小细节。
答案 3 :(得分:1)
你可以过度安排,看看它是否会伤害你的表现。将数组拆分为固定长度的小间隔(可在一个量子中计算,可能适合一个缓存页面),并查看性能与根据CPU数量进行拆分的比较。
使用std :: packaged_task并将其传递给一个线程,以确保您不受“启动”配置的伤害。
下一步将介绍线程池,但这更复杂。
答案 4 :(得分:0)
您可以接受工作线程数的命令行参数。