我正在使用"英特尔MKL"库求解具有多个右手边(rhs)矢量的线性方程组(A*x = b)
。rhs矢量是通过一个单独的例程异步生成的,因此不可能一次解决所有问题。
为了加快程序的速度,使用了一个多线程程序,其中每个线程负责求解单个rhs向量。由于矩阵A
总是恒定的,因此应当执行一次LU因子分解,并且随后在所有线程中使用这些因子。因此,我使用以下命令因子A
dss_factor_real(handle, opt, data);
并使用以下命令将句柄传递给线程以解决问题:
dss_solve_real(handle, opt, rhs, nRhs, sol);
然而,我发现在dss_solve_real
的几个实例中使用相同的handle
是不安全的。显然,由于某种原因,MKL库在每个实例中更改句柄,从而创建竞争条件。我阅读了MKL手册,但找不到任何相关内容。由于为每个线程分解A
是不合乎逻辑的,我想知道是否有任何方法可以克服这个问题,并在任何地方使用相同的handle
。
提前感谢您的帮助
就我对DSS接口的理解而言,handle
不仅包含LU因子分解,还包含dss_solve_real
中使用和修改的其他数据结构;这是经过设计的,因此应该使用锁定机制来避免多个线程在同一个handle
上同时调用dss_solve_real
。
此外,您认为dss_solve_real
是串行的(否则我不明白为什么要同时调用它的多个实例)可能是错误的。DSS是PARDISO求解器的接口,它在所有阶段都应该是并行的,而不仅仅是因子分解。
编辑
放弃DSS接口并直接调用pardiso,应该可以有多个线程串行地解决单个rhs。(不容易,但仔细编程应该是可能的…)
然而,从最大吞吐量(每单位时间解决的rhs)而不是最小延迟(启动单个rhs的解决方案之前的时间)的角度来看,我认为最好的方法是使用单个工作线程,通过对并行求解器的单个调用来解决队列中等待的所有rhs。当然,应该组织队列,以便将rhs矢量存储在连续存储器区域中。