下面给出两个方阵相乘的示例代码. Z(m,L) = X(m,n) * Y(n,L). 其中X,Y,Z也可以是长阵
program main
use omp_lib !// 使用omp_lib并行
use ifport, only : fdate !// 使用fdate进行计算时间统计
implicit none
integer, parameter :: m =5000 , n = 5000, L = 5000
real :: x(m,n) = 0.0 , y(n,L) = 0.0 , z(m,L) = 0.0 !// z = x * y
integer :: i, j, k
call random_seed()
call random_number(x)
call random_number(y)
print*, fdate()
z = matmul(x,y)
print*, fdate()
open( 100, file = 'z1.dat' ) !// 输出matmul计算的z的第一列
do i = 1, size(z,1)
write( 100,'(*(g0,3x))' ) i, z(i,1)
end do
close( 100 )
!$omp parallel private(i, j, k) shared(x, y, z)
!$omp do schedule(static)
do i = 1, L
do j = 1, m
z(j,i) = 0.
do k = 1, n
z(j,i) = z(j,i) + x(j,k)*y(k,i)
end do
end do
end do
!$omp end do
!$omp end parallel
print*, fdate()
open( 100, file = 'z2.dat' ) !// 输出openmp并行计算的z的第一列
do i = 1, size(z,1)
write( 100,'(*(g0,3x))' ) i, z(i,1)
end do
close( 100 )
end program main
此代码运行环境:win10, vs2013+ivf2013, x64 release,
Optimization: Maximize Speed plus Higher Level Optimizations (/O3)
三次fdate的输出分别为:
Sun Jun 02 13:17:45 2019
Sun Jun 02 13:17:58 2019
Sun Jun 02 13:18:04 2019
可以看出内置函数matmul计算时间约为13s
自己重新写的算法计算时间约为6s, 节省时间约为7s
而且经过测试发现:matmul的运行时间与没有加并行的下面代码
do i = 1, L
do j = 1, m
z(j,i) = 0.
do k = 1, n
z(j,i) = z(j,i) + x(j,k)*y(k,i)
end do
end do
end do
运行时间在s的量级上是相同的。猜测fortran中的matmul函数并没有进行优化
经过验证,两种算法计算的结果相同。
如果有网友发现上述代码有任何错误或者是有什么好的建议或是意见,欢迎互相讨论