考虑下面的Fortran代码
program example
implicit none
integer, parameter :: ik = selected_int_kind(15)
integer, parameter :: rk = selected_real_kind(15,307)
integer(ik) :: N, i, j, pc, time_rate, start_time, end_time, M
real(rk), allocatable:: K(:,:), desc(:,:)
real(rk) :: kij, dij
integer :: omp_get_num_threads, nth
N = 2000
M = 400
allocate(K(N,N))
allocate(desc(N,M))
pc=10
do i = 1, N
desc(i,:) = real(i,rk)
if (i==int(N*pc)/100) then
print * ,"desc % complete: ",pc
pc=pc+10
endif
enddo
call system_clock(start_time)
!$OMP PARALLEL PRIVATE(nth)
nth = omp_get_num_threads()
print *,"omp threads", nth
!$OMP END PARALLEL
!$OMP PARALLEL DO &
!$OMP DEFAULT(SHARED) &
!$OMP PRIVATE(i,j,dij,kij)
do i = 1, N
do j = i, N
dij = sum(abs(desc(i,:) - desc(j,:)))
kij = dexp(-dij)
K(i,j) = kij
K(j,i) = kij
enddo
K(i,i) = K(i,i) + 0.1
enddo
!$OMP END PARALLEL DO
call system_clock(end_time, time_rate)
print* , "Time taken for Matrix:", real(end_time - start_time, rk)/real(time_rate, rk)
end program example我在MacOS X10.11上使用gfortran-6编译了它,使用下面的标志
gfortran example.f90 -fopenmp -O0gfortran example.f90 -fopenmp -O3gfortran example.f90 -fopenmp -mtune=native之后,我使用OMP_NUM_THREADS变量使用单线程和双线程运行它。我看得出来,它使用的是两个核。但是,应该启用向量化的O3标志对性能毫无帮助,如果有任何影响的话,它会稍微降低一些性能。时间表如下(以秒为单位)(超过10次的avgd):
|Thrds->| 1 | 2 |
|Opt | | |
----------------------
|O0 |10.962|9.183|
|O3 |11.581|9.250|
|mtune |11.211|9.084|我的节目怎么了?
发布于 2020-05-24 20:41:32
首先,如果您想要从-O3获得良好的性能,您应该给它一些实际可以优化的东西。大部分工作发生在sum内部,它工作在向量化表达式上。当您从-O0切换到-O3时,它不会得到更多的优化。
另外,如果您想要更好的性能,请转置desc,因为desc(i,:)在内存中是不连续的。desc(:,i)是。这是Fortran -它的矩阵是列-主要的。
https://stackoverflow.com/questions/61991851
复制相似问题