高性能的C++多维数组

18

我正在寻找关于C++高性能多维数组库/类的建议。我需要:

  • 能够在运行时动态分配大小的数组

  • 能快速访问和修改单个数组值

  • 能够使用简单的数组算术,例如array1 = array2 + 2 * array3

  • 一个经过良好维护的库

我已经了解了各种库,包括:

  • Blitz++,看起来正是我需要的,但似乎没有得到很好的维护(最新稳定版本发布于5年前)。

  • Boost不支持数组算术,并且相对于Blitz++而言速度较慢。

  • Jon Bowman的array.h没有文档。

是否有任何其他建议或对上述选项的评论?


感谢回复。只是想澄清一下,我对线性代数不感兴趣,只对数组容器和简单算术运算感兴趣。 - astrofrog
9个回答

7

Eigen非常维护良好(目前,至少每个月都会推出新版本),并支持您所需的其他操作。


2
Eigen似乎不支持多维数组。 - Ran
4
现在的Eigen(主分支)已经拥有了一个功能齐全的张量库(多维数组)。 - iNFINITEi

4

这里有一份较为全面且相对较新的调查报告,包括基准测试结果,请点击此处查看

我认为你可以通过将Boost.UBlas与类似LAPACK或Intel MKL这样的底层数值库绑定来加速它的运行,但我还没有尝试过。

据我了解,经常作为备选的实现方案是Boost.UBlas和MTL。我认为广泛采用这些方案更容易促进持续支持和发展。


3
  • uBlas是Boost的一部分。它提供完整的BLAS级别1-3,因此具有很多数组算术函数。
  • Armadillo也似乎是一个C++线性代数库,据我所见,它可以选择使用LAPACK / Atlas(这当然使它具有规范的速度)。
  • GNU Scientific Library提供完整的BLAS。我不知道它有多快,或者它是否可以使用LAPACK / Atlas。
  • 如果您所需的不比您列出的更花哨,那么您可以很容易地自己包装例如Atlas的BLAS。但是如果您没有必要重新发明轮子,您可能不想这样做。

3

Necomi似乎提供了您需要的功能。

它支持运行时固定维度的任意多维数字,并提供对单个元素的快速访问,同时支持算术(和其他)表达式。


2
也许您想尝试我的“Multi”库:https://gitlab.com/correaa/boost-multi
  • 具有在运行时确定大小的动态分配数组的能力
    multi::array<int, 2> A({m, n});
  • 能够访问和修改单个数组值(快速)
    A[i][j] += 42;

生成类似于A.base() + i*stride_1 + j*stride_2的机器码。想要使用简单的数组算术运算,例如array1 = array2 + 2 * array3。我决定将数组算术运算与数据结构分开。虽然如此,该库非常兼容STL算法(如果您的步幅允许,它还具有使用BLAS的适配器)。过度简化一些关于存取模式的问题...。更多信息请参见https://gitlab.com/correaa/boost-multi#whats-up-with-the-multiple-bracket-notation
template<class T, class X, class Y>
auto axpy(T alpha, X const& x, Y&& y) -> Y&& {
    assert( extensions(x) == extensions(y) );
    std::transform(
        x.elements().begin(), x.elements().end(),
        y.elements().begin(), 
        y.elements().begin(),
        [&](auto const& ex, auto& ey) {return alpha*x + ey;}
    );
    return std::forward<Y>(y);
}
...

auto array1 = axpy(2, array2, +array3);  // array1 = 2*array2 + array3;  // unary + will make a modifiable copy before it starts.
  • 一个维护良好的代码库

只要我能,我会一直维护它,并欢迎贡献者。


2

还有一点自我推广的成分,

https://github.com/dwwork/FortCpp/

我在GitHub上发布了自己的解决方案。 尽管我不是C++专家,但我认为至少可以分享一下我的经验。


1
从性能角度来看,我尝试过boost::MultiArray和Armadillo。两者都不够快,因为它们的访问时间比数组或向量慢,而且我能够通过使用简单的手写循环(在编译器优化的帮助下)在操作x1(4:10) = x2(1:6) + x2(2:7) + x2(3:8)中击败这些包。当你涉及矩阵乘法时,这些包可能通过LAPACK和BLAS提供一些好处,但你也可以自己使用这些接口。

1

1

在这里先声明一下,以下内容是毫不掩饰的自我推销:

https://github.com/ndarray/ndarray

值得研究。

虽然它不提供优化的数学运算符,但它确实为此提供了与Eigen的接口。它真正突出的地方在于通过SWIG或Boost.Python提供与Python/NumPy的互操作性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接