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);
    }
}
posted @ 2024-01-24 07:29  Mesonoxian  阅读(26)  评论(0编辑  收藏  举报