一起来学OpenMP(5)——有效的数据规约

一起来学OpenMP(5)——有效的数据规约

  (2012-03-04 12:41:03)
一、引言

本节介绍reduction的用法。

 

二、reduction示例

[cpp]   view plain copy print ?
  1. #include <iostream>  
  2. #include <omp.h> // OpenMP编程需要包含的头文件  
  3.   
  4. int main()  
  5.  
  6.     int sum 0;   
  7.   
  8.     std::cout << "Before: " << sum << std::endl;  
  9.   
  10. #pragma omp parallel for reduction(+: sum)   
  11.     for (int 0; 10; ++i)   
  12.      
  13.         sum sum i;  
  14.         std::cout << sum << std::endl;  
  15.      
  16.   
  17.     std::cout << "After: " << sum << std::endl;  
  18.     return 0;  
  19.  

输出如下:

其中sum是共享的,采用reduction之后,每个线程根据reduction(+: sum)的声明算出自己的sum,然后再将每个线程的sum加起来。

可以看到,第一个线程sum的值依次为0, 1, 3, 6, 10;第二个线程sum的值一次为5, 11, 18, 26, 35;最后10+35=45。

 

如果将其中的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 //导致结果错误。

 

reduction声明可以看作:

1. 保证了对sum的原则操作

2. 多个线程的执行结果通过reduction中声明的操作符进行计算,以加法操作符为例:

假设sum的初始值为10,reduction(+: sum)声明的并行区域中每个线程的sum初始值为0(规定),并行处理结束之后,会将sum的初始化值10以及每个线程所计算的sum值相加。

 

三、reduction的声明形式

我们在上边已经了解了reduction的声明形式,其具体如下:

reduction (operator: var1, val2, ...)

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

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

                  整数、浮点               0

                   整数、浮点               0

                  整数、浮点               1

                  整数                        所有位均为1

                   整数                        0
                  整数                        0

&&                 整数                        1

||                   整数                        0

 

小结

对reduction的用法进行了介绍,下面介绍线程同步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值