带 noalias 的特征矩阵-向量乘法

Eigen Matrix-Vector multiplication w/ noalias

我一直在阅读 Eigen 文档以使用 noalias 来避免在做 Matrix-Matrix 产品时进行不必要的临时分配,但我想知道是否可以在以下情况下使用 noalias:

Eigen::VectorXf x(3);
x << 1, 2, 3;

Eigen::MatrixXf A(3, 3);
A << 1, 2, 3, 4, 5, 6, 7, 8, 9;

// Is this valid? Is it valid under certain size assumptions for A and x but not others?
x.noalias() = A * x;

天真地,noalias 在这种情况下似乎是有效的,因为您实际上只需要访问 Matrix 中每列一次的 Vector 元素。

另一方面,x明显出现在表达式的两边,矩阵乘法涉及各种低级黑魔法,使得这种情况难以推理。

testing with Clang trunk and Eigen trunk 之后,启用优化后,noalias 的情况会产生不正确的结果。 GCC 主干具有相同的行为。

输出:

Program returned: 0
.noalias
0
0
0
alias
14
32
50

代码:

#include <iostream>
#include <Eigen/Dense>

auto no_alias() -> Eigen::VectorXf
{
    Eigen::VectorXf x(3);
    x << 1, 2, 3;

    Eigen::MatrixXf A(3, 3);
    A << 1, 2, 3, 4, 5, 6, 7, 8, 9;

    x.noalias() = A * x;
    return x;
}

auto alias() -> Eigen::VectorXf
{
    Eigen::VectorXf x(3);
    x << 1, 2, 3;

    Eigen::MatrixXf A(3, 3);
    A << 1, 2, 3, 4, 5, 6, 7, 8, 9;

    x = A * x;
    return x;
}

int main () 
{
    std::cout << ".noalias" << std::endl;
    for (const auto& no : no_alias())
    {
        std::cout << no << std::endl;
    }

    std::cout << "alias" << std::endl;
    for (const auto& no : alias())
    {
        std::cout << no << std::endl;
    }
}