gpt4 book ai didi

c++ - OpenMP/C++ : number of elements in for-loop

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:44:51 26 4
gpt4 key购买 nike

我正在用 C++ 中的 OpenMP 做一些非常简单的测试,我遇到了一个可能很愚蠢的问题,但我找不到问题所在。在以下 MWE 中:

#include <iostream>
#include <ctime>
#include <vector>
#include <omp.h>

int main()
{

int nthreads=1, threadid=0;
clock_t tstart, tend;
const int nx=10, ny=10, nz=10;
int i, j, k;
std::vector<std::vector<std::vector<long long int> > > arr_par;

arr_par.resize(nx);
for (i=0; i<nx; i++) {
arr_par[i].resize(ny);
for (j = 0; j<ny; j++) {
arr_par[i][j].resize(nz);
}
}

tstart = clock();
#pragma omp parallel default(shared) private(threadid)
{
#ifdef _OPENMP
nthreads = omp_get_num_threads();
threadid = omp_get_thread_num();
#endif
#pragma omp master
std::cout<<"OpenMP execution with "<<nthreads<<" threads"<<std::endl;
#pragma omp end master
#pragma omp barrier
#pragma omp critical
{
std::cout<<"Thread id: "<<threadid<<std::endl;
}

#pragma omp for
for (i=0; i<nx; i++) {
for (j=0; j<ny; j++) {
for (k=0; k<nz; k++) {
arr_par[i][j][k] = i*j + k;
}
}
}
}
tend = clock();
std::cout<<"Elapsed time: "<<(tend - tstart)/double(CLOCKS_PER_SEC)<<" s"<<std::endl;

return 0;
}

如果nxnynz等于10,则代码运行流畅。如果我将这些数字增加到 20,就会出现段错误。无论元素数量有多少,它都可以按顺序或 OMP_NUM_THREADS=1 正常运行。

我编译了这该死的东西

g++ -std=c++0x -fopenmp -gstabs+ -O0 test.cpp -o test

使用 GCC 4.6.3。

如有任何想法,我们将不胜感激!

最佳答案

您的循环计数器中存在数据竞争:

#pragma omp for
for (i=0; i<nx; i++) {
for (j=0; j<ny; j++) { // <--- data race
for (k=0; k<nz; k++) { // <--- data race
arr_par[i][j][k] = i*j + k;
}
}
}

因为 jk 都没有被赋予 private 数据共享类,所以当多个线程尝试访问它们时,它们的值可能会超过相应的限制立即增加它们,导致对 arr_par 的越界访问。多个线程同时增加jk的机会随着迭代次数的增加而增加。

处理这些情况的最佳方法是简单地在循环运算符本身内声明循环变量:

#pragma omp for
for (int i=0; i<nx; i++) {
for (int j=0; j<ny; j++) {
for (int k=0; k<nz; k++) {
arr_par[i][j][k] = i*j + k;
}
}
}

另一种方法是在并行区域的头部添加private(j,k)子句:

#pragma omp parallel default(shared) private(threadid) private(j,k)

由于并行循环的循环变量被隐式设为私有(private),因此在您的情况下,将 i 设为私有(private)并不是绝对必要的。尽管如此,如果 i 在代码的其他地方使用,将其设为私有(private)以防止其他数据竞争可能是有意义的。

此外,不要使用 clock() 来测量并行应用程序的时间,因为在大多数 Unix 操作系统上,它会返回所有线程的总 CPU 时间。请改用 omp_get_wtime()

关于c++ - OpenMP/C++ : number of elements in for-loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23153716/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com