openblas可以在fortran中用多线程做矩阵乘法吗?
Can openblas do matrix multiplication with multi-threads in fortran?
在我的 Fortran 代码中,矩阵乘法是使用 openblas 库中的 'dgemm' 处理的。
矩阵的尺寸很大,7000 X 7000,所以我想减少矩阵操作的计算成本。
我尝试使用多线程调用 'dgemm',但它似乎不起作用(仅作为单线程工作)。 'time'命令用于记录需要计算的时间。不管我是否使用 -lpthreads 标志,我的计算时间都是一样的。在我看来,多线程不起作用。
下面是我的test.f和编译命令。你能推荐我在矩阵操作中使用多线程的方法吗?对于重复的问题和过于简单和基础的问题感到抱歉,但现有的问答不适合我。感谢您的任何评论!
- 在 bashrc 中:
出口OPENBLAS_LIB=/mypath/lib
出口[=52=]=/mypath/include
出口OMP_NUM_THREADS=4
出口GOTO_NUM_THREADS=4
出口OPENBLAS_NUM_THREADS=4
- 来源命令:
gfortran test.f -o test.x -lopenblas -lpthread
样本来源
program test
implicit none
integer :: i, j, k
integer :: m, n, num_threads
double precision :: alpha, s
double precision, allocatable :: aa(:,:), bb(:,:), cc(:,:)
call openblas_set_num_threads(4)
m=7000
allocate(aa(m,m))
allocate(bb(m,m))
allocate(cc(m,m))
aa=1.d0
bb=2.d0
cc=0.d0
write(*,*) 'initialization over'
! calculate matrix multiplication using library
alpha=1.d0
call dgemm('N', 'N', m, m, m, alpha, aa, m, bb, m, alpha, cc, m)
write(*,*) 'matrix multiplication over', cc(1,1), cc(m,m)
endprogram test
您需要启用并行化优化才能生效,即这样编译
gfortran -O test.f -o test.x -lopenblas -lpthread
注意 -O
开关。
无论您尝试在 OMP_NUM_THREADS
、OPENBLAS_NUM_THREADS
、MKL_NUM_THREADS
或任何其他环境变量中设置多少线程,都没有关系。在你的代码中你有
call openblas_set_num_threads(4)
并且它具有优先级,如果可能的话,您将始终获得这 4 个线程。
据我所知,-lpthreads
没有用。它通常会自动链接,当您没有链接器错误时,这意味着实际上不需要显式链接。
在我对您的代码进行的测试中,由于 call openblas_set_num_threads(4)
,我总是需要大约 17 秒的时间来 运行 您的代码。当我将它更改为 1 时,我有 25 秒。这是一台简单的笔记本电脑,其他东西 运行ning。重要的是它也从385%CPU变成了99%CPU.
我使用 OpenSUSE 中包含的默认二进制 OpenBLAS。
在我的 Fortran 代码中,矩阵乘法是使用 openblas 库中的 'dgemm' 处理的。 矩阵的尺寸很大,7000 X 7000,所以我想减少矩阵操作的计算成本。
我尝试使用多线程调用 'dgemm',但它似乎不起作用(仅作为单线程工作)。 'time'命令用于记录需要计算的时间。不管我是否使用 -lpthreads 标志,我的计算时间都是一样的。在我看来,多线程不起作用。
下面是我的test.f和编译命令。你能推荐我在矩阵操作中使用多线程的方法吗?对于重复的问题和过于简单和基础的问题感到抱歉,但现有的问答不适合我。感谢您的任何评论!
- 在 bashrc 中:
出口OPENBLAS_LIB=/mypath/lib
出口[=52=]=/mypath/include
出口OMP_NUM_THREADS=4
出口GOTO_NUM_THREADS=4
出口OPENBLAS_NUM_THREADS=4
- 来源命令:
gfortran test.f -o test.x -lopenblas -lpthread
样本来源
program test implicit none integer :: i, j, k integer :: m, n, num_threads double precision :: alpha, s double precision, allocatable :: aa(:,:), bb(:,:), cc(:,:) call openblas_set_num_threads(4) m=7000 allocate(aa(m,m)) allocate(bb(m,m)) allocate(cc(m,m)) aa=1.d0 bb=2.d0 cc=0.d0 write(*,*) 'initialization over' ! calculate matrix multiplication using library alpha=1.d0 call dgemm('N', 'N', m, m, m, alpha, aa, m, bb, m, alpha, cc, m) write(*,*) 'matrix multiplication over', cc(1,1), cc(m,m) endprogram test
您需要启用并行化优化才能生效,即这样编译
gfortran -O test.f -o test.x -lopenblas -lpthread
注意 -O
开关。
无论您尝试在 OMP_NUM_THREADS
、OPENBLAS_NUM_THREADS
、MKL_NUM_THREADS
或任何其他环境变量中设置多少线程,都没有关系。在你的代码中你有
call openblas_set_num_threads(4)
并且它具有优先级,如果可能的话,您将始终获得这 4 个线程。
据我所知,-lpthreads
没有用。它通常会自动链接,当您没有链接器错误时,这意味着实际上不需要显式链接。
在我对您的代码进行的测试中,由于 call openblas_set_num_threads(4)
,我总是需要大约 17 秒的时间来 运行 您的代码。当我将它更改为 1 时,我有 25 秒。这是一台简单的笔记本电脑,其他东西 运行ning。重要的是它也从385%CPU变成了99%CPU.
我使用 OpenSUSE 中包含的默认二进制 OpenBLAS。