使用OpenMP构建基于CPP迭代器的自定义聚合器

时间:2016-11-15 20:29:59

标签: c++ performance iterator openmp

以下情景:

  • 处理两种不同空间分辨率数据的模拟
  • 将更精细的分辨率数据映射到更粗略的数据的现有查找表
  • 将数据(准确地说是不同的数据)聚合或分发到其他比例的重复工作

我不想一遍又一遍地为循环等编写相同的两个,而是希望能够编写如下内容:

for(const auto gridcell& : iterator) {
   container[gridcell.id] = gridcell.map([] getRequiredData(CellRef cell){return cell->getSpecificData()})}

或使用openMP

#pragma omp parallel for
        for (int j = 0; j < iterator.size(); ++j) {

例如,对于每个0.5°网格单元,我想将lambda函数应用于所有beloningin 5'单元,重新获取所需数据并进行求和/平均......之后再进行。

到目前为止一切顺利。我已经实现了它,并且比使用两个for循环(使用#pragma omp parallel for的两个实现)慢得多。 到目前为止我所做的就是实现一个自定义迭代器,存储有关查找表的信息,在每次迭代时返回一个新的GridItem。

GridItem的实现看起来像这样:

    class FiveDegreeToZeroFiveItem {
private:
    AssociatedNodes nodes;
//Is called in public constructor not included here
    static AssociatedNodes getData(){
        AssociatedNodes out;
        std::vector<int> tmp;
        try{tmp = lu_table.at(pos);}
        catch (const std::out_of_range& oor){return out;} //No 5min nodes in 5min cell

        int i = 0;
        for (int id : tmp) {
            i = id_table.at(id);
            out.push_back(vector->at(i).get());
        }
        return out;
    }
//Other implementations like averaging etc. left out
    template <
        class ElemT,
        class FunctionT,
        class T = decltype(std::declval<FunctionT>()(std::declval<ElemT>())),
        typename = typename std::enable_if<!std::is_void<T>::value>::type
    >
    const T iterate(FunctionT fun) const{
        T val;
        for (int j = 0; j < nodes.size(); ++j) {
            val += fun(nodes.at(j));
        }
        return val;
    }
public:
//Constructor with call to private getData() omitted for readability


template <
        class ElemT,
        class FunctionT
    >
    const void map(FunctionT fun) const {
        iterate<ElemT>(std::forward<FunctionT>(fun));
    }
};

我遗漏了一些代码,将其简化为必需品(如果我错过了一些重要内容,我会很乐意将其包含在内)。它实现了它的构建,但正如我提到的那样慢。 我的方法有一般性缺陷吗?或者有没有理由为什么它比两个for循环慢得多? (错误使用)openMP的原因是什么?

0 个答案:

没有答案