0

我们有一个性能问题,首先将表达式转换为 Boost.uBLAS 向量,然后进行评估。如果可以跳过向量创建并且直接使用vector_expression,则会有所不同。如果允许,我在 Boost.uBLAS 文档中找不到。事实上,文档中的示例是使用容器类而不是直接使用表达式。它只提到 Boost.uBLAS 使用表达式模板,理论上应该使案例工作。norm_2 函数接受 vector_expression 作为参数,这可能是第二条线索。

一个简化的情况是这样的,其中计算矩阵行之间的范数:

#include <boost/numeric/ublas/assignment.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/vector.hpp>

int main()
{
    namespace ublas = boost::numeric::ublas;

    ublas::matrix<double> m{3, 4};

    m <<= 0, 1, 2, 3,
          3, 4, 5, 6,
          6, 7, 8, 9;

    double d = 0;

    for (size_t n = 1; n != m.size1(); ++n)
    {
        const ublas::matrix_row<ublas::matrix<double>> row1{m, 0};
        const ublas::matrix_row<ublas::matrix<double>> row2{m, n};

#if 1
        const auto e = row1 - row2; // creates an expression

        d += ublas::norm_2(e);      // uses the expression
#else
        const ublas::vector<double> v = row1 - row2;   // creates a vector (performance issue)

        d += ublas::norm_2(v);
#endif
    }

    return 0;
}

有谁知道这是否允许?

4

1 回答 1

0

我们有一个性能问题,首先将表达式转换为 Boost.uBLAS 向量,然后进行评估。如果可以跳过向量创建并且直接使用vector_expression,则会有所不同。

uBLAS 提供了表达式模板 (ET),可以避免创建临时对象。如果您在一个表达式中有多个元素操作,这将非常有用。在这种情况下,ET 对运行时性能有积极的影响——尽管我不得不说它取决于向量和矩阵的大小。看看这篇论文

如果允许,我在 Boost.uBLAS 文档中找不到。

这是允许的 - 否则复制构造函数将被保护或私有,请参阅类matrix_expression描述。

事实上,文档中的示例是使用容器类而不是直接使用表达式。

真的。我们需要提供更多的例子。但是,ublas文档显示二进制向量操作创建一个expression_type包含对操作和操作数的引用。您可以使用这样的实例。

Boost.uBLAS 使用表达式模板,理论上应该使案例工作。norm_2 函数接受 vector_expression 作为参数,这可能是第二条线索。

是的,看看编译器资源管理器中生成的汇编for循环内没有分配内存。所以你的方法是有效的。

你也可以写

// norm_2 uses a temporary expression instance again without memory allocation
d += ublas::norm_2(row1 - row2); 
于 2020-04-11T13:03:15.340 回答