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