【问题标题】:On memory allocation in armadillo sparse matrices犰狳稀疏矩阵中的内存分配
【发布时间】:2016-03-18 09:25:11
【问题描述】:

我想知道创建稀疏矩阵后是否需要释放locationsvalues 对象占用的内存。代码如下:

void load_data(umat &locations, vec& values){
  // fill up locations and values
}

int main(int argc, char**argv){
    umat loc;
    vec val;
    load_data(loc,val);
    sp_mat X(loc,val);
    return 0;
}

在上面的代码中,load_data() 填充了locationsvalues 对象,然后在main() 中创建了稀疏矩阵。我的问题:在构造X 之后,我是否需要释放位置和值使用的内存?原因是X 可能很大,而我的内存不足。我知道当 main 返回时,操作系统将释放 locationsvalues 以及 X。但是,真正的问题是X 占用的内存是否与locationsvaluesX 占用的内存相同,在这种情况下我需要释放locationsvalues

【问题讨论】:

  • 它应该写在 lib 的文档中。如果没有,1。在 load_data 之前放置一个断点,检查可执行文件使用的内存大小。 2.加载相当大的数据,发现内存大小变化。 3.运行sp_mat这一行,看看内存增加率是否接近secon step。如果相同就删除,否则不要。但是,我相信有更好的方法来检查它:)
  • 你为什么不看看 SpMat 类的犰狳源代码? include/armadillo_bits/SpMat_meat.hpp

标签: c++ memory-management armadillo


【解决方案1】:

您正在使用的构造函数 (SpMat_meat.hpp:231)

template<typename T1, typename T2>
inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>&  values, const bool sort_locations = true);

values 中的值的 填充稀疏矩阵。

我了解您担心内存不足,如果将locvalX 分开保存,您基本上拥有相同数据的两个副本,占用的内存是实际需要的两倍(这确实是您的代码 sn-p 中发生的情况),所以我将尝试专注于解决这个问题并给您一些选择:

1) 如果您可以暂时保留两个数据副本,最简单的解决方案是动态分配locval,并在@ 初始化后立即删除它们987654328@

int main(int argc, char**argv){
    umat* ploc;
    vec* pval;
    load_data(*ploc,*pval); 
    // at this point we have one copy of the data
    sp_mat X(*ploc,*pval); 
    // at this point we have two copies of the data
    delete ploc;
    delete pval;
    // at this point we have one copy of the data

    return 0;
}

当然,您可以使用安全指针代替 C 风格的指针,但您明白了。

2) 如果您绝对不想在任何时候拥有两个数据副本,我建议您修改您的load_data 例程,以依次加载值并直接将它们插入X

void load_data(umat &locations, vec& values, sp_mat& X){
 // fill up locations and values one by one into X
}

其他选项是 i) 使用移动语义将val 中的值直接移动X 或 ii) 直接使用为val 分配的内存作为@ 的内存987654336@,类似于矩阵的高级构造函数

Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem = true, const bool strict = false)

然而,这两个选项都需要在犰狳库级别上进行修改,因为尚未为稀疏矩阵提供这样的功能(目前只有一个普通的移动构造函数)。不过,向开发人员请求这些功能是个好主意!

【讨论】:

  • 感谢您的回答。我找到了答案。尽管。根据犰狳,它在堆上分配内存,它与locationsvalues 是分开的。我可以在分配 X 后立即释放内存。对于您的第二种选择,一个接一个地填充 X 是非常昂贵的。正如犰狳文档所说,批量插入非常快。我在尝试您的第二个解决方案时发现了同样的问题。这真的很耗时。原因是 X 是稀疏的,每次你填满它时,它都会寻找随机分布在一个大数组中的位置。这样做需要一些开销。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 2020-12-09
  • 1970-01-01
相关资源
最近更新 更多