Есть ли способ сделать «многоразовый снимок» программы? - PullRequest
2 голосов
/ 19 февраля 2020

Вот ситуация: я работаю над относительно большой программой на C ++ (в Linux). Эта программа может быть разделена на две части. Часть A - это просто набор предварительных вычислений, основанных на некоторых данных, которые остаются неизменными с течением времени, что создает довольно сложную и большую структуру данных. Проблема в том, что часть А занимает слишком много времени (около минуты), и вы можете предположить, что она не может быть значительно оптимизирована в дальнейшем. Часть B, которая идет сразу после части A, в основном представляет собой несколько запросов к данным, загруженным в часть A.

Итак, вот что я хочу сделать: поскольку структура данных, построенная в части A, всегда одинакова, не было бы неплохо иметь «снимок» этого, и поэтому, каждый раз, когда вы загружаете программу, вы можете просто быстро извлечь данные из снимка и просто перейти прямо к B?

И вот вопрос: есть ли способ сделать это?

Ответы [ 3 ]

5 голосов
/ 19 февраля 2020

То, что вы описываете, по сути является «контрольной точкой» в HP C: вы назначаете кусок памяти, который можно быстро восстановить при перезапуске программы, не тратя значительное время на сохранение / загрузку этих данных.

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

При перезапуске программы вы просто сопоставьте память снова и проверьте, была ли она инициализирована или нет. Таким образом, ваше время запуска сводится практически к нулю (время для отображения в памяти файла и загрузки фрагментов с диска по мере необходимости).

Вы не представили никакого кода, поэтому я не могу дать вам конкретный совет, но вам нужно будет убедиться, что все выделения памяти для дорогостоящей части выполняются внутри памяти, управляемой Ken, например, путем реализации собственного распределителя памяти, поддерживаемого памятью, управляемой Ken, путем передачи настраиваемого распределителя во все структуры данных STL, или просто убедите свою библиотеку управления памятью выделить память в памяти Кена. Пример последнего параметра см. В разделах jemallo c arena.create и thread.arena.

1 голос
/ 19 февраля 2020

Для автоматического решения c, которое не требует кода, вы можете взглянуть на CRIU (Checkpoint / Restore In Userspace), которое позволяет вам заморозить запущенный процесс и проверить его состояние на диске , Чтобы затем восстановить процесс и запустить его точно так же, как это было во время остановки.

0 голосов
/ 19 февраля 2020

Если вы контролируете все распределения, используемые в этой структуре данных, возможно, есть разумный путь.

Вы начинаете с байтов вашего файла "A.saved". Вместо указателей у вас есть смещения от начала файла.

unsigned char * start; // !! global pointer

template <typename T>
class offset_ptr {
    std::size_t offset;
public:
    offset_ptr(std::size_t offset) : offset(offset) {}
    offset_ptr(T* ptr) : offset(pointer - start) {}

    T& operator*() const { return *reinterpret_cast<T*>(start + offset); }
    T& operator->() const { return reinterpret_cast<T*>(start + offset); }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...