如何找到boost::dynamic_bitset占用的内存?
How to find the memory occupied by a boost::dynamic_bitset?
我正在写一个C++程序,我需要估计一个boost::dynamic_bitset<>占用的内存。 sizeof() 运算符总是 returns 32 作为值,但我怀疑是否总是如此,尤其是当位数超过 100 万时。
估计这个的更好方法是什么?
提前致谢。
您可以预期实际内存使用量(以字节为单位):
sizeof
对象本身(在你的例子中你说的是 32 字节)plus
- 然而,您构建的
dynamic_bitset
的许多位除以 8,
可能会被你的动态内存分配库四舍五入,但最坏的情况下可能会以字节为单位
如果您 push_back
或 append
到 dynamic_bitset
逐渐增加其长度,它会可能 周期性地使内存使用量加倍,同样的方式,例如std::vector
和 std::unordered_map
可以,但我还没有检查代码或文档。这通常被认为是过度复制和浪费内存之间的合理折衷。如果要查看,请查看源代码。
在运行时,您可以通过调用 .capacity()
并除以 8 来更准确地了解当前分配的字节数(但分配库仍然会有一些开销,并且有固定的每个 sizeof
的字节数 - 在您的情况下为 32):
size_type capacity() const;
Returns: The total number of elements that *this can hold without requiring reallocation.
Throws: nothing.
参见:https://www.boost.org/doc/libs/1_75_0/libs/dynamic_bitset/dynamic_bitset.html
您可以除以 8,因为您可以在一个字节中容纳 8 位。 (严格来说,最好使用 CHAR_BIT 而不是硬编码 8)。
笼统的回答,这里IMO就是衡量。
您可以使用内存分析器执行此操作。示例:Valgrind 地块
就在前几天我为此做了 comment at a closed question:
@RetiredNinja just ran with 20gibibit, no problem (except it took 5 minutes) and peak allocation of 20.95GiB (18.63GiB in a std::string) – 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
或者您可以使用 GUI 工具,例如 massif_visualizer
:
有关更多示例,请参阅我在此站点上使用它的其他答案:https://whosebug.com/search?tab=votes&q=user%3a85371%20massif
我正在写一个C++程序,我需要估计一个boost::dynamic_bitset<>占用的内存。 sizeof() 运算符总是 returns 32 作为值,但我怀疑是否总是如此,尤其是当位数超过 100 万时。
估计这个的更好方法是什么?
提前致谢。
您可以预期实际内存使用量(以字节为单位):
sizeof
对象本身(在你的例子中你说的是 32 字节)plus- 然而,您构建的
dynamic_bitset
的许多位除以 8, 可能会被你的动态内存分配库四舍五入,但最坏的情况下可能会以字节为单位
如果您 push_back
或 append
到 dynamic_bitset
逐渐增加其长度,它会可能 周期性地使内存使用量加倍,同样的方式,例如std::vector
和 std::unordered_map
可以,但我还没有检查代码或文档。这通常被认为是过度复制和浪费内存之间的合理折衷。如果要查看,请查看源代码。
在运行时,您可以通过调用 .capacity()
并除以 8 来更准确地了解当前分配的字节数(但分配库仍然会有一些开销,并且有固定的每个 sizeof
的字节数 - 在您的情况下为 32):
size_type capacity() const;
Returns: The total number of elements that *this can hold without requiring reallocation. Throws: nothing.
参见:https://www.boost.org/doc/libs/1_75_0/libs/dynamic_bitset/dynamic_bitset.html
您可以除以 8,因为您可以在一个字节中容纳 8 位。 (严格来说,最好使用 CHAR_BIT 而不是硬编码 8)。
笼统的回答,这里IMO就是衡量。
您可以使用内存分析器执行此操作。示例:Valgrind 地块
就在前几天我为此做了 comment at a closed question:
@RetiredNinja just ran with 20gibibit, no problem (except it took 5 minutes) and peak allocation of 20.95GiB (18.63GiB in a std::string) – 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
或者您可以使用 GUI 工具,例如 massif_visualizer
:
有关更多示例,请参阅我在此站点上使用它的其他答案:https://whosebug.com/search?tab=votes&q=user%3a85371%20massif