OpenMP是一个库,是针对共享内存并行编程的API。
OpenMP被明确地设计成可以用来对已有的穿行程序进行增量式并行化,这对于MPI是不可能的,对于Pthreads也是相当困难的。
这里的OpenMP学习这几部分:1)对源代码进行少量改动就可以并行化许多串行的for循环。2)任务并行化。3)显式线程同步。4)缓存对共享内存编程的影响(这是共享内存编程中的标准问题)。5)当串行代码(特别是一个串行库)被一个共享内存程序使用时遇到的问题。
1.入门:多线程执行
我们想多线程执行Hello()函数,需要这样写:
#pragma omp parallel num_threads(thread_count)
Hello();
...
return 0;
当代码块执行完,即线程从Hello调用中返回时,有一个隐式路障,这意味着完成代码块的线程将等待线程组中的所有其他线程完成代码块。当左右线程都完成了代码块,从线程将终止,主线程将继续执行之后的代码,此例子中,执行 ... return 0.
而在Hello函数内部,需要得到当前执行自己的线程号,所以内部是这样的:
void Hello(void){
int my_rank = omp_get_thread_num();
int thread_count = omp_get_num_threads();
...
}
2.竞争条件(race condition)和临界区(critical section)
race condition:多线程试图访问一个共享资源,并且至少一个访问是更新该共享资源。
critical section: 引起竞争条件的代码。即global_result += my_result 是一个被多个更新共享资源的线程执行的代码,并且共享资源一次只能被一个线程更新。
OpenMP中使用critical指令保证互斥:
#pragma omp parallel