Fortran Coder

查看: 7373|回复: 1
打印 上一主题 下一主题

[并行] open acc处理矩阵的并行问题

[复制链接]

2

帖子

1

主题

0

精华

入门

F 币
40 元
贡献
19 点
跳转到指定楼层
楼主
发表于 2019-2-25 20:43:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我在尝试做一个四维矩阵运算,维度为num。矩阵用一维数组存储, 主要代码如下tmp=0.0

do d = 1, num
do c = 1, num
do b = 1, c-1
do a = 1, b-1   
     idx1 = (d-1)*num**3+(c-1)*num**2+(b-1)*num+a
     idx2 = (d-1)*num**3+(a-1)*num**2+(c-1)*num+b
     idx3 = (d-1)*num**3+(b-1)*num**2+(a-1)*num+c
     tmp=tmp+matrix(idx1)+matrix(idx2)+matrix(idx3)

enddo
enddo
enddo
enddo
-----
这里的循环里b依赖于c,a依赖于b。我尝试利用omp并行,可以得到和串行一样的结果,并行代码如下
!$omp parallel do reduction(+:tmpe)
do……
enddo……
!$omp end parallel do

但是如果用openacc在gpu下并行则不行(已经将matrix,copy到GPU上新开的matrix_device中),代码如下
!$acc parallel loop reduction(+:tmpe)
do……
enddo……
!$acc end parallel loop


然后进一步发现如果b和a的循环次数都是“1,num”, 没有依次和c,b相关联,则能够计算出正确的tmpe。
由于矩阵具有对称性,如果将b和a都按照num来进行循环,则会比源代码中计算量多六倍。
求大神指导在open acc的情况下,这一段代码应该如何写才能够得到足够快的运行速度。
====================
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

63

帖子

9

主题

0

精华

专家

超凡脱俗

F 币
474 元
贡献
237 点
沙发
发表于 2019-3-15 12:03:56 | 只看该作者
本帖最后由 Jackdaw 于 2019-3-15 16:04 编辑

写法有问题吧,可以参考下面两种

[Fortran] 纯文本查看 复制代码
!$acc parallel copyin(mat) private(idx1, idx2, idx3)
    !$acc loop 
    do d = 1, num
        do c = 1, num 
            do b =1, c -1 
                do a = 1, b -1 
                    idx1 = (d-1)*num**3 + (c-1)*num**2 + (b-1)*num + a 
                    idx2 = (d-1)*num**3 + (a-1)*num**2 + (c-1)*num + b 
                    idx3 = (d-1)*num**3 + (b-1)*num**2 + (a-1)*num + c
                    tmp  = tmp + mat( idx1 ) + mat( idx2 ) + mat( idx3 ) 
                end do 
            end do 
        end do 
    end do    
    !$acc end loop
    !$acc end parallel   



[Fortran] 纯文本查看 复制代码
!$acc kernels copyin(mat) private(idx1, idx2, idx3) 
    do d = 1, num
        do c = 1, num 
            do b =1, c -1 
                do a = 1, b -1 
                    idx1 = (d-1)*num**3 + (c-1)*num**2 + (b-1)*num + a 
                    idx2 = (d-1)*num**3 + (a-1)*num**2 + (c-1)*num + b 
                    idx3 = (d-1)*num**3 + (b-1)*num**2 + (a-1)*num + c
                    tmp  = tmp + mat( idx1 ) + mat( idx2 ) + mat( idx3 ) 
                end do 
            end do 
        end do 
    end do  
    !$acc end kernels   

天下英雄出我辈,一入江湖岁月催。

鸿图霸业谈笑间,不胜人生一场醉。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-26 08:47

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表