我创建了 C++ 方法来查找数字的除数。第二步是在 C++ 中使用 openmp。
不幸的是,我无法管理为什么我的函数 doStuff
会抛出 memory error
。可能问题出在线程上,我在所有线程停止之前检查数组。有人可以帮助我吗?
没有必要把我的程序全部看完,问题出在doStuff()
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include "omp.h"
using namespace std;
vector<int> dividors;
int NUMBER = 1000;
bool ifContains(vector<int> element, int dividedNumber)
{
for(int i=0; i<dividors.size(); i++)
{
if(dividors[i] == dividedNumber)
return true;
}
return false;
}
void doStuff()
{
int sqr = (int) sqrt(NUMBER);
int sqrp1 = sqr + 1;
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 1; i < sqrp1; i++)
{
if (NUMBER % i == 0)
{
if (!ifContains(dividors, i))
dividors.push_back(i);
int dividednumber = NUMBER / i;
if (!ifContains(dividors,dividednumber))
dividors.push_back(dividednumber);
}
}
sort(dividors.begin(), dividors.end());
#pragma omp for nowait
for (int i = 0; i < dividors.size(); i++)
{
cout << dividors[i] << "\r\n";
}
}
}
int main()
{
doStuff();
return 0;
}
这个我也试过了,但是不行
void doStuff()
{
int sqr = (int) sqrt(NUMBER);
int sqrp1 = sqr + 1;
#pragma omp parallel
{
#pragma omp for
for (int i = 1; i < sqrp1; i++)
{
if (NUMBER % i == 0)
{
if (!ifContains(dividors, i))
dividors.push_back(i);
int dividednumber = NUMBER / i;
if (!ifContains(dividors,dividednumber))
dividors.push_back(dividednumber);
}
}
#pragma omp single
sort(dividors.begin(), dividors.end());
#pragma omp single
for (int i = 0; i < dividors.size(); i++)
{
cout << dividors[i] << "\r\n";
}
}
}
最佳答案
有几种方法可以解决这个问题。最简单的就是使用 ordered
子句。请参阅下面的代码。但是,这消除了一些并行性。更好的方法是在并行 block 中声明 prviate dividors vector (我称之为 dividors_private
),这样每个线程都有自己的私有(private)版本,然后写入 dividors
vector 关键 block 。排序是在私有(private) vector 上并行完成的。最后的排序是在单个线程中对 dividors
完成的,但由于其中大部分已经排序,所以速度很快。请参见下面的第二个代码:
带顺序的代码版本:
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include "omp.h"
using namespace std;
vector<int> dividors;
int NUMBER = 1000;
bool ifContains(vector<int> dividors, int dividedNumber)
{
for(int i=0; i<dividors.size(); i++)
{
if(dividors[i] == dividedNumber)
return true;
}
return false;
}
void doStuff()
{
int sqr = (int) sqrt(NUMBER);
int sqrp1 = sqr + 1;
#pragma omp parallel
{
#pragma omp for ordered
for (int i = 1; i < sqrp1; i++)
{
if (NUMBER % i == 0)
{
#pragma omp ordered
{
dividors.push_back(i);
if (!ifContains(dividors, i))
dividors.push_back(i);
int dividednumber = NUMBER / i;
if (!ifContains(dividors, dividednumber))
dividors.push_back(dividednumber);
}
}
}
}
sort(dividors.begin(), dividors.end());
for (int i = 0; i < dividors.size(); i++)
{
cout << dividors[i] << "\r\n";
}
}
int main()
{
doStuff();
return 0;
}
使用私有(private)除数 vector 的代码版本
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include "omp.h"
using namespace std;
vector<int> dividors;
int NUMBER = 1000;
bool ifContains(vector<int> dividors, int dividedNumber)
{
for(int i=0; i<dividors.size(); i++)
{
if(dividors[i] == dividedNumber)
return true;
}
return false;
}
void doStuff()
{
int sqr = (int) sqrt(NUMBER);
int sqrp1 = sqr + 1;
#pragma omp parallel
{
vector<int> dividors_private;
#pragma omp for nowait
for (int i = 1; i < sqrp1; i++)
{
if (NUMBER % i == 0)
{
dividors_private.push_back(i);
//printf("i %d\n", i);
if (!ifContains(dividors_private, i))
dividors_private.push_back(i);
int dividednumber = NUMBER / i;
if (!ifContains(dividors_private, dividednumber))
dividors_private.push_back(dividednumber);
}
}
sort(dividors_private.begin(), dividors_private.end());
#pragma omp critical
{
dividors.insert(dividors.end(), dividors_private.begin(), dividors_private.end());
}
}
sort(dividors.begin(), dividors.end());
for (int i = 0; i < dividors.size(); i++)
{
cout << dividors[i] << "\r\n";
}
}
int main()
{
doStuff();
return 0;
}
关于c++ - 运行方法并等待完成所有 for 循环 openmp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16722990/