【问题标题】:gsl::gsl_vector vs std::vector overheads and efficiencygsl::gsl_vector vs std::vector 开销和效率
【发布时间】:2013-07-23 08:37:06
【问题描述】:

我正在考虑实现一个类似容器的数组,但我不确定是使用 gsl::gsl_vector 还是 std::vector。容器需要节省空间,但调用值也要非常快。容器将在主程序中不断被引用,例如,将值输入到张量函数中,等等。我从容器中调用了数十亿次。

以下是我目前考虑过的利弊: gsl_vector 很方便,因为它允许我偶尔使用 gsl BLAS 库,并且gsl_vector_get(...) 调用非常有效。另一方面,我可以使用 stl 迭代器获得几乎相同的调用速度,并且 stl 向量有一个我觉得很自然的接口。

上面的代码中是否存在我应该注意的内存开销/效率问题?

另外,我目前正在使用std::vector<gsl_vector*> 实现,以及一个遍历std::vector 的迭代器。在这里使用 gsl_matrix 会更聪明吗?这个想法是使用 gsl_vector_views 来获得正确的向量,而不是迭代器。这样会更有效率吗?

【问题讨论】:

    标签: c++ vector stl comparison gsl


    【解决方案1】:

    一方面,使用 gsl_vector 确实可以使用 gsl BLAS,这是一个很大的优势。另一方面,gsl 接口对于 c++ 程序员来说也是相当麻烦的。因此,这两种解决方案都不是真正令人满意的。但是,我更喜欢使用 gsl_matrix,因为

    (i) 通过一些努力,您可以编写一个小的包装类来改进 gsl_matrix 的繁琐 C 接口(处理 std::vector 中缺少 BLAS 库要困难得多)。

    (ii) gsl_matrix 只是一维连续数组的包装器,其中m(i,j) = array[i*N + j] 用于方阵(即使矩阵不是方阵 gsl_matrix 仍将其实现为一维数组)。在std::vector<gsl_vector*> 中,您需要单独“malloc”每个 gsl_vector,这意味着内存不会是连续的。这会影响性能,因为内存分配中缺乏“空间局部性”通常会大大增加缓存未命中率。

    如果您可以选择使用完全不同的解决方案,我会使用 Blaze lib 中的 StaticMatrix 或 DynamicMatrix 类来实现张量计算

    Blaze

    为什么是 Blaze?

    (i) StaticMatrix 或 DynamicMatrix 接口比std::vector<gsl_vector*> 或 gsl_matrix 好很多

    (ii) Blaze 是 C++ 中最快的 BLAS 库。如果您有可用的英特尔 MKL,它比 gsl 快(请记住,英特尔 MKL 比 gsl BLAS 快)。为什么这样?因为 Blaze 使用了一种称为“智能表达式模板”的新技术。基本上,德国的研究人员在一系列文章paper 1paper 2 中表明,许多 C++ BLAS 库中的标准技术“表达式模板”技术对于矩阵运算(BLAS 3 运算)来说是很糟糕的,因为编译器可以' t 比低级代码更聪明。但是,“表达式模板”可以用作英特尔 MKL 等低级 BLAS 库的更智能包装器。因此,他们创建了“智能表达式模板”技术,它只是您选择的低级 blas lib 的包装器。他们的基准是惊人的

    benchmark

    【讨论】:

    • 有趣的是,项目 X 显示的基准测试结果如何,碰巧 X 出来的速度最快。 Eigen 人也非常坚持他们的代码很好,并且自从基准测试中使用的版本以来,Armadillo 已经改变/改进。您的里程可能会有所不同。
    • 它比犰狳快得多(您可以查看基准链接),因为正如我所说的 blaze 使用“智能表达式模板”。含义:Blaze 仅将模板用作低级 c 代码 blas 库(如 intel mkl)的包装器。犰狳尝试在编译时使用循环展开(“表达式模板”的原始形式)来计算矩阵运算,我链接的论文表明这远非最佳解决方案(仅使用编译器无法击败英特尔 mkl!) .我认为 Eigen 使用了混合实现,但 Blaze 也比 Eigen 快。
    • 是的。基准可能会有所不同。但是“表达式模板”无法击败英特尔 MKL(或任何其他 c 低级代码)的想法是非常可靠的。使用模板作为优化低级代码的包装器比依靠编译器完成 100% 的工作要好得多。我认为所有 C++ BLAS 都在这方面趋同,这就是“智能表达式模板”背后的理念。
    • MKL 恰好是多核的,但它不再是唯一的多核 BLAS 库。 Armadillo 也会调用 BLAS,因此可以使用 MKL 或 OpenBLAS 或您安装的任何其他工具。 Eigen 通常会尝试自己的事情,而不是调用 BLAS。但是感谢 Blaze 的指针,我会留意的。
    猜你喜欢
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    • 2021-05-26
    • 1970-01-01
    • 2017-09-21
    相关资源
    最近更新 更多