我在FORTRAN中实现了Conjugate Gradient,取代了wikipedia example by(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秒。
几点:
M16_LAY_GAS16
ASM会对multpd
进行深入分析。没有什么有用的(否则,我不知道在哪里看)FWIW,我使用了VTune。KMP_AFFINITY
将一个线程以串行方式映射到一个处理器,将两个线程并行映射到两个处理器。我的问题是:为什么MKL_DYNAMIC不将线程数设置为1,如果这是最佳的?如果相同的工作(在较短的时间内)由1完成,我不一定需要使用2个线程。
我做错了什么或英特尔MKL出了什么问题?
答案 0 :(得分:3)
MKL_DYNAMIC
在功能上与OpenMP标准中的OMP_DYNAMIC
/ omp_set_dynamic()
相同。
这并不意味着“神奇地改变尽可能快地运行代码的线程数”。这意味着在某些情况下,如果存在系统资源或其他特定于实现的原因,运行时可以从用户指定的值或系统缺省值更改线程数。鉴于你没有指定多个线程,并且有4个并发硬件线程可用,我猜你的MKL_SET_DYNAMIC = TRUE
案例正在使用四个线程。
如果您运行MKL_SET_DYNAMIC=TRUE MKL_SET_NUM_THREADS=16
之类的内容,可能会发现运行时将线程数限制为4并且性能优于MKL_SET_DYNAMIC=FALSE MKL_SET_NUM_THREADS=16
,因为运行时可能会检测您要求的可用并发硬件线程数以上。但这就是我所期望的。