减少邻接列表的内存需求

时间:2009-09-01 14:07:00

标签: c++ memory boost graph boost-graph

我正在使用adjacency_list< vecS,vecS,bidirectionalS ...> 广泛。我有很多图表同时加载了那个内存 成为一个问题。我正在进行静态程序分析并存储 boost图中反汇编二进制的调用图和流程图。 因此,我可以有几万个函数== flowgraphs和一个 巨大的呼唤图。我真的想减少我的内存使用量 仍在使用BGL的图表。

因为我的图形在加载和边缘和顶点计数后是静态的 事先知道我看到了巨大的优化潜力。对于 例如,我想为所有顶点/边分配一个缓冲区 单个图形,让图形只将索引存储到该缓冲区中。

更多问题:
1)使用顶点和边缘属性的内存开销是多少?一世 他们中有很多人 2)是否有可能说服BGL使用收缩装置 成语?据我所知,邻接列表使用push_back来添加 边缘。是否可以通过交换来减少内存使用量 结果矢量与自己的副本?也许通过复制整个 图?
3)是否可以将升压池分配器与BGL一起使用?目前 我可以告诉BGL目前执行大量小额分配 - 出于空间和运行时效率的原因,我真的很想避免这种情况。

是否有人已经构建了针对内存使用进行了优化的BGL版本? 我应该尝试使用现有的图形结构并使用它进行扩充 自定义分配器或某些东西,或者编写自己的分配器更有成效 实现并尝试保持与BGL的接口兼容 我可以继续使用它的算法吗?

最好的问候,

Sören

4 个答案:

答案 0 :(得分:8)

BGL中有一种鲜为人知的图形类型称为“压缩稀疏行”图。它看起来很新,并没有从索引页面链接。然而,它确实采用了一个漂亮的小技巧来使图形表示尽可能小。 http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/compressed_sparse_row.html

在我们的一些图表中使用它我已经能够将总内存使用量减少20% - 所以它确实非常值得优化。

它还将顶点/边缘属性存储在向量中,从而为这些属性提供尽可能小的开销。

请注意,使用最新boost 1.40的版本仅支持方向图(而不是双向)。如果你需要能够有效地迭代顶点的边缘和边缘(就像我所做的那样),你需要从subversion中检出boost trunk。 Jeremiah非常乐于根据我的要求添加该功能。

答案 1 :(得分:1)

  1. 开销取决于您使用的是哪个版本,以及您是否选择了“捆绑”属性。我只使用捆绑属性并阅读代码我期望每个属性包花费你2个指针+你使用的捆绑类型的大小+每个附加属性的sizeof。没有概念检查的东西留在二进制afaik。既然你有代码,为什么不测量成本呢?如果您没有任何工具来帮助尝试在已知大小的缓冲区中生成已知大小的图形。有些事情最终会失败,那时你应该有计数。

  2. 您是否尝试过调用adjacency_list<blah>.swap(adjacency_list& x)?我希望能够妥善收缩容器。

  3. ???

  4. 我开始编写类似你正在描述的系统,但最终放弃了BGL并切换到编写我自己的算法,在所有链接符号的sqlite数据库上运行。

答案 2 :(得分:0)

由于BGL设计为interoperate with legacy or custom graphs,因此您最好自己编写自己的图表。

答案 3 :(得分:0)

作为答案:

  

3)是否可以将升压池分配器与BGL一起使用?据我所知,BGL目前执行大量的小分配 - 出于空间和运行时效率的原因,我真的很想避免这种情况。

here复制的代码:

 template <class Allocator>
  struct list_with_allocatorS { };

  namespace boost {
    template <class Alloc, class ValueType>
    struct container_gen<list_with_allocatorS<Alloc>, ValueType>
    {
      typedef typename Alloc::template rebind<ValueType>::other Allocator;
      typedef std::list<ValueType, Allocator> type;
    };
  }

  // now you can define a graph using std::list 
  //   and a specific allocator  
  typedef adjacency_list< list_with_allocatorS< std::allocator<int> >, vecS, directedS> MyGraph;