繁体   English   中英

将向量过滤到并行的另一个向量上

[英]Filtering vector onto another vector in Parallel

我正在尝试将一个向量并行过滤到另一个向量中。 我当前的设置产生了太多的开销,所以它甚至比串行的还要慢。 具体来说:

#pragma omp parallel for collapse(2)
for(int i = 0 ; i < a.size() ; i++){
   for(int j = 0 ; j < a.size() ; j++){
      if(meetsConditions(a[i], a[j])){
         std::vector<int> tmp = {i, j};
         #pragma omp critical
         b.push_back(tmp);
      }
   }
}

我正在保存索引,因为我想稍后对满足条件的每对夫妇运行一个单独的序列号 function:

for(auto element : b){
   doSmth(a[element[0]], a[element[1]]);
}

我尝试用一个新的空向量来做,将它的大小调整为 a.size()*a.size(),当它递增时使用原子子句中的第三个索引分配元素,但这导致了数据竞争(除非我看错了)。 请问我go怎么解决这个问题? 也许使用列表可以使它更容易? 或者直接存储指向这些元素的指针会更容易? 我真的是 C++ 的新手,所以我不太确定如何让它工作。

假设a.size()足够大,我将只并行化第一个循环(不崩溃),对每个线程使用本地b_local ,最后将所有b_local连接到共享b

#pragma omp parallel
{
    std::vector<std::vector<int>> b_local;
    #pragma omp for
    for (int i = 0 ; i < a.size() ; i++){
        for(int j = 0 ; j < a.size() ; j++){
            if(meetsConditions(a[i], a[j])){
                std::vector<int> tmp = {i, j};
                b_local.push_back(tmp);
            }
        }
    }
    #pragma omp critical
    b.insert(b.end(),b_local.begin(),b_local.end()); 
}

这应该更有效,因为critical部分现在在循环之外并且每个线程只遇到一次。 b_local对每个线程都是私有的,更新它时不需要critical

但实际上我不确定它是否值得并行化,除非 meetsConditions() 有很多计算。

我希望这段代码运行得更慢,因为你有一个关键部分将强制 b.push_back(tmp) 在单个线程中运行。

也许希望删除关键部分,而是将结果直接写入已经适当大小的 b,例如:

vector<std::vector<int>> b;
b.resize(a.size() * a.size());

#pragma omp parallel for collapse(2)
for (int i = 0; i < a.size(); i++) {
    for (int j = 0; j < a.size(); j++) {
        if (meetsConditions(a[i], a[j])) {
            std::vector<int> tmp = { i, j };
            b.at((i*a.size())+j) = tmp;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM