将特征矩阵的向量设置为 0
Set Vector of Eigen Matrices to 0
我正在为一个特殊的应用调整霍夫变换,为此我需要在一个向量中存储很多特征矩阵,并且我需要它们在开始时都为 0。
这就是我初始化它的方式:
typedef Eigen::Matrix<int,30,150> HoughMatrix
std::vector<HoughMatrix> hough_spaces(num_spaces)
我现在的问题是,使所有这些矩阵的所有元素都等于 0 的最快方法是什么?
我尝试遍历每个 Vector 元素并执行:
hough_spaces[i].setZero()
但这相当慢。有没有更快的方法?或者直接将它们初始化为0的方法?
感谢您的帮助
有趣的是 Eigen::Matrix
似乎没有构造函数来初始化元素。来自 Eigen: The Matrix class:
Matrix3f a;
-> 没有分配,没有元素初始化
MatrixXf a(10,15);
-> 已分配但未初始化的元素
最后 (!) 一些允许为小型向量初始化元素的构造函数:
Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0);
如果您继续阅读 Eigen: Advanced initialization,您会发现
Special matrices and arrays
The Matrix and Array classes have static methods like Zero(), which
can be used to initialize all coefficients to zero. [...]
Example
std::cout << "A fixed-size array:\n";
Array33f a1 = Array33f::Zero();
std::cout << a1 << "\n\n";
PS
But that was rather slow. Is there a faster way?
如果不了解有关 "slow" 的 exaclt 含义的更多详细信息,则很难讨论细节。我只能说我希望初始化只比分配单元化元素快,然后 setZero()
.
首先,Eigen::Matrix<int,30,150>
默认对齐到 16 字节,这在 64 位系统或 C++17 上很可能会正常工作,但否则您可能会遇到 some caveats。
解决任何对齐问题的简单方法是编写
typedef Eigen::Matrix<int,30,150, Eigen::DontAlign> HoughMatrix;
现在写你想要的东西的惯用方式是写
std::vector<HoughMatrix> hough_spaces(num_spaces, HoughMatrix::Zero());
但是,这将导致 memcpy
调用循环(至少对于 gcc 和 clang:https://godbolt.org/z/ULixBm)。
或者,您可以创建一个包含未初始化 HoughMatrix
es 的向量并在其上应用 std::memset
:
std::vector<HoughMatrix> hough_spaces(num_spaces);
std::memset(hough_spaces.data(), 0, num_spaces*sizeof(HoughMatrix));
请注意,为了 运行 而 Eigen 不必循环遍历所有元素,需要 HoughMatrix
未对齐(如开头所示)或禁用对齐断言:https://godbolt.org/z/nDJqV5
如果您实际上不需要 std::vector
功能(主要是复制和调整大小的能力),您可以在使用后使用 calloc
和 free
分配一些内存.为了防漏,可以将其封装成 std::unique_ptr
:
// unique_ptr with custom deallocator (use a typedef, if you need this more often):
std::unique_ptr<HoughMatrix[], void(&)(void*)> hough_spaces(static_cast<HoughMatrix*>(std::calloc(num_spaces, sizeof(HoughMatrix))), std::free);
if(!hough_spaces) throw std::bad_alloc(); // Useful, if you actually handle bad-allocs. If you ignore failed callocs, you'll likely segfault when accessing the data.
Clang 和 gcc 会将其优化为单个 calloc
/free
对:
https://godbolt.org/z/m4rzRq
一种完全不同的方法是尝试使用 3D 张量而不是矩阵向量:
typedef Eigen::Tensor<int, 3> HoughSpace;
HoughSpace hough_spaces(num_spaces,30,150);
hough_spaces.setZero();
看看 generated assembly 这看起来是半最优的,即使 -O3 -DNDEBUG
。
总的来说,请注意,对任何与内存相关的内容进行基准测试可能会产生误导。例如,对 calloc
的调用可能 return 几乎是瞬时的,但在较低级别上指向未分配的页面,这使得第一次访问它们的实际成本更高。
我正在为一个特殊的应用调整霍夫变换,为此我需要在一个向量中存储很多特征矩阵,并且我需要它们在开始时都为 0。 这就是我初始化它的方式:
typedef Eigen::Matrix<int,30,150> HoughMatrix
std::vector<HoughMatrix> hough_spaces(num_spaces)
我现在的问题是,使所有这些矩阵的所有元素都等于 0 的最快方法是什么? 我尝试遍历每个 Vector 元素并执行:
hough_spaces[i].setZero()
但这相当慢。有没有更快的方法?或者直接将它们初始化为0的方法? 感谢您的帮助
有趣的是 Eigen::Matrix
似乎没有构造函数来初始化元素。来自 Eigen: The Matrix class:
Matrix3f a;
-> 没有分配,没有元素初始化
MatrixXf a(10,15);
-> 已分配但未初始化的元素
最后 (!) 一些允许为小型向量初始化元素的构造函数:
Vector2d a(5.0, 6.0); Vector3d b(5.0, 6.0, 7.0); Vector4d c(5.0, 6.0, 7.0, 8.0);
如果您继续阅读 Eigen: Advanced initialization,您会发现
Special matrices and arrays
The Matrix and Array classes have static methods like Zero(), which can be used to initialize all coefficients to zero. [...]
Example
std::cout << "A fixed-size array:\n"; Array33f a1 = Array33f::Zero(); std::cout << a1 << "\n\n";
PS
But that was rather slow. Is there a faster way?
如果不了解有关 "slow" 的 exaclt 含义的更多详细信息,则很难讨论细节。我只能说我希望初始化只比分配单元化元素快,然后 setZero()
.
首先,Eigen::Matrix<int,30,150>
默认对齐到 16 字节,这在 64 位系统或 C++17 上很可能会正常工作,但否则您可能会遇到 some caveats。
解决任何对齐问题的简单方法是编写
typedef Eigen::Matrix<int,30,150, Eigen::DontAlign> HoughMatrix;
现在写你想要的东西的惯用方式是写
std::vector<HoughMatrix> hough_spaces(num_spaces, HoughMatrix::Zero());
但是,这将导致 memcpy
调用循环(至少对于 gcc 和 clang:https://godbolt.org/z/ULixBm)。
或者,您可以创建一个包含未初始化 HoughMatrix
es 的向量并在其上应用 std::memset
:
std::vector<HoughMatrix> hough_spaces(num_spaces);
std::memset(hough_spaces.data(), 0, num_spaces*sizeof(HoughMatrix));
请注意,为了 运行 而 Eigen 不必循环遍历所有元素,需要 HoughMatrix
未对齐(如开头所示)或禁用对齐断言:https://godbolt.org/z/nDJqV5
如果您实际上不需要 std::vector
功能(主要是复制和调整大小的能力),您可以在使用后使用 calloc
和 free
分配一些内存.为了防漏,可以将其封装成 std::unique_ptr
:
// unique_ptr with custom deallocator (use a typedef, if you need this more often):
std::unique_ptr<HoughMatrix[], void(&)(void*)> hough_spaces(static_cast<HoughMatrix*>(std::calloc(num_spaces, sizeof(HoughMatrix))), std::free);
if(!hough_spaces) throw std::bad_alloc(); // Useful, if you actually handle bad-allocs. If you ignore failed callocs, you'll likely segfault when accessing the data.
Clang 和 gcc 会将其优化为单个 calloc
/free
对:
https://godbolt.org/z/m4rzRq
一种完全不同的方法是尝试使用 3D 张量而不是矩阵向量:
typedef Eigen::Tensor<int, 3> HoughSpace;
HoughSpace hough_spaces(num_spaces,30,150);
hough_spaces.setZero();
看看 generated assembly 这看起来是半最优的,即使 -O3 -DNDEBUG
。
总的来说,请注意,对任何与内存相关的内容进行基准测试可能会产生误导。例如,对 calloc
的调用可能 return 几乎是瞬时的,但在较低级别上指向未分配的页面,这使得第一次访问它们的实际成本更高。