推进有些慢。学习openmp的小结。
1.对于单纯的parallel语句
竞争条件 多个线程试图控制访问一个共享资源,并且至少其中一个访问是更新该共享资源,可能导致错误
引起竞争条件的代码称为临界区。临界区是一个被多个更新共享资源的线程执行的代码,并且共享资源一次只能被一个线程更新。
用critical指令对临界区的代码进行控制。
#pragmaomp critical
这条指令告诉编译器需要安排线程对下列的代码块进行互斥访问。
2.规约子句
定义一个归约变量来表示归约的结果。
3.对于openmp中的parallel for
主要是消除其for循环中的数据依赖,
消除循环依赖,主要通过修改代码语句形式
除了消除循环依赖,还需要保证每个线程有其自己的某变量副本,保证其变量有私有作用域。一个线程对此变量的更新不会影响另一个线程此变量的值。
4.关于作用域
需通过了解程序,显示的明确每个变量的作用域
语句为#pragmaomp parallel for num_threads()\
Default(none)reduction() private() shared()
5.用parallel指令在外部循环前创建thread_count个线程的集合。然后,使用一个for指令,告诉openmp使用已有的线程组来并行化for循环
#pragmaomp parallel
for()
for()
#pragma omp for
for()
#pragma omp for
6.循环调度
Parallelfor指令,循环分配给线程的操作是由系统完成的,大部分即粗略的使用块分割。
将循环分配给线程称为调度,schedule子句用于在parallel for 或者 for指令中进行迭代分配。
scheduletype:
static迭代在循环执行前分配给线程
dynamicguided 迭代在循环执行时分配给线程
auto编译器和运行时系统决定调度方式
runtime调度在运行时决定
如果不使用schedule子句就已经达到了令人满意的性能,就不需要再进行多余的工作。但是,如果怀疑默认调度的性能可以提升,那么可以对各种调度进行试验。
通过改变线程个数和迭代次数 进行试验 最优的调度方式是由线程个数和迭代次数共同决定
关于调度选择的一个小结:
如果循环的每次迭代需要几乎相同的计算量,那么可能默认的调度方式能提供最好的性能
如果随着循环的进行,迭代的计算量呈线性递增,那么采用较小的chunksize的static调度可能会提供最好的性能
如果每次迭代的开销事先不能确定,那么可能需要尝试多种不同的调度策略