I am trying to use boost::singleton_pool to create a large number of objects of a type 'Order' in a highly performance critical multithreaded application. Looking at the documentation, this is what I should be doing,
struct OrderTag{};
typedef boost::singleton_pool<OrderTag, sizeof(Order)> OrderPool;
boost::singleton_pool has a static member function malloc which returns pointer of the void*, but I need to create objects of the type Order in OrderPool by making calls to its constructor. Shall I be using boost::pool_allocator along with singleton_pool to do so?
Thanks.
In short: no. boost::pool_allocator implementation itself uses boost::singleton_pool and provides interface like std::allocator so you can use it with STL containers (but not only STL and not only containers) like vector, list etc. The UserAllocator concept is not something like boost::pool_allocator but it's a thing that controls memory management at the lowest level. For example I wrote UserAllocator that allocates memory via mmap() function and not uses heap at all.
So to create objects of a type 'Order' you should use boost::pool_allocator or boost::fast_pool_allocator. In your case it is not necessary to use boost::singleton_pool directly.
You can use singleton_pool with placement new like this:
Order* p = new (OrderPool.malloc()) Order(/* add ctor parameters if any*/);
or use boost::object_pool<Order>
Related
The standard C++17 include a new namespace pmr including a set of classes grouped under the name of memory_resource.
After a search on internet, I found very few vulgarized information about it, the direct consequence is this question:
What are the main ideas behind pmr and especially pmr::memory_resource?
Detailing a bit more the question, some of the question marks in my head are:
What does it bring new, or what were the limitations it solve?
What is the difference with allocator?
Does polymorphic mean it is possible to select runtime the allocator provided to a container constructor? (e.g. for testing purpose)
Does it helps for implementing memory pool, or other memory management schemes?
Context:
In the intend of creating a memory pool allocator, I found information about this namespace. Reading names like pool_options or polymorphic_allocator raised my attention.
Related questions:
polymorphic_allocator: when and why should I use it?
A polymorphic_allocator is intended to let you have an allocator whose behavior is dynamically determined at runtime.
The only way to create a polymorphic_allocator is:
Default constructed, in which case it uses std::pmr::get_default_resource() return value, which is a memory_resource*.
Pass it a memory_resource*.
copy from another polymorphic_allocator.
So the point of customization for a polymorphic_allocator is creating a class that inherits from memory_resource and implementing its methods, or using one of the pre-declared memory_resources that are defined in std::pmr: (un)synchronized_pool_resource and monotonic_buffer_resource as types, or std::pmr::new_delete_resource() / std::pmr::null_memory_resource().
Suppose you want a your memory to be allocated using a strategy different than the 5 provided in std::pmr. Then you make a class that inherits from std::pmr::memory_resource, and pass it to a container which uses a polymorphic_allocator.
Imagine a class C that has a member variable m_MyList of type std::vector in which I want to store objects of type MyClass. C has two functions that add or remove objects in m_MyList.
m_MyList should also be made accessible for consumers of C as they need to read the collection of MyClass objects. The external reader of the collection will have no means to change the collection, thus the MyClass objects are owned only by C.
Now my question:
In C++11 style, what is the best T to store in the vector?
The possibilities seem to be:
std::vector<MyClass>
std::vector<MyClass*>
std::vector<unique_ptr<MyClass>>, using std:move to push the unique_ptr into the vector
If the MyClass objects are owned by C, then the best option would be the simplest:
std::vector<MyClass>
The only reason I could see for using std::unique_ptrs here is if you need to keep pointers to a base class for polymorphism. In this case the unique_ptrs serve the purpose of releasing resources upon destruction of the vector. But then the C interface should not transfer ownership to the clients.
Raw pointers (std::vector<MyClass*>) are incorrect if C owns the objects. The other two are pretty similar with the following trade-offs:
std::vector<MyClass> - requires MyClass to be copyable and/or move-able
std::vector<unique_ptr<MyClass>> - requires (additional) dynamic allocations
The kind of operations being performed on the container may also be relevant. To take an extreme example, if MyClass is large and the container is being repeatedly shuffled, unique_ptr would be the better choice.
At the beginning I use std::map, but I need to force the map to deallocate the memory. I use the map only once and has allocated large memory. The map only returns the memory to heap not to OS, so it still existed.
After some google, I found boost.pool, but I have no clear idea on how to implement a map using it, thanks!
Try to use swap trick:
std::map<yourtype> store;
...
// release store's memory
store.swap(std::map<yourtype>());
In swap you will create a temporary instance of map object, swap will swap the contents of the temporary instance and the base instance and the temporary instance will be destroyed.
What if you write a custom allocator and pass that to the map. Your alocator could use clib's malloc and free. I'm pretty sure that's at the OS level.
Your allocator class only needs to implement the methods shown here: http://www.cplusplus.com/reference/std/memory/allocator/
Then when you define your std::map .. pass the allocator class as the 3rd template argument: http://www.cplusplus.com/reference/stl/map/
eg:
std::map<KeyType, ValueType, less<KeyType>, MyAllocator>
This link from this book also has some example code for making your own allocator: http://www.josuttis.com/libbook/memory/myalloc.hpp.html
Warning: I think the reason most allocators don't give memory back to the OS is that it's faster to hold on to it for later, than to give back to OS and get more every time; so you might see some speed inefficiencies.
Edit: Also found this neat looking howto: http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4079
I'd like to use a std::vector to control a given piece of memory. First of all I'm pretty sure this isn't good practice, but curiosity has the better of me and I'd like to know how to do this anyway.
The problem I have is a method like this:
vector<float> getRow(unsigned long rowIndex)
{
float* row = _m->getRow(rowIndex); // row is now a piece of memory (of a known size) that I control
vector<float> returnValue(row, row+_m->cols()); // construct a new vec from this data
delete [] row; // delete the original memory
return returnValue; // return the new vector
}
_m is a DLL interface class which returns an array of float which is the callers responsibility to delete. So I'd like to wrap this in a vector and return that to the user.... but this implementation allocates new memory for the vector, copies it, and then deletes the returned memory, then returns the vector.
What I'd like to do is to straight up tell the new vector that it has full control over this block of memory so when it gets deleted that memory gets cleaned up.
UPDATE: The original motivation for this (memory returned from a DLL) has been fairly firmly squashed by a number of responders :) However, I'd love to know the answer to the question anyway... Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?
The obvious answer is to use a custom allocator, however you might find that is really quite a heavyweight solution for what you need. If you want to do it, the simplest way is to take the allocator defined (as the default scond template argument to vector<>) by the implementation, copy that and make it work as required.
Another solution might be to define a template specialisation of vector, define as much of the interface as you actually need and implement the memory customisation.
Finally, how about defining your own container with a conforming STL interface, defining random access iterators etc. This might be quite easy given that underlying array will map nicely to vector<>, and pointers into it will map to iterators.
Comment on UPDATE: "Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?"
Surely the simple answer here is "No". Provided you want the result to be a vector<>, then it has to support growing as required, such as through the reserve() method, and that will not be possible for a given fixed allocation. So the real question is really: what exactly do you want to achieve? Something that can be used like vector<>, or something that really does have to in some sense be a vector, and if so, what is that sense?
Vector's default allocator doesn't provide this type of access to its internals. You could do it with your own allocator (vector's second template parameter), but that would change the type of the vector.
It would be much easier if you could write directly into the vector:
vector<float> getRow(unsigned long rowIndex) {
vector<float> row (_m->cols());
_m->getRow(rowIndex, &row[0]); // writes _m->cols() values into &row[0]
return row;
}
Note that &row[0] is a float* and it is guaranteed for vector to store items contiguously.
The most important thing to know here is that different DLL/Modules have different Heaps. This means that any memory that is allocated from a DLL needs to be deleted from that DLL (it's not just a matter of compiler version or delete vs delete[] or whatever). DO NOT PASS MEMORY MANAGEMENT RESPONSIBILITY ACROSS A DLL BOUNDARY. This includes creating a std::vector in a dll and returning it. But it also includes passing a std::vector to the DLL to be filled by the DLL; such an operation is unsafe since you don't know for sure that the std::vector will not try a resize of some kind while it is being filled with values.
There are two options:
Define your own allocator for the std::vector class that uses an allocation function that is guaranteed to reside in the DLL/Module from which the vector was created. This can easily be done with dynamic binding (that is, make the allocator class call some virtual function). Since dynamic binding will look-up in the vtable for the function call, it is guaranteed that it will fall in the code from the DLL/Module that originally created it.
Don't pass the vector object to or from the DLL. You can use, for example, a function getRowBegin() and getRowEnd() that return iterators (i.e. pointers) in the row array (if it is contiguous), and let the user std::copy that into its own, local std::vector object. You could also do it the other way around, pass the iterators begin() and end() to a function like fillRowInto(begin, end).
This problem is very real, although many people neglect it without knowing. Don't underestimate it. I have personally suffered silent bugs related to this issue and it wasn't pretty! It took me months to resolve it.
I have checked in the source code, and boost::shared_ptr and boost::shared_array use dynamic binding (first option above) to deal with this.. however, they are not guaranteed to be binary compatible. Still, this could be a slightly better option (usually binary compatibility is a much lesser problem than memory management across modules).
Your best bet is probably a std::vector<shared_ptr<MatrixCelType>>.
Lots more details in this thread.
If you're trying to change where/how the vector allocates/reallocates/deallocates memory, the allocator template parameter of the vector class is what you're looking for.
If you're simply trying to avoid the overhead of construction, copy construction, assignment, and destruction, then allow the user to instantiate the vector, then pass it to your function by reference. The user is then responsible for construction and destruction.
It sounds like what you're looking for is a form of smart pointer. One that deletes what it points to when it's destroyed. Look into the Boost libraries or roll your own in that case.
The Boost.SmartPtr library contains a whole lot of interesting classes, some of which are dedicated to handle arrays.
For example, behold scoped_array:
int main(int argc, char* argv[])
{
boost::scoped_array<float> array(_m->getRow(atoi(argv[1])));
return 0;
}
The issue, of course, is that scoped_array cannot be copied, so if you really want a std::vector<float>, #Fred Nurk's is probably the best you can get.
In the ideal case you'd want the equivalent to unique_ptr but in array form, however I don't think it's part of the standard.
1.) What is the difference between
CArray <SomeClass> collection;
and
CArray <SomeClass,SomeClass> collection;
or even
CArray <SomeClass* ,SomeClass* > collection;
?
2.) While reading some comments on Stackoverflow I came to a note saying "Don't use CArray". Why should CArray not be used?
This:
CArray <SomeClass> collection;
is equivalent to this:
CArray <SomeClass, const SomeClass&> collection;
The second template parameter is used to specify the type through which members are accessed. The template parameters are described in the documentation on MSDN.
This:
CArray <SomeClass* ,SomeClass* > collection;
stores a collection of pointers to objects of type SomeClass, whereas the other two store collections of objects of type SomeClass.
As for why you "shouldn't use it," std::vector, which is part of the C++ language standard, and thus portable, is probably a better choice for most projects. If you have legacy code that uses CArray, then you may need to use it, and there's nothing wrong with that.
The difference is what is stored in the CArray object and how it is stored in the object, whether the CArray elements are objects or pointers to objects of some class.
CArray seems to have a few unexpected behaviors. It has been around for a long time and was designed to fit into the MFC ecosystem. The C++ Standard Template Library vector has much nicer and more generic characteristics especially when dealing with objects other than simple data types.
My experience has been with using CList and CArray with pointers to objects. Doing this they seem to be more predictable though you do need to worry about managing memory.
One issue from looking at the source in afxtempl.h is that when the CArray is made larger through the internal function SetSize(), a memcpy_s() function is used to copy CArray elements from one memory area to another. So you need to be careful about pointers and shallow copying of CArray elements. And since memcpy_s() is used rather than memmove_s() if you are doing something funky with over lapped memory areas, there may be an issue.
This may be why my experience with CArray as a container for pointers to objects seems to work much better.
The interesting thing is it looks like the Append() and Copy() methods use an internal function CopyElements() which performs an element by element assignment and not a memcpy_s() function call. However these methods are used with CArray objects and not with the individual elements.
CArray is derived from CObject which means that the data structure will have all the baggage of CObject. However there are also some good things that CObject brings along in the MFC world like serialization.
It looks like you should use a reference as the second template argument so you should use CArray <SomeClass, SomeClass &> collection; if you are using a class. I ran into problems when I did not do this until I discovered the section Creating an Array List from MFC Collections: The CArray Class.
2) Since CArray reallocates memory when new element is added.