带 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;
}
}
我一直在阅读 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;
}
}