我有一个算法需要在函数内部构造一个NxN矩阵,该函数将返回该矩阵的乘积,其中Nx1向量也是在运行中构建的。 (N通常为8或9,但必须针对大于该值的值进行推广)。
我正在使用特征库来执行更复杂的代数运算(最小二乘和其他一些约束问题),因此切换它不是一种选择。
我对功能进行了基准测试,由于内存密集,存在巨大的瓶颈 分配。我的目标是构建一个线程安全的应用程序,因此,在某些情况下,我用全局向量中的元素引用替换了这些矩阵和向量,该向量用作无法存储在堆栈中的对象的提供者。这避免了调用特征矩阵和向量的构造函数/析构函数,但它不是一个优雅的解决方案,如果不采取相当的谨慎,它可能会导致巨大的问题。
因此,Eigen是否提供了一种解决方法,因为我没有看到将分配器作为这些对象的模板参数传递的选项,还是有更明显的事情要做?
答案 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
类型,并拥有广义大小矩阵的管理器。
每当你调用一个对象时,你会检查你是否有一个所需大小的自由对象,然后返回对它的引用。如果没有,您分配一个新的。简单。如果要释放对象,则在资源管理器中将其标记为空。我不认为需要更复杂的东西,但当然可以实现更复杂的逻辑。
为了确保线程安全,我会在管理器中锁定。如果需要,在构造函数中初始化它。当然,需要锁定free
和allocate
。
但取决于工作时间表。如果线程在自己的数组上工作,我会考虑为每个线程创建一个资源管理器实例,这样它们就不会相互计时。问题是,如果您有12个核心在分配/解除分配上工作繁重,那么全局锁定或全局管理器可能会耗尽,并且有效地序列化您的应用程序。“/ p>
答案 2 :(得分:1)
您可以尝试使用jemalloc
或tcmalloc
替换默认内存分配器。感谢LD_PRELOAD
机制,很容易尝试。
我认为它也适用于大多数C ++项目。
答案 3 :(得分:0)
您可以在使用operator new
或operator new[]
调用该函数之前为某些常见的矩阵大小分配内存,将void*
指针存储在某处并让函数本身检索具有正确大小的内存块。之后,您可以使用placement new进行矩阵构造。详细信息在更有效的C ++ ,第8项中给出。