在我的fortran代码中,矩阵乘法是用openblas库中的"dgemm"处理的。矩阵的大小相当大,7000 X 7000,所以我想降低矩阵操作的计算成本。
我尝试使用多线程调用"dgemm",但它似乎不起作用(仅作为单线程工作(。"time"命令用于记录计算所需的时间。不管我是否使用-lpthreads标志,我的计算时间都是一样的。在我看来,多线程似乎不起作用。
下面是我的test.f和compile命令。你能推荐我在矩阵操作中使用多线程的方法吗?很抱歉问题重复,太简单和基础的东西,但现有的问答;As对我不起作用。谢谢你的评论!
- 在bashrc中:
导出OPENBLAS_LIB=/mypath/LIB
export OPENBLAS_INC=/mypath/include
导出OMP_NUM_THREADS=4
export GOTO_NUM_THREADS=4
导出OPENBLAS_NUM_THREADS=4
源的- 命令:
gfortran测试。f-o测试。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
无论您试图在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秒。这是一台简单的笔记本电脑,其他东西正在运行。重要的是,它也从385%CPU变为99%CPU。
我使用OpenSUSE中包含的默认二进制OpenBLAS。
您需要启用并行化的优化才能生效,即编译为这样的
gfortran -O test.f -o test.x -lopenblas -lpthread
注意-O
开关。