Fortran LAPACK:高 CPU %sys 使用 DSYEV - 没有并行化 - 正常吗?
Fortran LAPACK: high CPU %sys usage with DSYEV - no parallelization - normal?
查看下面的进一步更新
我在 运行我的 Fort运行 代码时观察到安静的高系统 CPU 使用情况。 "user CPU usage" 占用了大约一个内核(系统是 Intel i7,具有 4 个内核/8 个线程,运行ning Linux),而系统 CPU 占用了大约 2 个内核(因此总体 CPU 使用率约为 75%)。谁能向我解释这是从哪里来的,这是否是 "normal" 行为?
我用 gfort运行 编译代码(优化关闭了 -O0,尽管那部分似乎并不重要)和 link 针对 BLAS、LAPACK 和一些(其他)C-职能。我自己的代码没有使用任何并行化,linked 代码也没有(据我所知)。至少我没有使用任何并行化的库版本。
代码本身是关于组装和求解有限元系统并使用大量(?)分配和内部函数调用(matmul,dot_product),尽管整体 RAM 使用率非常低(~200MB) ).我不知道这些信息是否足够/有用,但我希望有人知道那里发生了什么。
此致,
本
更新
我想我确实找到了(部分)从 LAPACK 调用 DSYEV 的问题(计算真实对称矩阵 A 的特征值,在我的例子中是 3x3)。
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
编译和 linking 是用
完成的
gfortran test.f90 -o test -llapack
这个程序给了我很高的 %sys CPU 使用率。任何人都可以验证这一点(显然 LAPACK 是解开代码所必需的)?这是 "normal" 行为还是我的 code/system/librariers 有问题...?
更新 2
在@roygvib 的评论的鼓励下,我 运行 另一个系统上的代码。在第二个系统上,高 CPU sys 使用无法重现。比较这两个系统,我似乎无法找到这是从哪里来的。 运行 相同的 OS 版本(Linux Ubuntu),相同的 gfort运行 版本(4.8),内核版本,LAPACK 和 BLAS。 "Major" 区别:处理器在有问题的系统上是 i7-4770,在另一个系统上是 i7-870。 运行 越野车上的测试代码给我大约 %user 16s 和 %sys 28s。在 i7-870 上是 %user 16s %sys 0s。 运行 代码四次(并行)给我的每个进程的总体时间在另一个系统上约为 18s,在有问题的系统上为 44s。
还有什么我可以寻找的想法吗?
更新 3
我认为我们越来越接近:
在另一个系统上使用静态 link 到 LAPACK 和 BLAS 库构建测试程序,
gfortran test.f90 -O0 /usr/lib/liblapack.a /usr/lib/libblas.a -Wl,--allow-multiple-definition
和 运行 在有问题的系统中使用该代码使我的 %sys 时间大约为 0(根据需要)。另一方面,在有问题的系统上使用静态 links 为 LAPACK 和 BLAS 构建测试程序,并 运行 在另一个系统上 return high %sys CPU 用法也是如此!很明显,图书馆似乎有所不同,对吧?
在有问题的系统上构建静态版本导致文件大小约为 18MB(!),在其他系统上为 100KB。另外我必须包括
-Wl,--allow-multiple-definition
仅在其他系统上发出命令(否则会抱怨 xerbla 的多个定义),而在有问题的系统上我必须(明确地)link 反对 libpthread
gfortran test.f90 -O0 /usr/lib/liblapack.a /usr/lib/libblas.a -lpthread -o test
有趣的是
apt-cache policy liblapack*
return两个系统的版本和回购目标相同(libblas* 也是如此)。还有什么想法吗?也许还有其他一些我不知道的检查库版本的命令?
我对经济放缓的解读:
我们使用了 LAPACK 和 BLAS 的线程(可能是 OpenMP)版本。这些尝试启动多个线程来并行解决线性代数问题。这通常会加快计算速度。
但是在这种情况下
do mm=1,5000000
eigvec=tens
call dsyev(jobz,uplo,ndim,eigvec,ndim,eigval,work,lwork,info)
enddo
这是为一个非常小的问题(一个 3x3 矩阵)多次调用库。这不能有效地并行解决,矩阵太小了。与线程同步相关的开销决定了求解时间。同步(如果甚至没有创建线程)完成 5000000 次!
补救措施:
使用非线程 BLAS 和 LAPACK
如果使用 OpenMP 集 OMP_NUM_THREADS=1
完成并行化,这意味着 仅使用一个线程
根本不要使用 LAPACK,因为对于特殊情况 3x3 有专门的算法可用 https://en.wikipedia.org/wiki/Eigenvalue_algorithm#3.C3.973_matrices
查看下面的进一步更新
我在 运行我的 Fort运行 代码时观察到安静的高系统 CPU 使用情况。 "user CPU usage" 占用了大约一个内核(系统是 Intel i7,具有 4 个内核/8 个线程,运行ning Linux),而系统 CPU 占用了大约 2 个内核(因此总体 CPU 使用率约为 75%)。谁能向我解释这是从哪里来的,这是否是 "normal" 行为?
我用 gfort运行 编译代码(优化关闭了 -O0,尽管那部分似乎并不重要)和 link 针对 BLAS、LAPACK 和一些(其他)C-职能。我自己的代码没有使用任何并行化,linked 代码也没有(据我所知)。至少我没有使用任何并行化的库版本。
代码本身是关于组装和求解有限元系统并使用大量(?)分配和内部函数调用(matmul,dot_product),尽管整体 RAM 使用率非常低(~200MB) ).我不知道这些信息是否足够/有用,但我希望有人知道那里发生了什么。
此致, 本
更新 我想我确实找到了(部分)从 LAPACK 调用 DSYEV 的问题(计算真实对称矩阵 A 的特征值,在我的例子中是 3x3)。
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
编译和 linking 是用
完成的gfortran test.f90 -o test -llapack
这个程序给了我很高的 %sys CPU 使用率。任何人都可以验证这一点(显然 LAPACK 是解开代码所必需的)?这是 "normal" 行为还是我的 code/system/librariers 有问题...?
更新 2 在@roygvib 的评论的鼓励下,我 运行 另一个系统上的代码。在第二个系统上,高 CPU sys 使用无法重现。比较这两个系统,我似乎无法找到这是从哪里来的。 运行 相同的 OS 版本(Linux Ubuntu),相同的 gfort运行 版本(4.8),内核版本,LAPACK 和 BLAS。 "Major" 区别:处理器在有问题的系统上是 i7-4770,在另一个系统上是 i7-870。 运行 越野车上的测试代码给我大约 %user 16s 和 %sys 28s。在 i7-870 上是 %user 16s %sys 0s。 运行 代码四次(并行)给我的每个进程的总体时间在另一个系统上约为 18s,在有问题的系统上为 44s。 还有什么我可以寻找的想法吗?
更新 3 我认为我们越来越接近: 在另一个系统上使用静态 link 到 LAPACK 和 BLAS 库构建测试程序,
gfortran test.f90 -O0 /usr/lib/liblapack.a /usr/lib/libblas.a -Wl,--allow-multiple-definition
和 运行 在有问题的系统中使用该代码使我的 %sys 时间大约为 0(根据需要)。另一方面,在有问题的系统上使用静态 links 为 LAPACK 和 BLAS 构建测试程序,并 运行 在另一个系统上 return high %sys CPU 用法也是如此!很明显,图书馆似乎有所不同,对吧? 在有问题的系统上构建静态版本导致文件大小约为 18MB(!),在其他系统上为 100KB。另外我必须包括
-Wl,--allow-multiple-definition
仅在其他系统上发出命令(否则会抱怨 xerbla 的多个定义),而在有问题的系统上我必须(明确地)link 反对 libpthread
gfortran test.f90 -O0 /usr/lib/liblapack.a /usr/lib/libblas.a -lpthread -o test
有趣的是
apt-cache policy liblapack*
return两个系统的版本和回购目标相同(libblas* 也是如此)。还有什么想法吗?也许还有其他一些我不知道的检查库版本的命令?
我对经济放缓的解读:
我们使用了 LAPACK 和 BLAS 的线程(可能是 OpenMP)版本。这些尝试启动多个线程来并行解决线性代数问题。这通常会加快计算速度。
但是在这种情况下
do mm=1,5000000
eigvec=tens
call dsyev(jobz,uplo,ndim,eigvec,ndim,eigval,work,lwork,info)
enddo
这是为一个非常小的问题(一个 3x3 矩阵)多次调用库。这不能有效地并行解决,矩阵太小了。与线程同步相关的开销决定了求解时间。同步(如果甚至没有创建线程)完成 5000000 次!
补救措施:
使用非线程 BLAS 和 LAPACK
如果使用 OpenMP 集
OMP_NUM_THREADS=1
完成并行化,这意味着 仅使用一个线程根本不要使用 LAPACK,因为对于特殊情况 3x3 有专门的算法可用 https://en.wikipedia.org/wiki/Eigenvalue_algorithm#3.C3.973_matrices