OpenMP编程的数据竞争问题
来源:互联网 发布:拨打电话变声软件 编辑:程序博客网 时间:2024/06/06 05:37
OpenMP编程的数据竞争问题
使用OpenMP编程时,通常都是将函数内的某段代码并行化执行,但是,对于在函数内声明的变量,很容易被多个线程同时读写访问,这将导致数据竞争问题。
不妨先看一个代码例子:
找出下面代码中的问题
template <class T>
void Parallel_Matrix_Sub(T *a, int row_a, int col_a, int as, T *b, int bs, T *c, int cs)
{
int i, j;
int nCore = omp_get_num_procs();
#pragma omp parallel for num_threads(nCore)
for ( i = 0; i < row_a; i++ )
{
int row_i_a = i * as;
int row_i_b = i * bs;
int row_i_c = i * cs;
for ( j = 0; j < col_a; j++ )
{
//c[i][j] = a[i][j] - b[i][j]
c[row_i_c + j] = a[row_i_a + j] - b[row_i_b + j];
}
}
}
稍有经验的人就可以发现,上面代码中,j变量声明在OpenMP语句块的外面,因此,对各个线程来说,它是共享变量,OpenMP创建的多个线程都会访问j。内层循环中的j++可能会被多个线程同时执行,将导致程序运行出现无法预测的错误。改正后的代码如下:
template <class T>
void Parallel_Matrix_Sub(T *a, int row_a, int col_a, int as, T *b, int bs, T *c, int cs)
{
int i;
const int nCore = omp_get_num_procs();
#pragma omp parallel for num_threads(nCore)
for ( i = 0; i < row_a; i++ )
{
int j;
int row_i_a = i * as;
int row_i_b = i * bs;
int row_i_c = i * cs;
for ( j = 0; j < col_a; j++ )
{
//c[i][j] = a[i][j] - b[i][j]
c[row_i_c + j] = a[row_i_a + j] - b[row_i_b + j];
}
}
}
注意上面的代码中的加粗两行,变量j改为在内层循环内声明,这样创建线程时,变量j为每个线程的局部变量,不存在数据竞争问题。
对于const int nCore = omp_get_num_procs(); 这行,将变量nCore声明为
const类型后,后面的代码就无法对其进行写操作,可以避免线程内的代码对线程外的变量进行写操作,避免数据竞争问题。
根据上面的实例修改情况,可以归纳出两条避免OpenMP出现数据竞争的建议:
1. 尽量在并行循环内部申明局部变量
2. 对于并行循环外面的变量,尽量使用const类型,以保证在并行循环内不会发生写操作。对于没有使用const的变量,表明需要进行写操作,可以在检视代码时重点检视这些未使用const的变量是否用了锁或原子操作来进行保护。
- OpenMP编程的数据竞争问题
- OpenMP编程的数据竞争问题
- OpenMP编程->数据传递
- OpenMP编程->数据约束
- 多线程数据竞争问题
- C++多线程编程学习一 [关于数据竞争问题]
- C++多线程编程一 [关于数据竞争问题]
- OpenMP: OpenMP编程指南
- OpenMP: OpenMP编程指南
- OpenMP: OpenMP数据环境
- openmp并行的计时问题
- 一个线程竞争的问题
- 竞争编程与实际编程的不同
- OpenMp编程
- c++并发编程中由static类型变量引起的条件竞争问题
- 多线程编程的锁问题解析(锁竞争死锁活锁及Date Race等)
- Openmp并行编程的入门资料
- OpenMP多核编程的配置与测试
- C++ string祥解
- dom4j
- php学习笔记(6):PHP循环语句的介绍与应用
- java版简意俄罗斯方块
- pku 1273 Drainage Ditches 最大流入门基础题
- OpenMP编程的数据竞争问题
- Java编程中的IO系统
- 自定义类,导出dll,stl容器vector
- Hibernate
- c++ 代码的执行顺序
- java 中区分字符串中的字符与数字
- java中判断字符串是否为数字的三种方法
- java字符串查找替换
- 近期 安排