【问题标题】:How to find the memory occupied by a boost::dynamic_bitset?如何找到 boost::dynamic_bitset 占用的内存?
【发布时间】:2021-01-12 05:23:28
【问题描述】:

我正在编写一个 C++ 程序,我需要估计 boost::dynamic_bitset 占用的内存。 sizeof() 运算符总是返回 32 作为值,但我怀疑是否总是如此,尤其是当位数超过 100 万时。

估计这个的更好方法是什么?

提前致谢。

【问题讨论】:

  • 阅读 vector 的 sizeof stackoverflow.com/questions/34034849/…,这是同一个问题。 sizeof 是“接口的大小”,而不是使用多少内存结构,所以结构中有多少元素并不重要。

标签: c++ boost


【解决方案1】:

您可以预期实际内存使用量为(以字节为单位):

  • sizeof 对象本身(你说的是 32 字节)plus
  • 无论你构造了多少位 dynamic_bitset 除以 8, 可能会被您的动态内存分配库四舍五入,但最坏的情况可能是字节的下一个二的幂

如果你 push_backappenddynamic_bitset 逐渐增加它的长度,它会可能周期性地增加一倍内存使用,同样的方式例如std::vectorstd::unordered_map 可以,但我还没有检查过代码或文档。这通常被认为是过度复制和浪费内存之间的明智折衷。如果要检查,请查看源代码。

在运行时,您可以通过调用 .capacity() 并除以 8 来更准确地了解当前分配的字节数(但分配库中仍然会有一点开销,并且每个字节的字节数是固定的sizeof - 32 在你的情况下):

size_type capacity() const;

返回: *this 无需重新分配即可容纳的元素总数。 抛出:什么都没有。

见:https://www.boost.org/doc/libs/1_75_0/libs/dynamic_bitset/dynamic_bitset.html

您可以除以 8,因为您可以在一个字节中容纳 8 位。 (严格来说最好使用CHAR_BIT而不是硬编码8)。

【讨论】:

    【解决方案2】:

    一般的答案,在这里,IMO 是衡量。

    您可以使用内存分析器执行此操作。示例:Valgrind Massif

    就在前几天我为这个comment at a closed question做的:

    @RetiredNinja 刚刚运行 with 20gibibit,没问题(除了花了 5 分钟)和 20.95GiB 的峰值分配(std::string 中的 18.63GiB)——sehe 22 hours ago

    代码是:

    #include <boost/dynamic_bitset.hpp>
    #include <boost/lexical_cast.hpp>
    #include <iostream>
    
    int main() {
        boost::dynamic_bitset<> dbs(20'000'000'000);
        for (size_t i =0; i < dbs.size(); ++i) {
            dbs.set(i, rand()%2);
        }
        std::string s;
        to_string(dbs, s);
        std::cout << "Size: " << (dbs.size() >> 30) << "gibibit\n";
        std::cout << s.substr(0,10) << " ... " << s.substr(s.size() - 10, 10) << "\n";
    }
    

    我使用的命令:

    time valgrind --tool=massif ./sotest 
    

    结果是一个文件 massif.out.10060,您可以使用ms_print 进行分析:

    --------------------------------------------------------------------------------
    Command:            ./sotest
    Massif arguments:   (none)
    ms_print arguments: massif.out.10060
    --------------------------------------------------------------------------------
    
    
        GB
    20.95^                                                                       #
         |                                                            :::::::::::#
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |                                                            :          #
         |:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::          #
         |:                                                           :          #
       0 +----------------------------------------------------------------------->Ti
         0                                                                   1.629
    
    Number of snapshots: 10
     Detailed snapshots: [5 (peak)]
    
    --------------------------------------------------------------------------------
      n        time(i)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
    --------------------------------------------------------------------------------
      0              0                0                0             0            0
      1      2,280,103           72,712           72,704             8            0
      2      2,390,775    2,500,074,448    2,500,072,704         1,744            0
      3 1,508,985,532,574   22,500,076,440   22,500,072,705         3,735            0
      4 1,791,172,952,129   22,500,077,472   22,500,073,729         3,743            0
      5 1,791,172,960,303   22,500,077,472   22,500,073,729         3,743            0
    100.00% (22,500,073,729B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
    ->88.89% (20,000,000,001B) 0x4F6E408: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
    | ->88.89% (20,000,000,001B) 0x4F6EE3E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace_aux(unsigned long, unsigned long, unsigned long, char) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
    |   ->88.89% (20,000,000,001B) 0x1094AB: void boost::to_string_helper<unsigned long, std::allocator<unsigned long>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(boost::dynamic_bitset<unsigned long, std::allocator<unsigned long> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool) (basic_string.h:1453)
    |     ->88.89% (20,000,000,001B) 0x109067: main (dynamic_bitset.hpp:1273)
    |       
    ->11.11% (2,500,000,000B) 0x108F83: main (new_allocator.h:115)
    | 
    ->00.00% (73,728B) in 1+ places, all below ms_print's threshold (01.00%)
    
    --------------------------------------------------------------------------------
      n        time(i)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
    --------------------------------------------------------------------------------
      6 1,791,172,960,303    2,500,075,480    2,500,073,728         1,752            0
      7 1,791,172,960,356           73,744           73,728            16            0
      8 1,791,172,971,034            1,032            1,024             8            0
      9 1,791,172,972,716                0                0             0            0
    

    或者你可以使用像massif_visualizer这样的GUI工具:

    有关更多示例,请参阅我在此站点上使用它的其他答案:https://stackoverflow.com/search?tab=votes&q=user%3a85371%20massif

    【讨论】:

      猜你喜欢
      • 2017-01-14
      • 2017-12-20
      • 1970-01-01
      • 2015-09-09
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      相关资源
      最近更新 更多