OpenMP/C++:循环中的元素数
OpenMP/C++: number of elements in for-loop
我正在用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;
}
如果nx
、ny
和nz
等于10
,则代码运行平稳。如果我把这些数字增加到20
,我得到一个segfault。无论元素数量如何,它都可以按顺序运行或使用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;
}
}
}
由于j
和k
都没有被赋予private
数据共享类,当几个线程试图同时增加它们时,它们的值可能会超过相应的限制,从而导致对arr_par
的越界访问。使多个线程同时增加j
或k
的机会随着迭代次数的增加而增加。
处理这些情况的最佳方法是简单地在循环运算符内部声明循环变量:
#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)
在您的情况下,使i
私有化并不是严格必要的,因为并行循环的循环变量是隐式私有的。尽管如此,如果i
在代码的其他地方使用,那么将其设为私有以防止其他数据竞争可能是有意义的。
此外,不要使用clock()
来测量并行应用程序的时间,因为在大多数Unix操作系统上,它会返回所有线程的总CPU时间。请改用omp_get_wtime()
。
相关文章:
- 擦除while循环中迭代的元素
- C++:如何循环通过向量中的整数元素
- 对于set上的循环-获取next元素迭代器
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- 如何从使用 for 循环中的矢量大小的矢量中删除元素
- C++基于范围的 for 循环和元素副本
- 这个返回元素位置的基于循环的函数有什么问题?
- 为什么我在尝试在单向链表中打印元素时会出现这个永无止境的循环
- 循环访问还包含未使用元素的字符串数组
- C++用于循环跳过向量的元素?
- 基于相邻元素 c++ 的分段误差范围的循环
- 循环中的变量被设置为下一个数组的元素始终具有相同的内存地址?
- 使用现代C++在 Eigen3 矩阵上使用 for 循环进行元素操作的优雅方式
- 需要帮助编写一个小程序来将循环乘以 n 个元素和 k 个多重性
- C++ 数据结构队列:使用 for 循环查找队列中最大的元素
- 将函数应用于特征矩阵中的所有元素,而无需循环
- 使用 C++ 从每个循环的数组中选择 n 个元素
- 忽略元素的基于范围的 for 循环
- 优先级队列(使用 pairs<int,int> ) 根据 for 循环迭代器的顶级元素
- 用于随机访问和元素循环的最佳数据结构(C++)