[英]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.