[Eigen中文文档] Eigen 和多线程

文档总目录

英文原文(Eigen and multi-threading)

使 Eigen 并行运行

某些 Eigen 算法可以利用硬件中存在的多个内核。为此,在编译器上启用 OpenMP 就足够了,例如:

  • GCC:-fopenmp
  • ICC:-openmp
  • MSVC:检查构建属性中的相应选项。

可以使用 OpenMP API 或 Eigen 的 API 使用以下优先级来控制将使用的线程数:

OMP_NUM_THREADS=n ./my_program
omp_set_num_threads(n);
Eigen::setNbThreads(n);

除非调用了 setNbThreads,否则 Eigen 将使用 OpenMP 指定的线程数。可以通过调用 setNbThreads(0); 来恢复此行为。可以查询将使用的线程数:

n = Eigen::nbThreads( );

可以通过定义 EIGEN_DONT_PARALLELIZE 预处理器标记在编译时禁用 Eigen 的多线程。

目前,以下算法可以利用多线程:

警告:

在大多数操作系统上,将线程数量限制为物理核心数量非常重要,否则预计会显着降低速度,特别是对于涉及密集矩阵的操作。

确实,超线程的原理是在单个内核上以交错的方式运行多个线程(在大多数情况下为2)。然而,Eigen的矩阵乘积内核已经完全优化,并且已经利用了将近100%的CPU容量。因此,在单个核上运行多个此类线程的空间非常有限,性能会因为缓存污染和其他开销而显著下降。在阅读到这个阶段,可能会想知道为什么Eigen不仅限于物理核心的数量?这只是因为OpenMP不允许知道物理核心的数量,因此Eigen将启动与OpenMP报告的核心数一样多的线程。

在多线程应用程序中使用 Eigen

如果应用程序是多线程的,并且多个线程调用 Eigen,那么必须在创建线程之前通过调用以下例程来初始化 Eigen:

#include <Eigen/Core>
 
int main(int argc, char** argv)
{
  Eigen::initParallel();
  
  ...
}

注意:

使用 Eigen 3.3 和完全兼容 C++11 的编译器(即线程安全的静态局部变量初始化),调用 initParallel() 是可选的。

警告:

需要注意的是,所有生成随机矩阵的函数都不是可重入的,也不是线程安全的。这些函数包括DenseBase::Random()DenseBase::setRandom(),尽管它们调用了Eigen::initParallel()。这是因为这些函数是基于std::rand的,而std::rand不是可重入的。为了获得线程安全的随机生成器,我们建议使用c++11随机生成器或boost::random

如果应用程序与 OpenMP 并行化,可能需要禁用 Eigen 自己的并行化,如上一节所述。

警告:

OpenMP 与可能引发异常的自定义标量类型一起使用可能会在引发异常时导致意外行为。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万俟淋曦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值