请参阅下面的进一步更新
运行Fortran代码时,我发现系统CPU占用率一直很高。“用户CPU使用率”大约占用一个核心(系统是具有4核心/ 8线程的Intel i7,运行Linux),而系统CPU占用大约2核心(因此,总体CPU使用率约为75%)。谁能告诉我这是哪里来的,并且这是“正常”行为吗?
我使用gfortran编译代码(优化已关闭-O0,尽管那部分似乎无关紧要),并针对BLAS,LAPACK和某些(其他)C函数进行了链接。我自己的代码未使用任何并行化,链接的代码也未使用(据我所知)。至少我没有使用任何并行库版本。
该代码本身是关于组装和求解有限元系统的,并且使用了很多(?)分配和内部函数调用(matmul,dot_product),尽管总体RAM使用量非常低(〜200MB)。我不知道这些信息是否足够/有用,但是我希望有人知道那里发生了什么。
最好的问候,本
更新我想我确实找到了从LAPACK调用DSYEV的问题(部分)(在我的情况下,计算实符号矩阵A的特征值)。
program test
implicit none
integer,parameter :: ndim=3
real(8) :: tens(ndim,ndim)
integer :: mm,nn
real(8), dimension(ndim,ndim):: eigvec
real(8), dimension(ndim) :: eigval
character, parameter :: jobz='v' ! Flags calculation of eigenvectors
character, parameter :: uplo='u' ! Flags upper triangular
integer, parameter :: lwork=102 ! Length of work array
real(8), dimension(lwork) :: work ! Work array
integer :: info
tens(1,:) = [1.d0, 2.d0, 3.d0]
tens(2,:) = [2.d0, 5.d0, 1.d0]
tens(3,:) = [3.d0, 1.d0, 1.d0]
do mm=1,5000000
eigvec=tens
! Call DSYEV
call dsyev(jobz,uplo,ndim,eigvec,ndim,eigval,work,lwork,info)
enddo
write(*,*) eigvec
write(*,*) int(work(1))
endprogram test
编译和链接完成
gfortran test.f90 -o test -llapack
该程序给我%sys CPU使用率很高。谁能验证这一点(显然必须使用LAPACK来取消编码)?这是“正常”行为还是我的代码/系统/库...出了问题?
更新2受@roygvib的评论鼓励,我在另一个系统上运行了代码。在第二个系统上,无法再现高CPU sys使用情况。比较这两个系统,我似乎找不到这是从哪里来的。两者都运行相同的OS版本(Linux Ubuntu),相同的gfortran版本(4.8),内核版本,LAPACK和BLAS。“主要”区别:处理器是越野车系统上的i7-4770,另一个是处理器上的i7-870。在越野车上运行测试代码给了我%user 16s和%sys 28s的信息。在i7-870上,它是%user 16s %sys 0s。运行代码的四倍(并行)给我约的每个进程的总体定时的其他系统上18S和手推车系统上44S。还有什么我还能找的想法吗?
更新3我认为我们越来越接近:使用指向LAPACK和BLAS库的静态链接,在另一个系统上构建测试程序,
gfortran test.f90 -O0 /usr/lib/liblapack.a /usr/lib/libblas.a -Wl,--allow-multiple-definition
并在越野车系统中运行该代码可使我的%sys时间约为0(根据需要)。另一方面,在越野车系统上使用指向LAPACK和BLAS的静态链接构建测试程序,并在其他系统上运行代码也会返回%sys CPU高使用率!显然,这些库似乎有所不同,对吧?在错误的系统上构建静态版本会导致文件大小约为18MB(!),而在另一个系统上则为100KB。我必须包括其他
-Wl,--allow-multiple-definition
仅在另一个系统上执行命令(否则会抱怨xerbla的多个定义),而在越野车系统上,我必须(明确地)链接到libpthread
gfortran test.f90 -O0 /usr/lib/liblapack.a /usr/lib/libblas.a -lpthread -o test
有趣的是
apt-cache policy liblapack*
对于两个系统返回相同的版本和回购目的地(libblas *也是如此)。还有其他想法吗?也许还有其他一些我不知道的命令来检查库版本?
我对减速的解释是:
使用了LAPACK和BLAS wes的线程化版本(可能是OpenMP)。这些尝试启动多个线程以并行解决线性代数问题。这通常会加快计算速度。
但是在这种情况下
do mm=1,5000000
eigvec=tens
call dsyev(jobz,uplo,ndim,eigvec,ndim,eigval,work,lwork,info)
enddo
多次调用库来解决一个非常小的问题(3x3矩阵)。这不能并行有效地解决,矩阵太小。与线程同步相关的开销支配了解决时间。同步(即使不是创建线程)也完成了5000000次!
补救措施:
使用非线程的BLAS和LAPACK
如果并行化是使用OpenMP set完成的OMP_NUM_THREADS=1
,则意味着仅使用一个线程
根本不使用LAPACK,因为对于特殊情况3x3,有专门的算法可用https://en.wikipedia.org/wiki/Eigenvalue_algorithm#3.C3.973_matrices
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句