Fortran 串行版本比并行版本慢,MKL_DYNAMIC=TRUE

Fortran 串行版本比并行版本慢,MKL_DYNAMIC=TRUE,fortran,linear-algebra,lapack,blas,Fortran,Linear Algebra,Lapack,Blas,我在FORTRAN中通过用(FORTRAN)英特尔MKL子例程替换线性代数子例程实现了共轭梯度。(仅限DGEMV、DAXPY和DNRM。结果表明,a=b比DCOPY快,a=2*a比DSCAL快) 答案是正确的,实施没有问题。但是,当我将其编译为ifort CG.f90-mkl时,结果如下: MKL_SET_DYNAMIC=TRUE;140秒 MKL_SET_DYNAMIC=FALSE,MKL_SET_NUM_THREADS=1;70秒 MKL_SET_DYNAMIC=FALSE,MKL_SET_

我在FORTRAN中通过用(FORTRAN)英特尔MKL子例程替换线性代数子例程实现了共轭梯度。(仅限DGEMV、DAXPY和DNRM。结果表明,a=b比DCOPY快,a=2*a比DSCAL快)

答案是正确的,实施没有问题。但是,当我将其编译为
ifort CG.f90-mkl
时,结果如下:

MKL_SET_DYNAMIC=TRUE;140秒

MKL_SET_DYNAMIC=FALSE,MKL_SET_NUM_THREADS=1;70秒

MKL_SET_DYNAMIC=FALSE,MKL_SET_NUM_THREADS=2~100秒

有几点:

  • 通过超线程,我有2个真实内核和2个虚拟内核。我不想在2核机器上运行16个线程
  • 分析已经产生了对
    M16\u LAY\u GAS16
    的深奥引用,经过大量搜索,它最终成为
    multpd
    ASM。没有任何有用的结果,否则(或者,我不知道去哪里看)FWIW,我使用了VTune
  • 问题的规模不小。上面的示例是与我的RAM大小成比例的矩阵大小(对于我的4 GB系统,大约为13k x 13k)
  • KMP_AFFINITY
    以串行方式将一个线程映射到一个处理器,以并行方式将两个线程映射到两个处理器
  • 我的问题是:为什么MKL_不将线程数动态设置为1(如果这是最优的)?如果相同的工作(在更短的时间内)由1完成,我不一定需要使用2个线程。


    “英特尔MKL”是否有问题?

    MKL\u DYNAMIC
    在功能上与OpenMP标准中的
    OMP\u DYNAMIC
    /
    OMP\u set\u DYNAMIC()
    相同

    这并不意味着“神奇地改变线程数量以尽可能快地运行代码”。这意味着,在某些情况下,如果存在系统资源或其他特定于实现的原因,运行时可以从用户指定的值或系统默认值更改线程数。如果您没有指定多个线程,并且有4个并发硬件线程可用,我猜您的
    MKL\u SET\u DYNAMIC=TRUE
    案例使用了4个线程


    如果运行类似于
    MKL\u SET\u DYNAMIC=TRUE MKL\u SET\u NUM\u THREADS=16
    的程序,您可能会发现运行时会将线程计数限制为4,并且性能会优于
    MKL\u SET\u DYNAMIC=FALSE MKL\u SET\u NUM\u THREADS=16
    ,因为运行时可能会检测到您请求的线程数超过了可用的并发硬件线程数。但这就是我所期望的

    MKL\u DYNAMIC
    在功能上与OpenMP标准中的
    OMP\u DYNAMIC
    /
    OMP\u set\u DYNAMIC()
    相同

    这并不意味着“神奇地改变线程数量以尽可能快地运行代码”。这意味着,在某些情况下,如果存在系统资源或其他特定于实现的原因,运行时可以从用户指定的值或系统默认值更改线程数。如果您没有指定多个线程,并且有4个并发硬件线程可用,我猜您的
    MKL\u SET\u DYNAMIC=TRUE
    案例使用了4个线程


    如果运行类似于
    MKL\u SET\u DYNAMIC=TRUE MKL\u SET\u NUM\u THREADS=16
    的程序,您可能会发现运行时会将线程计数限制为4,并且性能会优于
    MKL\u SET\u DYNAMIC=FALSE MKL\u SET\u NUM\u THREADS=16
    ,因为运行时可能会检测到您请求的线程数超过了可用的并发硬件线程数。但这就是我所期望的

    我很好奇为什么你没有提到
    DGEMV
    或者
    DSYMV
    …我很好奇为什么你没有提到
    DGEMV
    或者
    DSYMV
    …使用
    MKL_NUM_THREADS=16
    MKL_DYNAMIC=TRUE
    运行时会将其限制为2(结果表明2对于这个问题是最优的)而使用FALSE时,则有4个线程。难道没有一种机制可以“神奇地将线程数更改为最佳值”@Nunoxic:不幸的是,编译器OpenMP运行时都不是通灵的,它们不知道要使用什么设置来优化代码运行。这很有趣。我将探讨MKL_如何动态分配多少。谢谢!运行
    MKL_NUM_THREADS=16
    MKL_DYNAMIC=TRUE
    时,会将其限制为2(结果表明2是解决问题的最佳选择),而使用FALSE则会限制为4个线程。难道没有一种机制可以“神奇地将线程数更改为最佳值”@Nunoxic:不幸的是,编译器OpenMP运行时都不是通灵的,它们不知道要使用什么设置来优化代码运行。这很有趣。我将探讨MKL_如何动态分配多少。谢谢!