Allocators for Shared Memory in C++03, C++11, and Boost ACCU 2013, Bristol

Allocators for Shared Memory in C++03, C++11, and Boost ACCU 2013, Bristol

Allocators for Shared Memory in C++03, C++11, and Boost ACCU 2013, Bristol Frank Birbacher Inform GmbH, Aachen 13th April 2013, r210 C++ allocators are rarely looked at but for using shared memory as a means of interprocess communication they spring to mind. For a long time this was a good idea in theory but in practice not until C++11. Explaining allocators and their use case “shared memory” is the focus here. Shared memory is shown using tne Boost.Interprocess library. Contents 1 Allocators 03 2 1.1 Idea . 2 1.2 Definition . 3 1.3 Problems in C++03 . 6 2 Shared Memory 8 2.1 What is it? . 8 2.2 Pointers in shared memory . 9 2.3 Boost.Interprocess: The Big Picture . 11 2.4 String in shared memory . 12 3 Allocators 11 16 3.1 What’s new in C++11? . 16 3.2 Scoped allocator . 19 4 Appendix 22 4.1 Allocator 03—details . 22 4.2 std::list 03 using an allocator . 23 4.3 std::list 11 using an allocator . 24 4.4 Propagating allocators 11 . 25 4.5 Source code: strings in shared memory . 26 Allocators and Shared Memory Frank Birbacher Goals of this presentation Slide 2 • show functionality of allocators • show allocator use in shared memory • compare allocators in C++03 and C++11 • show the scoped allocator adaptor The functionality of C++03 allocators is explained and how the idea of allocators can be leveraged for accessing shared memory. Examples will demonstrate construction of standard containers in shared memory. Afterwards the changes to allocators in C++11 will be shown. These changes influence the way containers use allocators and they enable more control over object construction. This will be shown with the scoped allocator adaptor. 1 Allocators 03 1.1 Idea The hidden strategy Slide 5 • allocator is parameter of containers • allocator is member of containers • strategy pattern • rarely changed namespace std { template< typename T, typename Alloc = std::allocator<T> // <== > class list { ... }; An allocator is rarely looked at. It is a template parameter of every standard con- tainer and defaults to std::allocator. If changed this parameter will influence the way a container interacts with memory. Additionally an instance of the given type is stored as a container member. As such the allocator is a strategy object that may carry state. Concept Slide 6 Influence … • access to objects – abstraction from memory model – for example far and near pointer (Intel x86 16bit) • allocation scheme r210 2 Inform GmbH, Aachen Allocators and Shared Memory Frank Birbacher – changing allocation strategy • object construction – influence initialization ùñ C++11 scoped allocator by defining … • types for pointer and its arithmetic – usually T* – could be a pointer like class – could be separate pointer type provided by compiler • replacements for “malloc” and “free” – called “allocate” and “deallocate” – they match pointer type – provide uninitialized memory • wrappers for object con-/destruction – called “construct” and “destroy” – initialise given memory An allocator has three tasks: first it defines how memory and objects are addressed and accessed, second it may change the way to allocate raw memory, and third it can influence object construction. Allocators were invented in 1994 in preparation of the C++1998 standard. It was en- visioned allocators could enable access to different types of memory like shared memory, persistent memory, or different memory hardware in embedded systems. Alexander Stepanov, the original author of the STL, said the following: A nice feature of STL is that the only place that mentions the machine-related types in STL—something that refers to real pointer, real reference—is encap- sulated within roughly 16 lines of code. (Alexander Stepanov, in Dr. Dobb’s Journal, March 1995) 1.2 Definition Functionality of allocators Slide 8 template<typename T> struct allocator allocate deallocate raw mem: construct destroy object: T = value_type r210 3 Inform GmbH, Aachen Allocators and Shared Memory Frank Birbacher • two step object construction • allocation and construction separated Before showing the raw definition of allocators we take a look at the functionality of allocators. That is the way they are used to create new objects in memory. An allocator is usually a class template with a parameter. This parameter is called the value type. The allocator is prepared to provide and initialize memory for its value type. The object construction and memory allocation are separated. Memory is allocated by calling the function allocate which returns uninitialised memory. This memory is initial- ised using the function construct. On the reverse the functions destroy and deallocate free the object. A quick reference of all allocator members is given in the appendix, see page 22. Pointer type Slide 9 Task 1: define pointer type template<typename T> struct allocator { typedef T value_type; typedef ... pointer; // T* typedef ... const_pointer; // T const* typedef ... reference; // T& typedef ... const_reference; // T const& typedef ... size_type; // size_t typedef ... difference_type; // ptrdiff_t ... An allocator defines a bunch of types. At first it publishes its value type. But the most important one is the pointer type. It may be any pointer like type that overloads operators -> and unary * and acts like a random access iterator. The pointer type is accompanied by the respective reference type and types for pointer arithmetic. The size_type is unsigned while the difference_type is signed and is the result of pointer subtraction. Malloc and free Slide 10 Task 2: change allocation scheme template<typename T> struct allocator { ... pointer allocate(size_type nObjs, void* hint =0); // malloc(nObjs * sizeof(T)) void deallocate(pointer p, size_type nObjs); r210 4 Inform GmbH, Aachen Allocators and Shared Memory Frank Birbacher // free(p) ... Besides the pointer type the allocator provides the functions allocate and deallocate. They act similar to malloc and free in that they provide uninitialised memory. But they define the size of the request in number of objects of value type, not in number of bytes. A possible implementation of allocate could call malloc. It would multiply the number of objects and the size of its value type to determine the number of bytes required. The optional hint pointer can have special meaning which is solely defined by the allocator. On the slide the hint pointer is shown with type void*, but actually it has the pointer type of the void instantiation of the allocator: allocator<void>::const_pointer. The value of the hint must be a still valid—not deallocated—previously allocated memory block. For instance it could be a request to place the new allocation near the old one in order to increase data locality. Note that the deallocate function also takes the size of the block. This is unusual, but the value is usually known and it may help the allocator implementation on custom allocation schemes. Construction and Destruction Slide 11 Task 3: wrap object construction template<typename T> struct allocator { ... // in C++03: void construct(pointer, T const&); void destroy(pointer); ... For actual object construction and destruction the functions construct and destroy are provided. The first one copies a given object instance into the memory that the pointer points to. That means construct will invoke the copy constructor of T. The function may have side effects. The second function simply has to invoke the destructor of the object pointed to. It may have side effects as well. This very limited functionality of construct and destroy is enhanced in C++11. Changing value type Slide 12 gets A = allocator<int> list<int, A> rebind+ctor allocator<list::node> wants r210 5 Inform GmbH, Aachen Allocators and Shared Memory Frank Birbacher template<typename T> struct allocator { ... // ”template typedef”: template<typename U> struct rebind { typedef allocator<U> other; }; // constructor: template<typename U> allocator(allocator<U> const&); The allocator instances passed to standard containers always specify the same value type as the container. But for some containers objects of different type have to be created in memory. For instance the std::list will construct list nodes with extra pointers to store the links to next and previous nodes. This means a list<int> gets an allocator for int but requires an allocator for its node<int> type. In order to enable construction of nodes the list needs to somehow “rebind” the given allocator type to a new value type. This is accomplished by a nested class template named “rebind” that provides a new allocator instantiation. This is like the new C++11 alias templates, but in old C++98 style. The rebind template is accompanied by a converting constructor that converts any allocator object into its own type. Using the rebind template the list determines the rebound allocator type and using the constructor it converts any allocator object passed in to that new type. It will store and use that converted object as a member. A quick reference of all allocator members is given in the appendix, see page 22. std::list using an allocator Slide 13 Alloc allocate deallocate Alloc construct destroy struct node { next prev T value }; Continuing with the list the picture shows the steps to construct a list node. On the rebound allocator the allocate function provides the list with memory for a single node. In that memory the list constructs a node by means of the construct function. The node contains the list pointers and the actual list element type. As this demonstrates the element type T is not constructed by the allocator directly. That’s why the allocator<T> is of no direct use. Everything is done by the allocator<node<T> >. Code that shows the approach can be found in the appendix, see page 23. 1.3 Problems in C++03 Problems in the definition Slide 15 • reference type redundant r210 6 Inform GmbH, Aachen Allocators and Shared Memory Frank Birbacher – will always be T&, no replacement possible – cannot overload operator .

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    28 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us