我在Fortran中编写一个涉及线性最小二乘(A ^( - 1)* b)计算的代码。为此,我使用了子程序" DGELSD"。我能够从我的代码中得到正确的答案。我已经用MATLAB提供的数据交叉检查了我的解决方案。
现在谈到计算时间,MATLAB的时间比我的.f90代码少得多。我编写.f90代码的主要动机是进行繁重的计算,因为MATLAB无法处理这个问题(随着矩阵大小的增加,需要花费越来越多的时间)。我说的是矩阵的阶数(10 ^ 6 x 10 ^ 6)。
我知道我可能缺乏代码的矢量化或并行化(因为我是新手)。但它会有什么不同吗?作为子程序" DGELSD"已经高度优化。我也使用Intel ifort编译器和visual studio作为编辑器。
我附上了主要代码(.f90)的一部分以供参考。请建议可以采取哪些措施来减少计算时间。我有很好的硬件配置来运行繁重的计算。
工作站规范:Intel Xeon 32核心 - 64位处理器,64 GB RAM。
代码信息:
a)我使用过DGELSD'英特尔MKL示例站点上提供的示例..
b)我正在使用x64架构。
c)这是我在MATLAB中用于比较的代码。
function min_norm_check(m,n)
tic
a=15*m*n;
b=15*m*n;
c=6;
A=rand(a,b);
B=rand(b,c);
C=A\B;
toc
end
这是下面给出的Fotran代码:
! Program to check the time required to
! calculate linear least square solution
! using DGELSD subroutine
PROGRAM MAIN
IMPLICIT NONE
INTEGER :: M,N,LDA,LDB,NRHS,NB,NG
REAL :: T1,T2,START,FINISH
DOUBLE PRECISION, DIMENSION (:,:), ALLOCATABLE :: D_CAP,A,B,TG,DG
INTEGER :: I=0
NB=10
NG=10
M = 15*NB*NG
N = 15*NB*NG
NRHS = 6
!!
LDA = MAX(M,N)
LDB = MAX(M,NRHS)
!
ALLOCATE (A(LDA,N))
ALLOCATE (B(LDB,NRHS))
A = 0
B = 0
CALL RANDOM_NUMBER(A)
CALL RANDOM_NUMBER(B)
CALL CPU_TIME(START)
DO I=1,1
WRITE(*,*) I
CALL CALC_MIN_NORM_D(M,N,LDA,LDB,NRHS,A,B,D_CAP)
ENDDO
CALL CPU_TIME(FINISH)
WRITE(*,*)'("TIME =',FINISH-START,'SECONDS.")'
END
SUBROUTINE CALC_MIN_NORM_D(M,N,LDA,LDB,NRHS,A,B,D_CAP)
!
! SUBROUTINE DEFINITION TO CALCULATE THE
! LINEAR LEAST SQUARE SOLUTION OF ([A]^-1*B)
!
IMPLICIT NONE
INTEGER :: M,N,NRHS,LDA,LDB,LWMAX,INFO,LWORK,RANK
DOUBLE PRECISION RCOND
INTEGER, ALLOCATABLE, DIMENSION(:) :: IWORK
DOUBLE PRECISION :: A(LDA,N),B(LDB,NRHS),D_CAP(LDB,NRHS)
DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:) :: S,WORK
!
WRITE(*,*)'IN CALC MIN NORM BEGINING'
WRITE(*,*)'DGELSD EXAMPLE PROGRAM RESULTS'
LWMAX = 1E8
ALLOCATE(S(M))
ALLOCATE(IWORK(3*M*0+11*M))
ALLOCATE(WORK(LWMAX))
! NEGATIVE RCOND MEANS USING DEFAULT (MACHINE PRECISION) VALUE
RCOND = -1.0
!
! QUERY THE OPTIMAL WORKSPACE.
!
LWORK = -1
CALL DGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK,LWORK, IWORK, INFO )
LWORK = MIN( LWMAX, INT( WORK( 1 ) ) )
!WRITE(*,*) 'AFTER FIRST DGELSD'
!
! SOLVE THE EQUATIONS A*X = B.
!!!
CALL DGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK,LWORK, IWORK, INFO )
!
! CHECK FOR CONVERGENCE.
!
IF( INFO.GT.0 ) THEN
WRITE(*,*)'THE ALGORITHM COMPUTING SVD FAILED TO CONVERGE;'
WRITE(*,*)'THE LEAST SQUARES SOLUTION COULD NOT BE COMPUTED.'
STOP
END IF
!
!
WRITE(*,*)' EFFECTIVE RANK = ', RANK
!D_CAP = B
END
这是成功编译文件的构建日志。当我使用Visual studio和intel visual fortran时,我可以使用编辑器中提供的Compile选项编译我的程序。我的意思是说我不必使用命令行界面来运行我的程序。
Compiling with Intel(R) Visual Fortran Compiler 17.0.2.187 [IA-32]...
ifort /nologo /debug:full /Od /warn:interfaces /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc110.pdb" /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\\bin" /Qm32 "D:\Google Drive\Friday_May_27_2016\Mtech Thesis Job\All new work\Fortran coding\fortran hfgmc\Console6\Console6\Console6.f90"
Linking...
Link /OUT:"Debug\Console6.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"Debug\Console6.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"D:\Google Drive\Friday_May_27_2016\Mtech Thesis Job\All new work\Fortran coding\Console6\Console6\Debug\Console6.pdb" /SUBSYSTEM:CONSOLE /IMPLIB:"D:\Google Drive\Friday_May_27_2016\Mtech Thesis Job\All new work\Fortran coding\fortran hfgmc\Console6\Console6\Debug\Console6.lib" -qm32 "Debug\Console6.obj"
Embedding manifest...
mt.exe /nologo /outputresource:"D:\Google Drive\Friday_May_27_2016\Mtech Thesis Job\All new work\Fortran coding\fortran hfgmc\Console6\Console6\Debug\Console6.exe;#1" /manifest "Debug\Console6.exe.intermediate.manifest"
Console6 - 0 error(s), 0 warning(s)
我已编译程序,输出已写入文件' OUTPUT_FILE.TXT'。
IN CALC MIN NORM BEGINING
DGELSD EXAMPLE PROGRAM RESULTS
EFFECTIVE RANK = 1500
IN CALC MIN NORM ENDING
("TIME TAKEN TO SOLVE DGELSD= 4.290028 SECONDS.")
另一方面,MATLAB在输出命令窗口中给出以下结果:
min_norm_check(10,10)
经过的时间是0.224172秒。
此外,我不想超越MATLAB,简单易行。但随着问题规模的增加,MATLAB停止响应。我让我的程序在MATLAB上运行了两天多。它仍然没有产生任何结果。