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

共享与私有变量声明的方法

声明方法                                    功能

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 //导致结果错误。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值