在boost序列化中设置模板class的tracking traits以减少内存消耗
Set tracking traits of template class in boost serialization to reduce memory consumption
正如这个 link 所说的为模板 class 定义特征,我们应该手动定义它,或者我们从特征 class 中提取我们的 class。但是我想自动完成这个过程,因此受到BOOST_CLASS_TRACKING
的启发,我写了打击代码:
#include<boost/preprocessor/tuple/enum.hpp>
...
#define FOO_CLASS_TRACKING(E, PARAMETER_TUPLE, ...) \
namespace boost { \
namespace serialization { \
template<BOOST_PP_TUPLE_ENUM(PARAMETER_TUPLE)> \
struct tracking_level< __VA_ARGS__ > \
{ \
typedef mpl::integral_c_tag tag; \
typedef mpl::int_< E> type; \
BOOST_STATIC_CONSTANT( \
int, \
value = tracking_level::type::value \
); \
/* tracking for a class */ \
BOOST_STATIC_ASSERT(( \
mpl::greater< \
/* that is a prmitive */ \
implementation_level< __VA_ARGS__ >, \
mpl::int_<primitive_type> \
>::value \
)); \
}; \
}}
// which used like this
FOO_CLASS_TRACKING(boost::serialization::track_never, (typename Key, typename Value), Foo<Key, Value>)
我在我的代码中使用了这个宏,但现在我不确定这个宏是否会阻止 class 跟踪。
我有一个大数据结构,我想在序列化过程中消耗更少的内存。通过使用 callgrind
检查我的程序,我发现序列化库中的大部分 new()
调用来自文件 basic_oarchive.hpp
中名为 save_pointer
的函数,该函数存储了一个指向跟踪对象的指针映射,我预计通过将所有 classes 更改为 never_track
内存消耗会显着减少。但是没有发生重大变化。
我的宏有问题吗?或者序列化的内存消耗与对象的跟踪无关?
有什么方法可以找到 class 的跟踪特征是否已设置?
编辑:
简而言之,我的项目是一个 trie,每个节点都是抽象的指针 class 并且有指向其子节点的指针。如果我不禁用指针跟踪,所有这些节点都会保存在 boost 序列化库的映射中,并且在序列化期间内存会乘以 2。
更新:
我放在这里的宏效果很好。但是要禁用跟踪,您必须注意库中有许多内部指针可以跟踪它们。例如,在我的例子中,有许多指向 pair<const Key, Value>
的指针,这是许多 stl 或其他容器的内部指针。通过禁用所有这些内存消耗显着减少。
更新
OP 自 posted the synthetic benchmark 以来确实显示了他正在尝试测量的东西。
我运行它在Massif下,两次:左边只是建了一个大树,右边还序列化了它:https://gist.github.com/sehe/5f060a3daccfdff3178c#file-sbs-txt
Note how memory usage is basically exactly identical: object tracking is not an issue here
为了比较,启用跟踪时:https://gist.github.com/8d3e5dba7b124a750b9b
结论
Q. I used this macro in my code, but now I am not sure whether this macro prevent the class from tracking or not.
是的。很明显。
旧答案的原始脚注:
¹ 不,它通常不会是内存量的两倍——这将需要一种非常特殊的数据集,其有效负载与特里节点的大小比率非常低
正如这个 link 所说的为模板 class 定义特征,我们应该手动定义它,或者我们从特征 class 中提取我们的 class。但是我想自动完成这个过程,因此受到BOOST_CLASS_TRACKING
的启发,我写了打击代码:
#include<boost/preprocessor/tuple/enum.hpp>
...
#define FOO_CLASS_TRACKING(E, PARAMETER_TUPLE, ...) \
namespace boost { \
namespace serialization { \
template<BOOST_PP_TUPLE_ENUM(PARAMETER_TUPLE)> \
struct tracking_level< __VA_ARGS__ > \
{ \
typedef mpl::integral_c_tag tag; \
typedef mpl::int_< E> type; \
BOOST_STATIC_CONSTANT( \
int, \
value = tracking_level::type::value \
); \
/* tracking for a class */ \
BOOST_STATIC_ASSERT(( \
mpl::greater< \
/* that is a prmitive */ \
implementation_level< __VA_ARGS__ >, \
mpl::int_<primitive_type> \
>::value \
)); \
}; \
}}
// which used like this
FOO_CLASS_TRACKING(boost::serialization::track_never, (typename Key, typename Value), Foo<Key, Value>)
我在我的代码中使用了这个宏,但现在我不确定这个宏是否会阻止 class 跟踪。
我有一个大数据结构,我想在序列化过程中消耗更少的内存。通过使用 callgrind
检查我的程序,我发现序列化库中的大部分 new()
调用来自文件 basic_oarchive.hpp
中名为 save_pointer
的函数,该函数存储了一个指向跟踪对象的指针映射,我预计通过将所有 classes 更改为 never_track
内存消耗会显着减少。但是没有发生重大变化。
我的宏有问题吗?或者序列化的内存消耗与对象的跟踪无关? 有什么方法可以找到 class 的跟踪特征是否已设置?
编辑:
简而言之,我的项目是一个 trie,每个节点都是抽象的指针 class 并且有指向其子节点的指针。如果我不禁用指针跟踪,所有这些节点都会保存在 boost 序列化库的映射中,并且在序列化期间内存会乘以 2。
更新:
我放在这里的宏效果很好。但是要禁用跟踪,您必须注意库中有许多内部指针可以跟踪它们。例如,在我的例子中,有许多指向 pair<const Key, Value>
的指针,这是许多 stl 或其他容器的内部指针。通过禁用所有这些内存消耗显着减少。
更新
OP 自 posted the synthetic benchmark 以来确实显示了他正在尝试测量的东西。
我运行它在Massif下,两次:左边只是建了一个大树,右边还序列化了它:https://gist.github.com/sehe/5f060a3daccfdff3178c#file-sbs-txt
Note how memory usage is basically exactly identical: object tracking is not an issue here
为了比较,启用跟踪时:https://gist.github.com/8d3e5dba7b124a750b9b
结论
Q. I used this macro in my code, but now I am not sure whether this macro prevent the class from tracking or not.
是的。很明显。
旧答案的原始脚注:
¹ 不,它通常不会是内存量的两倍——这将需要一种非常特殊的数据集,其有效负载与特里节点的大小比率非常低