为什么 Eigen 不支持 OpenMP 进行系数运算?



这篇文章以及一些测试表明,尽管矩阵矩阵产品可以利用多个核心,但Eigen并没有将多处理应用于按系数运算,如cwiseProductArray乘法。

尽管如此,经过一些优化,Eigen似乎相当快,即使我试图为特定目的编写自己的矩阵库,我也怀疑它是否会比Eigen更快,即使我的库启用了OpenMP

  1. 当涉及到系数运算时,为什么Eigen不支持OpenMP?这是开发人员的某种失误,还是有一些特定的原因避免对特定操作进行多处理
  2. 我可以手动包含对此类操作的OpenMP支持吗?Eigen的代码似乎很复杂,因此即使使用Visual Studio工具,也很难找到特定函数的确切实现

在系数运算方面,为什么Eigen不支持OpenMP?这是开发人员的某种失误,还是有一些特定的原因避免对特定操作进行多处理?

默认情况下使用多个线程不是一个好主意,因为用户已经可以在其应用程序中使用多个螺纹,并且嵌套并行循环显然效率不高。此外,共享每个操作的工作可能会带来很大的开销,这对于中小型阵列的基本操作来说并不是很大。Eigen对于小型和大型阵列都是快速的。在实践中,在Eigen之上使用OpenMP是更好的。由于第一次接触策略,Numa系统尤其如此:由于远程访问或页面迁移,隐藏多线程可能会带来惊人的开销。

对于像LU分解这样的复杂操作,要求用户并行操作是不合理的,因为它需要重写大部分算法。这就是Eigen试图将这些算法并行化的原因。

我可以手动包含对此类操作的OpenMP支持吗?Eigen的代码似乎很复杂,因此即使使用Visual Studio工具,也很难找到特定函数的确切实现。

元素操作在OpenMP中并行实现是微不足道的。您可以简单地在循环上使用#pragma omp parallel for指令(可能与collapse子句组合(,使用基本的特征数组索引运算符迭代0到array.rows()(或array.cols()(本身。


请注意,虽然使用多个线程进行基本操作乍一看很有趣,但在实践中,在大多数机器上,它的速度往往令人失望。事实上,只要操作已经使用SIMD指令矢量化,那么与对每个项应用算术运算(例如,add/sub/mul(相比,在RAM中读取/写入数据是非常昂贵的。例如,在我的机器上,1个核心的吞吐量可以达到20-25 GiB/s,而6个核心的最大吞吐量是40 GiB/s(即,6个线程的加速率小于2倍(。

最新更新