Tmp

Материал из ru.wiki.laduga.ru
Перейти к: навигация, поиск

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

1.Зачем это нужно?

Это необязательно, но это повышает эффективность Вашей программы.

Когда C++ возвращает локальный объект, он копирует объект, возвращает копию и удаляет оригинал. Такое поведение является безопасным управлением памятью; Однако, если Вы имеете дело с большими объектами (такими, как 10-милионно элементное тензорное поле), это может быть дорогостоящим процессом. Передача ссылки не будет работать потому, что данные всё-равно будут выходить за пределы области действия. Задача состоит в том, чтобы получить большой набор данных, чтобы правильно произвести изменение масштаба, что и делает tmp.

2.Когда это нужно?

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

3.Как этим пользоваться?

Все объекты, которые выше одного размера поля, могут использовать tmp. Все они могут преобразовываться из tmp<object> в object, поэтому tmp прозрачный. Чтобы вернуть большой объект с помощью tmp, просто заключите возвращаемый тип в tmp< >:

// Original:
largeClass myFunc ()
   {
       largeClass returnMe(new largeClass);
       // Somehow fill the data in returnMe
       return returnMe;
   }
// Becomes:
tmp<largeClass> myFunc()
   {
       tmp<largeClass> tReturnMe(new largeClass);
       largeClass& returnMe = tReturnMe();
       // Somehow fill the data in returnMe
       return tReturnMe;
   }

Чтобы явно развернуть объект, используйте operator().

Уменьшение пиковой памяти менее важно, чем это было в 70-х годах, но иногда это может быть необходимо. Использование tmp для уменьшения объёма памяти:

  • Во-первых, алгоритм должен иметь точку, в которой Вы можете выбросить большое количество данных.
  • Поместите объект с отбрасываемыми данными в tmp:
tmp<largeClass> discardableDataObject;
  • Используйте объект, как обычно.
  • Когда придёт время выбросить данные:
discardableDataObject.clear();
  • Память освобождается.

Смотрите simpleFoam в качестве примера. Также показано здесь.

4.Как это работает?

4.1 Резюме

Обычно при возврате локального объекта, компилятор сначала вызывает copy constructor для создания возвратной копии, а затем вызывает деструктор исходного объекта для его очистки destructor. <tmp> переопределяет обе эти функции. Когда компилятор вызывает copy constructor, tmp копирует только pointer и reference, оставляя данные там, где они есть. Когда компилятор вызывает destructor, исходный tmp перенаправляет свой pointer на NULL. Поскольку данные имеют новую reference на него, компилятор оставляет его в покое, и новые данные сохраняются. На практике это становится немного сложнее.

4.2 Реализация

Переопределения copy constructor и destructor недостаточно для того,чтобы это сработало. Если tmp должен быть прозрачным, он должен вести себя так, как обычно ведёт себя развёрнутый объект. Это означает, что иногда tmp нужно будет правильно удалить, или его данные нужно будет правильно дублировать. Это означает, что он должен определить когда временный локальный объект, когда это дублированный объект, а когда это просто обычный объект в стеке. Чтобы достичь этого:

  • tmp содержит флаг, определяющий, является ли он временным объектом.
    • Флаг устанавливается true, если tmp строится из pointer на объект, как это было бы с new ключевым словом.
    • Флаг устанавливается false, если tmp создаётся из ссылки, как это происходит, если объект уже существует, или tmp помещается в стек.
    • Смотрите autoPtr для аналогичного класса обёртки, подходящего для pointers.
  • Все объекты, использующие tmp, отслеживают, сколько references указывают на них.
    • Это достигается с помощью класса refCount, и является одной из затрат, использующих tmp.
  • При удалении tmp спрашивает object сколько ссылок указывает на него.
    • Если их несколько, то при удалении tmp перенаправляет свой указатель.
    • Если есть только один, tmp не перенаправляет свой указатель, и данные окончательно удаляются.

Marupio 20:28, 26 February 2010 (UTC)

Ссылка на оригинал - http://openfoamwiki.net/index.php/OpenFOAM_guide/tmp