Установите черты отслеживания класса шаблона в ускоренной сериализации, чтобы уменьшить потребление памяти

Как указала эта ссылка для определения признаков для класса шаблона, мы должны определить его вручную или мы извлекаем наш класс из класса признаков. Но я хочу сделать этот процесс автоматически, по этой причине вдохновленный BOOST_CLASS_TRACKING Я написал код удара:

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>)

Я использовал этот макрос в своем коде, но теперь я не уверен, мешает ли этот макрос отслеживанию класса или нет. У меня большая структура данных, и я хочу использовать меньше памяти во время сериализации. Проверяя мою программу, используя callgrind Я обнаружил, что большинство new() вызов в сериализации lib из функции с именем save_pointer в файле basic_oarchive.hpp который хранит карту указателей для отслеживания объектов, я ожидал, изменив все классы на never_track потребление памяти значительно снижается. Но никаких существенных изменений не произошло.

У моего макроса есть проблема? или потребление памяти при сериализации не относится к отслеживанию объектов? Есть ли способ узнать, что отслеживающие черты класса были установлены или нет?

Редактировать:

Вкратце, мой проект состоит в том, что каждый узел является указателем на абстрактный класс и имеет указатель на его потомков. Если я не отключаю отслеживание указателей, все эти узлы сохраняются на карте библиотеки расширенной сериализации, а память умножается на два во время сериализации.

Обновить:

Макрос, который я здесь поставил, работает хорошо Но для отключения отслеживания вы должны заметить, что существует много внутренних указателей на то, что библиотека отслеживает их. Например, в моем случае было много указателей на pair<const Key, Value> который является внутренним указателем многих stl или других контейнеров. При отключении всех из них потребление памяти значительно уменьшается.

1 ответ

Решение

ОБНОВИТЬ

С тех пор OP опубликовал синтетический тест, показывающий, что он пытается измерить.

Я запускал его под Massif, дважды: слева просто строил большое дерево, а справа также сериализировал его: https://gist.github.com/sehe/5f060a3daccfdff3178c

введите описание изображения здесь

Обратите внимание, что использование памяти в основном точно одинаково: отслеживание объектов здесь не проблема

Для сравнения, когда отслеживание включено: https://gist.github.com/8d3e5dba7b124a750b9b

введите описание изображения здесь

Заключение

В. Я использовал этот макрос в своем коде, но теперь я не уверен, мешает ли этот макрос отслеживанию класса или нет.

Да. Это ясно делает.


Оригинальная сноска из старого ответа:

¹ Нет, это обычно не удваивает объем памяти - это потребовало бы очень специфического вида набора данных с очень низким отношением размера полезной нагрузки к размеру узла.

Другие вопросы по тегам