您的位置:首页 > 运维架构

Openmp补遗之数据共享&归约子句的学习

2012-03-11 00:44 211 查看
共享与私有变量声明的方法

声明方法 功能

shared(val1,val2,...) 共享变量在存储器中只有一份拷贝,所有的线程都能对它进行读写访问。正确性将由程序员来决定。 得到声明,初始赋值且写回

private(val1, val2, ...) 并行区域中变量val是私有的,即每个线程拥有该变量的一个拷贝 只得到声明,无初始赋值

无论该变量在并行区域外是否初始化,在进入并行区域后,该变量均不会初始化。

在VS2008下,会因为private所导致的私有变量未初始化而出现错误。

first_private(val1, val2, ...) 与private不同的是,每个线程在开始的时候都会对该变量进行一次初始化。 得到声明和初始赋值

各线程对val进行各自的操作,最后不会对公共区的val造成影响。

last_private(val1, val2, ...) 与private不同的是,并发执行的最后一次循环的私有变量将会拷贝到val 得到声明,无初始赋值,最后将数据赋回

reduction(operator : val1,val2 ) 每个线程根据reduction(+: sum)的声明算出自己的sum,然后再将每个线程的sum加起来。 得到声明,最后将数据归约(含初始值)

其中operator以及约定变量的初始值如下:

运算符 数据类型 默认初始值

+ 整数、浮点 0

- 整数、浮点 0

* 整数、浮点 1

& 整数 所有位均为1

| 整数 0

^ 整数 0

&& 整数 1

|| 整数 0

一种数据冲突的例子,需要reduction来避免!

如果将其中的reduction声明去掉,则会输出:

计算步骤如下:

第一个线程sum=0;第二个线程sum=5

第一个线程sum=1+5=6; 第二个线程sum=6+6=12

第一个线程sum=2+12=14;第二个线程sum=7+14=21

第一个线程sum=3+21=24;第二个线程sum=8+24=32

第一个线程sum=4+32=36;第二个线程sum=9+36=45

尽管结果是对的,但两个线程对共享的sum的操作是不确定的,会引发数据竞争,例如计算步骤可能如下:

第一个线程sum=0;第二个线程sum=5

第一个线程sum=1+5=6; 第二个线程sum=6+6=12

第一个线程sum=2+12=14;第二个线程sum=7+14=21

第一个线程sum=3+21=24;第二个线程sum=8+21=29 //在第一个线程没有将sum更改为24时,第二个线程读取了sum的值

第一个线程sum=4+29=33;第二个线程sum=9+33=42 //导致结果错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: