我有一些代码,我想以下列方式使用OpenMP:
std::vector<int> v(1000);
# pragma omp parallel for
for (int i = 0; i < 1000; ++i) {
v[i] = i;
}
Run Code Online (Sandbox Code Playgroud)
我已经读过,在多个线程写入单个容器的情况下,STL向量容器不是线程安全的,这意味着我需要在进行任何写入之前锁定向量; 但是,我也被告知上面的写操作在某种程度上是"原子的",所以上面没有竞争条件.有人可以澄清一下吗?
对于我的一个应用程序,我需要生成大小为2 ^ 35的向量(我的RAM的大小为96 GB,因此这个向量可以很容易地适应RAM).
int main ()
{
int i;
/* initialize random seed: */
srand (time(NULL));
vector<int> vec;
do {
i = rand() % 10 + 1;
vec.push_back(i);
} while ((vec.size()*sizeof(int))<pow(2,35));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,我注意到我的while while循环无限执行.其中一个可能的原因是vec.size()long unsigned int的范围,它远远小于插入的元素的数量pow(2,35),因为我认为它在无限循环中.我可能错了.如果我错了,请纠正我.但有人可以告诉我如何pow(2,35)在vec中插入大于数字的数字.
gcc版本:4.8.2
我有一个算法,其中一个目标是填充向量.出于性能考虑,算法的迭代遍布OpenMP线程.我想知道哪种方式可以提供更好/更安全的填充向量的方法.
注意,向量的排序必须是一致的(即vec1的值n必须来自与vec2的值n相同的迭代.)
假设1:
std::vector<BasicType> vec1;
std::vector<BasicType> vec2;
#pragma opm parallel for
for(...)
{
// Do some intensive stuff to compute val1 and val2
// ...
#pragma omp critical
{
vec1.push_back(val1);
vec2.push_back(val2);
}
}
// Then go on to work with vec1 and vec2...
Run Code Online (Sandbox Code Playgroud)
假设2:
std::vector<BasicType> vec1;
std::vector<BasicType> vec2;
#pragma opm parallel
{
std::vector<BasicType> vec1local;
std::vector<BasicType> vec2local;
#pragma omp for
for(...)
{
// Do some intensive stuff to compute val1 and val2
// ...
vec1local.push_back(val1);
vec2local.push_back(val2);
}
#pragma omp critical
{ …Run Code Online (Sandbox Code Playgroud) 假设我有一个f(i)依赖于索引的函数i(以及无法预先计算的其他值)。我想填充一个数组,a以便a[n] = sum(f(i)) from i=0 to n-1.
编辑:在 Hristo Iliev 发表评论后,我意识到我在做什么是一个累积/前缀总和。
这可以用代码编写为
float sum = 0;
for(int i=0; i<N; i++) {
sum += f(i);
a[i] = sum;
}
Run Code Online (Sandbox Code Playgroud)
现在我想使用 OpenMP 并行执行此操作。我可以用 OpenMP 做到这一点的一种方法是f(i)并行写出 的值,然后串行处理依赖关系。如果f(i)是一个慢函数,那么这可以很好地工作,因为非并行循环很简单。
#pragma omp parallel for
for(int i=0; i<N; i++) {
a[i] = f(i);
}
for(int i=1; i<N; i++) {
a[i] += a[i-1];
}
Run Code Online (Sandbox Code Playgroud)
但是可以在没有 OpenMP 的非并行循环的情况下做到这一点。然而,我想出的解决方案很复杂,而且可能是骇人听闻的。所以我的问题是,是否有一种更简单、更简单的方法来使用 OpenMP 做到这一点?
下面的代码基本上运行我为每个线程列出的第一个代码。结果是a给定线程中的值在一个常量内是正确的。我将每个线程的总和保存到一个suma …
我试图将OpenMP并行化添加到工作代码(只是一个for循环),但我无法摆脱分段错误.问题来自这条线:
pos += sprintf(com + pos, "%d ", i);
Run Code Online (Sandbox Code Playgroud)
com是一个字符数组,我尝试将其定义为char com[255]或char *com = malloc(255*sizeof(char))在for循环内部和之前.我在循环之前定义的时候添加private(com)了#pragma omp parallel for指令com.我也尝试过初始化和使用firstprivate.(pos是一个整数,初始化为0)
当我不添加-fopenmp一切工作正常,但与-fopenmp它给出segfault.我错过了什么?