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

时间:2014-01-28 10:04:10

标签: c++ performance memory-management matrix eigen

我有一个算法需要在函数内部构造一个NxN矩阵,该函数将返回该矩阵的乘积,其中Nx1向量也是在运行中构建的。 (N通常为8或9,但必须针对大于该值的值进行推广)。

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

功能进行了基准测试,由于内存密集,存在巨大的瓶颈 分配。我的目标是构建一个线程安全的应用程序,因此,在某些情况下,我用全局向量中的元素引用替换了这些矩阵和向量,该向量用作无法存储在堆栈中的对象的提供者。这避免了调用特征矩阵和向量的构造函数/析构函数,但它不是一个优雅的解决方案,如果不采取相当的谨慎,它可能会导致巨大的问题。

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

4 个答案:

答案 0 :(得分:3)

您可以以符合您需求的方式管理自己的记忆,并使用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';
}

答案 1 :(得分:2)

将我的意见收集到一个完整的想法中。我将尝试这样做。

因为eigen中的内存分配是IMO非常先进的东西,并且它们不会暴露很多地方。最好的办法是将特征对象本身包装到某种资源管理器中,就像OP一样。

我会把它变成一个简单的bin,它包含Matrix< Scalar, Dynamic, Dynamic>个对象。通过这种方式,您可以模拟Scalar类型,并拥有广义大小矩阵的管理器。

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

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

但取决于工作时间表。如果线程在自己的数组上工作,我会考虑为每个线程创建一个资源管理器实例,这样它们就不会相互计时。问题是,如果您有12个核心在分配/解除分配上工作繁重,那么全局锁定或全局管理器可能会耗尽,并且有效地序列化您的应用程序。“/ p>

答案 2 :(得分:1)

答案 3 :(得分:0)

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