[Eigen中文文档] 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 与可能引发异常的自定义标量类型一起使用可能会在引发异常时导致意外行为。

相关文章
|
8月前
|
存储 编译器
[Eigen中文文档] 深入了解 Eigen - 类层次结构
本页面介绍了Eigen类层次结构中 Core 类的设计及其相互关系。一般用户可能不需要关注这些细节,但对于高级用户和Eigen开发人员可能会有用。
131 0
|
8月前
|
存储 C语言 C++
|
8月前
|
存储 编译器
|
8月前
|
存储 缓存
[Eigen中文文档] 深入了解 Eigen - 惰性求值与混叠(Aliasing)
Eigen具有智能的编译时机制,可以实现惰性求值并在适当的情况下删除临时变量。它会自动处理大多数情况下的混叠问题,例如矩阵乘积。自动行为可以通过使用MatrixBase::eval()和MatrixBase::noalias()方法手动覆盖。
90 0
|
8月前
|
存储 安全 编译器
[Eigen中文文档] 常见的陷阱
本文将介绍一些Eigen常见的陷阱
97 0
|
8月前
|
存储 算法 NoSQL
[Eigen中文文档] 稀疏矩阵操作
在许多应用中(例如,有限元方法),通常要处理非常大的矩阵,其中只有少数系数不为零。在这种情况下,可以通过使用仅存储非零系数的特殊表示来减少内存消耗并提高性能。这样的矩阵称为稀疏矩阵。
222 0
|
8月前
|
存储
[Eigen中文文档] 就地矩阵分解
从 Eigen 3.3 开始,LU、Cholesky 和 QR 分解可以就地操作,即直接在给定的输入矩阵内操作。当处理大矩阵时,或者当可用内存非常有限(嵌入式系统)时,此功能特别有用。
48 0
|
8月前
|
存储 编译器 调度
|
8月前
|
安全
[Eigen中文文档] 混叠
在 Eigen 中,混叠是指相同的矩阵(或数组或向量)出现在赋值操作符的左边和右边。如下表达式,mat = 2*mat 或者 mat = mat.transpose()。第一个表达式是没有问题的,但是第二个表达式,会出现不可预料的结果。这一节会解释什么是混叠,以及它的危害与处理方法。
55 0
|
8月前
|
测试技术 API C++
[Eigen中文文档] 扩展/自定义Eigen(一)
在本节中,将介绍如何向MatrixBase添加自定义方法。由于所有表达式和矩阵类型都继承自MatrixBase,因此将方法添加到MatrixBase会立即使其对所有表达式可用!一个典型的用例是,使Eigen与另一个API兼容。
111 0