2011-11-24

Standard allocator interface.

As you know, Open CASCADE has its own memory allocation mechanism, which entry points are Standard::Allocate() and Standard::Free(). They forward (de-)allocation requests to a current memory manager, which can either be a). default system allocator (if environment variable MMGT_OPT=0), b). own Open CASCADE's (MMGT_OPT=1), or c). Intel TBB (MMGT_OPT=2).

Most Open CASCADE classes (e.g. all which are defined in .cdl files) redefine operators new and delete to use Standard::Allocate() and Standard::Free() respectively – look at any .hxx file.

Using common memory allocation mechanism allows to decrease memory footprint and/or increase performance, especially when using TBB allocator (in multi-threaded apps). However, you may easily miss this advantage in your application in the following typical cases:
1. You dynamically allocate objects of your classes and their new/delete operators do not use Standard::Allocate()/::Free().
2. You use standard containers (std::vector, std::map, std::list,...).
#1 is easily addressed by redefining new/delete operators in your base class(es) in a way similar to OCC.
#2 is more tough, as standard collections by default use standard allocator (std::allocator<T>). So all auxiliary elements (e.g. list nodes) are allocated outside of OCC-governed memory allocator.

This was until now. Hereby I would like to share a code that implements the standard allocator interface as defined by the ISO C++ Standard 2003 (and also conforming to a recently published C++11). Download Standard_StdAllocator.hxx.

This is a pure header implementation, so no .cxx files and linking with libraries is needed; just copy to your project and start using. Implementation is derived from Intel tbb::tbb_allocator, which itself just follows the C++ standard requirements.

The file is intentionally made copyright-free and put into a Public domain, the most permissive way. I also hope that the OCC team will be willing to pick up this file and integrate into OCC.

The simplest example can be as follows:

typedef Standard_StdAllocator<void> allocator_type;

std::vector<TopoDS_Shape, allocator_type> aSVec;
TopoDS_Solid aSolid = BRepPrimAPI_MakeBox (10., 20., 30.);
aSVec.push_back (aSolid);

std::list<int_Shape, allocator_type> aList;
aList.push_back (1);


There is also a unit test (download Standard_StdAllocatorTest.cxx). The code is based on Qt test framework and should be self-explaining to port to any other test framework.

Those who are curious enough may offer similar standard allocator implementation for NCollection_BaseAllocator which is used in NCollection containers. It is as straightforward as this one.

9 comments:

  1. Thanks Roman for this very interesting post and your contribution. However, it seems there is an issue with the repository you used. I'm able to download hxx/cxx files, but they appear to be some kind of html code, nothing to do with C++ code.

    ReplyDelete
  2. Hi Thomas,
    Please just go to the page following the url's and click the Download buttons. That should work.
    Otherwise - download from the OCC thread http://www.opencascade.org/org/forum/thread_22234/.

    ReplyDelete
  3. The referred files (Standard_StdAllocator.hxx ...) are broken.

    ReplyDelete
  4. As mentioned above, click the links. Then push the download buttons.

    ReplyDelete
  5. Hi Roman, there is a compile error on OSX/gcc-4.2.1 (see https://github.com/tpaviot/oce/issues/204)

    ReplyDelete
  6. Hi Thomas, thanks for reporting this and sorry for the trouble. I only verified compilation with VS2008 as was traveling with a notebook.
    Will try to look into the issue and provide a fix.
    Roman

    ReplyDelete
  7. The fix has been pushed to the OCE repositoy.

    By the way, you write that "Using common memory allocation mechanism allows to decrease memory footprint and/or increase performance". What should we expect from your patch in terms of performance/memory footprint? Did you measure any significant improvement?

    ReplyDelete
  8. Thank you and Denis Barbier for fix and integrating it!
    Performance and memory footprint benefits heavily depend on a workload where both OCC and standard mechanisms are mixed. I have not created a synthetic case to show it but the following explanation should give an idea.
    If the code intensively uses both, then there can be extra footprint given that standard containers allocate memory outside of OCC mechanism (when using OCC or TBB allocator), which meanwhile can hoard memory without using it.
    Performance penalties (from standard allocation) may come from two sources: a). fragmentation, which may appear during intensive allocation/deallocation of objects via standard allocator; b). multi-threaded environment where standard allocator uses a central coarse-grain lock causing threads to wait for each other. When using TBB allocator both issues are addressed, when using OCC - #a is addressed, while #b remains.

    ReplyDelete
  9. i like this blog...
    Louisiana Jobs | Careers & Recruitment at Jobscharger.com
    http://www.jobscharger.com/JobState/-Louisiana-.html

    ReplyDelete