繁体   English   中英

C ++本征矩阵运算与内存分配性能

[英]C++ Eigen Matrix Operations vs. Memory Allocation Performance

我有一种算法,要求在函数内部构造NxN矩阵,该函数将返回该矩阵与Nx1向量的乘积,该向量也是动态生成的。 (N通常为8或9,但必须将其推广为大于该值的值)。

我正在使用Eigen库来执行更复杂的代数运算(最小二乘和其他一些受约束的问题),因此切换它不是一个选择。

我已经这些函数进行了基准测试 ,由于密集的内存分配,存在一个巨大的瓶颈。 我的目标是构建一个线程安全的应用程序,因此,在某些情况下,我用对全局向量中元素的引用替换了这些矩阵和向量,这些向量用作无法存储在堆栈中的对象的提供程序。 这样可以避免调用Eigen矩阵和向量的构造函数/析构函数,但这不是一个很好的解决方案,如果不加注意的话,可能会导致巨大的问题。

这样,Eigen是否提供了一种解决方法,因为我看不到将分配器作为这些对象的模板参数传递的选项,还是还有其他更明显的事情要做?

您可以按照自己的需要来管理自己的内存,并使用Eigen::Map而不是Eigen::Matrix来执行计算。 只要确保数据正确对齐即可,否则请通知Eigen。

有关详细信息,请参见参考Eigen :: Map

这是一个简短的示例:

#include <iostream>
#include <Eigen/Core>


int main() {
    int mydata[3 * 4]; // Manage your own memory as you see fit
    int* data_ptr = mydata;

    Eigen::Map<Eigen::MatrixXi, Eigen::Unaligned> mymatrix(data_ptr, 3, 4);

    // use mymatrix like you would any another matrix
    mymatrix = Eigen::MatrixXi::Zero(3, 4);
    std::cout << mymatrix << '\n';

    // This line will trigger a failed assertion in debug mode
    // To change it see
    // http://eigen.tuxfamily.org/dox-devel/TopicAssertions.html
    mymatrix = Eigen::MatrixXi::Ones(3, 6);


    std::cout << mymatrix << '\n';
}

将我的意见收集成一个完整的想法。 这是我将尝试执行的操作。

因为本征中的内存分配是IMO相当高级的东西,所以它们没有暴露很多要使用的地方。 最好的选择是将特征对象本身包装到某种资源管理器中,例如OP。

我将其设为一个简单的bin,其中包含Matrix< Scalar, Dynamic, Dynamic>对象。 这样,您就可以对Scalar类型进行模板化,并拥有一个用于通用大小矩阵的管理器。

每当调用对象时,都会检查是否有所需大小的空闲对象,然后返回对该对象的引用。 如果不是,则分配一个新的。 简单。 当您要释放对象时,可以在资源管理器中将其标记为空闲。 我认为不需要任何更复杂的事情,但是当然可以实现一些更复杂的逻辑。

为了确保线程安全,我将锁定管理器。 如果需要,在构造函数中对其进行初始化。 当然,需要锁定freeallocate

但是取决于工作时间表。 如果线程在它们自己的数组上工作,我会考虑为每个线程创建一个资源管理器实例,这样它们就不会互相计时。 事实是,如果您有12个核心在分配/取消分配上投入大量精力,并有效地序列化了您的应用程序,那么全局锁或全局管理器可能会筋疲力尽。

您可以尝试使用jemalloctcmalloc替换默认的内存分配器。 LD_PRELOAD机制,很容易尝试。

我认为它也适用于大多数C ++项目。

您可以使用operator newoperator new[]调用该函数之前 ,为某些常见的矩阵大小分配内存,将void*指针存储在某个位置,然后让函数本身检索具有正确大小的内存块。 之后,您可以使用new放置进行矩阵构建。 更有效的C ++项目8中给出了详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM