OpenMP学习 第八章 OpenMP内存模型
第八章 OpenMP内存模型
内存模型
并发 是OpenMP的基础.如果两个或多个线程对内存中的相同地址执行混合读写操作,且这些读写操作没有被同步操作排序,则程序存在 数据竞争.
变量 是内存中一个地址的名称,这个内存可能是虚拟内存或物理内存.这意味着一个变量可能是随机存取存储器(RAM)中的一个位置.
在大多数系统中,RAM是通过动态随机存取存储器(DRAM)来实现的.
任何我们可能使用的OpenMP系统都使用了一个 宽松的内存一致性模型.
在编程语言中使用的一组规则称为 内存模型 ,该规则定义了读取共享变量时可以加载的值.
OpenMP通用核心内存模型
OpenMP最初的内存模型是用一个叫 冲刷(flush)的操作来定义的.
冲刷强制线程变量的临时视图与内存(RAM)中的变量值保持一致.即更新对所有线程而言的某个变量的值.
冲刷适用于线程间共享的所有变量.这个变量集称为 冲刷集(flush set).
程序文本中的语句定义了一些列对内存的加载和存储操作,我们称之为 程序顺序.
编译器对这些操作进行重排序以优化性能,这就是 编译器顺序.
线代微处理器可以在运行时进一步重排序这些操作,这就是 执行顺序.
冲刷 是每个线程的操作.线程发起冲刷操作,对于发起冲刷操作的该线程,冲刷集的变量值与共享内存保持一致.但是该线程不会显示另一个线程上的冲刷集的值.
冲刷是同步的一个重要方面,但是其本身不是同步操作,其只影响单个线程的内存操作.
在OpenMP通用核心中,以下几点都隐含了冲刷:
- 当一个新的线程组被parallel构造fork时.
- 当一个critical构造被线程加入时.
- 当一个线程完成一个critical构造并退出临界区时.
- 进入task区域时.
- 从task区域退出时.
- 在退出taskwait时.
- 在退出显式barrier构造时.
- 在退出隐式栅栏构造时.(无nowait)
生产者-消费者程序
生产者-消费者程序:
首先,确保运行时系统至少给我们两个线程,如果没有,那么退出程序.
如果有两个及以上的线程,那么进入程序.
一个生产者线程将调用一个函数在数组A中产生一个结果,
而另一个线程(消费者)将等待直到生产者完成.
这时,它将调用一个函数来使用这个结果.
bool flag=false;
#pragma omp parallel shared(A,B,flag)
{
int id = omp_get_thread_num();
int nthrds = omp_get_num_threads();
if((id==0)&&(nthrds<2))
exit(-1);
if(id==0){//生产者
produce(A);
flag=true;
}
if(id==1){//消费者
while(!flag)
//自旋锁(spin mutex)结构
consume(A);
}
}