【问题标题】:reducing memory requirements for adjacency list减少邻接表的内存需求
【发布时间】:2010-11-24 15:55:22
【问题描述】:

我正在使用 adjacency_list 广泛地。我一次加载了这么多图表 成为一个问题。我正在做静态程序分析并存储 升压图中反汇编二进制文件的调用图和流程图。 因此我可以有几万个函数==流程图和一个 巨大的呼号。我真的很想减少我的内存使用量 仍然使用 BGL 的图表。

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

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

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

最好的问候,

Sören

【问题讨论】:

  • 这可能不是您喜欢的答案,但是当涉及到字节计数以准备一些仅用于极少数任务的 boost 库中的一些黑客攻击时——您会得到更好的答案早在 Boost 用户邮件列表 lists.boost.org/mailman/listinfo.cgi/boost-users> 中。其他可能性是阅读源代码...

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


【解决方案1】:

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 在应我的要求添加该功能方面非常有帮助。

【讨论】:

    【解决方案2】:
    1. 开销取决于您使用的版本以及您是否使用“捆绑”属性。我只使用了捆绑的属性并阅读了我希望每个属性捆绑包花费你 2 个指针 + 你正在使用的捆绑包类型的大小 + 每个附加属性的大小的代码。二进制 afaik 中没有任何概念检查内容。既然你有代码,为什么不直接衡量成本呢?如果您没有任何工具可以帮助您尝试在已知大小的缓冲区中生成已知大小的图形。某些事情最终会失败,此时您应该算数。

    2. 你试过打电话给adjacency_list<blah>.swap(adjacency_list& x)吗?我希望这会适当地缩小容器。

    3. ???

    我开始编写类似于您描述的系统的东西,但最终放弃了 BGL,转而编写自己的算法以在包含所有链接器符号的 sqlite 数据库上运行。

    【讨论】:

    • 是的,我已经尝试过缩小尺寸(建议 2),但没有多大帮助。我们也在使用数据库后端,目前支持 mySQL、postgreSQL 和 SQLite。但是,我们对这些特定算法的访问模式确实需要内存中的专用数据结构。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      作为回答:

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        • 2013-05-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多