OpenFOAM guide/tmp

From OpenFOAMWiki

tmp is a wrapper class that allows large local objects to be returned from functions / methods without being copied. It also allows a program to quickly clear a large object out of memory, which can be used to reduce the peak memory. tmp works in the background and is not usually visible at the top-level code.

1 Why is it needed?

It isn't needed at all, but it reduces the effort and increases the efficiency of your program.

When C++ returns a local object, it copies the object, returns the copy, and deletes the original. This behaviour is safe memory management; however, if you are dealing with large objects (such as a 10 million element geometric tensor field), it can be a costly process. Passing a reference won't work because the data will still be going out of scope. The challenge is getting the large dataset to survive the change in scope, something that tmp accomplishes.

2 When do you need it?

If you are using OpenFOAM, you are already using tmp without seeing it. You can explicitly use it anytime you are returning a large local object. Furthermore, tmp is useful anytime you can delete a large object in the middle of an algorithm to reduce peak memory.

3 How do you use it?

All objects above a single field size can use tmp. They all can convert from tmp<object> to object, so tmp is transparent. To return a large object using tmp, simply enclose the return type with 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;
    }

To explicitly unwrap the object, use operator().

Reducing peak memory is less important now than it was in the 70's, but sometimes it may be necessary. To use tmp for reducing memory:

  • First, the algorithm must have a point where you can throw a large amount of data away, and this action reduces peak memory.
  • Wrap the object with the discardable data in tmp:
tmp<largeClass> discardableDataObject;
  • Use the object as usual.
  • When it comes time to throw away the data:
discardableDataObject.clear();
  • The memory is released.

See simpleFoam as an example. Also shown here.

4 How does it work?

4.1 Summary

Normally when returning a local object, the compiler will first call the copy constructor to create the return copy, then call the destructor on the original object to clean it up. <tmp> overrides both these functions. When the compiler calls the copy constructor, tmp only copies a pointer and a reference, leaving the data where it is. When the compiler calls the destructor, the original tmp redirects its pointer to NULL. Since the data has a new reference to it, the compiler leaves it alone, and the data survives. In practice, it gets a bit trickier.

4.2 Implementation

Overriding the copy constructor and destructor is not enough for this to work. If tmp is to be transparent, it must behave the way an unwrapped object would normally behave. This means sometimes tmp will need to be deleted properly, or its data will need to be duplicated properly. This mens it needs to detect when it is a temporary local object, when it is a duplicated object, and when it is just a regular object on the stack. To achieve this:

  • tmp holds a flag to determine whether it is a temporary object.
    • The flag is true if tmp it is constructed from a pointer to an object as it would be with the new keyword.
    • The flag is set to false if tmp is constructed from a reference, as would happen if the object already exists, or tmp is pushed onto the stack.
    • See autoPtr for a similar wrapper class suitable to pointers.
  • All objects usable by tmp keep track of how many references point to them.
    • This is achieved with the refCount class, and is one of the costs of implementing tmp.
  • When being deleted, tmp asks its object how many references are pointing to it.
    • If there is more than one, tmp redirects its pointer upon deletion.
    • If there is only one, tmp does not redirect its pointer, and the data is finally deleted.

Marupio 20:28, 26 February 2010 (UTC)