Matlab 减少DGELSD子例程的计算时间
我正在用Fortran编写一个涉及线性最小二乘(a^(-1)*b)计算的代码。为此,我使用了子程序“DGELSD”。我能够从我的代码中得到正确答案。我已经将我的解决方案与MATLAB提供的数据进行了交叉检查 现在说到计算时间,MATLAB比我的.f90代码花费的时间要少得多。我编写.f90代码的主要动机是进行繁重的计算,因为MATLAB无法处理这个问题(随着矩阵大小的增加,它需要越来越多的时间)。我说的是矩阵(10^6 x 10^6)的顺序 我知道我可能缺少代码的矢量化或并行化(因为我是新手)。但这会有什么不同吗?因为子程序“DGELSD”已经高度优化。此外,我还使用“英特尔ifort编译器”和visual studio作为编辑器 我已附上以下主要代码(.f90)的一部分以供参考。请建议可以做些什么来减少计算时间。我有良好的硬件配置来运行繁重的计算 工作站规格:英特尔至强32核64位处理器,64 GB RAM 代码信息: a) 我使用了“英特尔MKL示例网站”上提供的“DGELSD”示例 b) 我使用的是x64体系结构 c) 这是我在MATLAB中用于比较的代码Matlab 减少DGELSD子例程的计算时间,matlab,fortran,intel-mkl,Matlab,Fortran,Intel Mkl,我正在用Fortran编写一个涉及线性最小二乘(a^(-1)*b)计算的代码。为此,我使用了子程序“DGELSD”。我能够从我的代码中得到正确答案。我已经将我的解决方案与MATLAB提供的数据进行了交叉检查 现在说到计算时间,MATLAB比我的.f90代码花费的时间要少得多。我编写.f90代码的主要动机是进行繁重的计算,因为MATLAB无法处理这个问题(随着矩阵大小的增加,它需要越来越多的时间)。我说的是矩阵(10^6 x 10^6)的顺序 我知道我可能缺少代码的矢量化或并行化(因为我是新手)。
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与英特尔Visual fortran结合使用,因此可以使用编辑器中提供的编译选项编译程序。我的意思是说我不必使用命令行界面来运行我的程序
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)
此外,我还提供了“英特尔mkl”库,如下图所示:
我已经编译了程序,输出已经写入文件“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上运行了两天多。它仍然没有产生任何结果。您是如何编译它的?您确定要链接到英特尔的MKL库而不是系统上的其他lapack吗?是的,我只包含了英特尔数学内核库,可以通过console的属性模块直接添加到visual stdio中,向我们展示您的编译和链接命令,请以纯文本形式重新输入编译日志。我把它清理了一下,但是有些字符现在错了。但更重要的是向我们展示你们的时间测量,这样我们就可以知道需要多长时间。Matlab和Fortran两个版本。Matlab可能与并行BLAS/Lapack相关联。如果在yur编译器标志中要求使用顺序MKL,则代码将花费更多时间,尤其是在32核机器上。