Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
What happens when we do push_back with size() == capacity()?
I've heard a lot of opinions regarding this question. Most popular is: when the vector's size reaches its capacity, it allocates a new region of memory, copies the vector to the newly allocated memory, and inserts new value to the vector's end.
But, why do we have to do it? We have a virtual memory mechanism, we can just call realloc(vec.data(), (sizeof(vec::value_type) * vec.size()) * 2). The Allocator will give us a new memory page, and virtual addresses make the memory "consistent", so we don`t have to copy values from the vector.
Do I understand the virtual memory mechanism wrong?
You understand virtual memory mechanism correctly, basically you can create any amount of continuous page-aligned arrays in the proces' virtual memory space and they would be backed by non-contiguous physical memory.
But that is irrelevant to std::vector because std::allocator does not provide any API to take advantage of that, I think some see this as an oversight.
Just be mindful that C++ is not restricted to only architectures supporting virtual memory, although I think it would be an implementation detail of the standard library if it were implemented anyway.
No, you cannot use C realloc because C++ has objects with real lifetimes, everything is not just a blob of bytes that can be freely copied at whim, some special blobs might not like being moved and they will not appreciate it if you force them to.
Yes, if you are dealing with PODs, this would work with a custom::vector, not std::vector based on std::allocator.
There is a paper in works which addresses your concerns and goes beyond realloc, arguing "its day has passed" - P0901 which few days ago received rather positive feedback from the committee.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
It happens relatively often that a function needs additional memory.
In old codes I often encountered that the additional space has to be provided by the caller and passed to the function as a work array. I guess that this leaves more flexibility to the calling function and might improve performance.
On the other hand allocating the memory guarantees that the memory is actually available and also simplifies the interface.
Is there something like a best practice for handling those cases?
In C code it is common to let the caller take care of memory allocation, e.g. strcpy. The problem is that the called function doesn't know how much memory it can actually use. Therefore C has some functions where the caller also can specify a maximum, e.g. strncpy.
In C++ it is common to the let the called function handle memory allocation if needed. For instance vector::push_back. However, C++ still has functions where the caller is responsible, e.g. std::memcpy.
So there is no rule specifying one or the other. However, if possible it seems to be best pratice to let the called function handle memory allocation.
Still there are situations where the caller can get better performance by taking part in the allocation. Example: you call a function passing a (reference to a) vector and the called function will put data into the vector. If the caller knows that there will be added (push_backed) a lot of new elements and the caller knows the approximate number (e.g. 8000 to 10000), the caller can improve performance by reservering 10000 entries in the vector before doing the call. So this is like a joint effort. But the called function will still safely handle cases where more than 10000 entries are needed.
"Old" codes that I've seen that require the caller to allocate memory for work arrays were written (or significant components of them were written) before dynamic memory allocation was a standard part of computing languages. (See Fortran 77, for example.) They weren't doing it because they thought it was good practice so much as that computer science hadn't evolved far enough yet. Unless you're linking to such a library for legacy reasons, dynamic allocation is the better way to go.
Usually if your function needs an array whose length you do not know and that does not have a small maximum size then the right way to go with this would be to use new or malloc and allocate memory on the heap.
Say for example you need to parse a file and read in its contents into an array and you have no idea how long the file is then using a vector<> would be the right way to go. And then when you make a call to push_back() the element you add goes somewhere on the heap.
In "heap or passing work memory" you present a false dichotomy - by far the most common practice is for the called function to use the stack for its "working" memory. Using the stack is faster than dynamic allocation, and ensures deallocation as execution leaves the variable's containing scope, even if due to an exception.
In cases where the called function is preparing a value to return to the caller... that's NOT simply "working" memory and I assume that's not what you're asking about, but FWIW in that situation the callee may wish to decouple the memory from the stack to allow the data's lifetime to outlive its own. That's typically done using dynamic allocation, either implicitly when returning Standard Library containers, or explicitly with new (and hopefully shared pointers).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
Basically, I need a memory pool for fast allocation of small objects. Ideally, I'd like to replace allocations on both the host, and for memory allocated on GPUs with cudaMalloc. I can write my own, and I will if I have to, but I wouldn't mind swapping in one of the solid open-source implementations.
The only issue is that, with cudaMalloc, the memory pool cannot touch the allocated memory. My understanding is that many (all?) of the common memory allocators, like those in the title, store a small amount of metadata in the allocated data. They therefore wouldn't work.
Does anyone know of a memory allocator for which this is not the case?
If all your small allocations are the same size or have a reasonable upper bound, then a fixed size pool allocator is a good pattern.
The idea is that the allocator grabs a big block using the system call then manages its own free list of fixed size blocks within the big block. Allocation is as easy as taking the block at the head of the free list. Deallocation is a little more complicated but can be implemented in different ways depending on your requirements.
It is simple enough to write your own, or if you google C++ fixed size allocator you can find a number of good implementations including boost::pool
Any allocator needs to store some metadata, somewhere. When the allocation need gets simpler, of course, the amount of metadata will decrease.
I think, a normal fixed size allocator will still give you trouble, when I understand your problem right. You have a really special hardware constraint, as much I see.
You could of course use a fixed pool allocator, that does not offer to free single allocations but only free the whole pool. Thus the need to store metadata inside the allocated memory would be eliminated.
Of course you always can implement an allocator that stores the metadata outside the allocated area, by using a different memory region. But most libraries do store the metadata in the allocated area, because it is most convenient for normal architectures.
So the best guess would be to find a fixed pool allocator that does either not offer the functionality to free single allocations or where you can just not use this feature (and thus the allocator does not store any). This of course is only an option, when it would OK for you, to always release whole memory pools instead of single allocations (what is, btw. a good precaution against memory leaks, if it is applicable).
The other alternative of course would be to implement an own allocator, maybe on the basis of a simple allocator that uses as simple metadata as possible.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
well , it's known that GlobalAlloc/GlobalFree/HeapAlloc/HeapFree APIs are managing default heaps or user defined heaps (CreateHeap) , for each heap there are segments each segment has multiple blocks.It's known The Freelist and the lookaside list are managing the free blocks in each heap.
In was reversing a piece of software and I found that is using VirtualAlloc to allocate a big chunk of memory . Basically I cannot say that it's a heap because the chunk was directly allocated from the Virtual address space and it doesn't show any signs of being a heap.
But some routines in the application will setup a custom Freelist which is itself managed by the application and it's used to define and control the free portions of that big chunk allocated using VirtualAlloc.
Can I call this chunk a HEAP as the application has setup a Freelist structure managing it ?
VirtualAlloc can be used with success to implement custom memory managers. I suppose this is what your code might be doing. It might use VirtualAlloc to reserve contiguous large address space, but it initially does not commit it, this means no physical memory is retrieved from system. Free list might point to such non committed address spaces.
VirtualAlloc is actually at the lowest level when it comes to memory management, malloc library might be actually implemented using it.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I see this quote in many books that one of major problems of Arrays in C/C++ is:
Arrays needs a contiguous block of memory
I can't really understand why this feature of Arrays considers a problem? I think compiler can manage and assign correct size to the Array, so what's the problem?
When you consider the case of memory fragmentation, you may not be able to find a free block of memory which meets the size requirements of an entire array.
This is especially easy to see with certain allocation/deallocation schemes where thousands of variable sized objects are quickly allocated and deallocated, which can leave multiple holes in the free memory (depending on the strategy used). At this point, an ill timed allocation of a large object can fail to find any free space.
defragmentations happen within memory and then, when trying to allocate a memory, you may not have the correct size needed.
It's not a problem per say but it means that a contiguous block in memory has to be found to get space for the array. If your memory is very fragmented this may be tricky. That being said it is often very good that arrays have to be continuous because it means that you can have regular memory access and have fewer cache misses, creating cache friendly code.
Now on the other hand there are structures like linked lists which contain pointers to the other elements, this means they can be in different parts of memory and don't have to be continuous but it also means that when you try to access the pointer it may not be cached and thus you have a cache miss delaying the program.
The reason why a contigious block is an important feature is, when you call functions in the operating system, they usually expect the whole buffer being one byte after the other. For your own code it may not be a problem, because the array implementation can encapsulate the access to it, so that multiple smaller chunks could be presented to the outside as if it were ocntigious. Passing that memory to other functions, which don't know about your particular implementation, this no longer holds true.
Another, smaller issue, may be performance when accessing the array.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am developing a C++ application with Qt; involving tremendous number crunching. A large amount of dynamic memory is required for the entire operation. However the requirement is variable depending on a variable set by the user.
In resource monitor I can see that the Commit memory (memory allocated by OS for the exe) keeps on increasing with time as my program creates arrays in dynamic memory. So if I let Windows know beforehand that my exe will use X MB of memory, will this result in improved performance? If yes then how do I do this?
If you have a lot of memory allocations and cpu-intensive process that runs together, you might consider restructuring your program to use some memory pools.
The idea behind memory pool is that you allocate a pool of resources that you will probably need when processing beings, (maps, vectors, or any objects you happen to new very often), and the time you need a new object, you take the first available one from the pool, reset and use it, and when you are done with it you put it back into the pool so that it can be used again later.
This pattern can happen to be faster than continuously use new and delete, but only if your program intensively uses dynamic allocations while it is doing, for example, a minmax search over a huge tree, or something as intensive as that.
So if I let Windows know beforehand that my exe will use X MB of memory, will this result in improved performance? If yes then how do I do this?
I don't think so. The memory your app operates on is virtual and you don't really have a good control on how Windows actually allocates/maps physical memory onto virtual.
But you can try allocating the required amount of memory upfront and then use it as a pool for custom allocators. It may result in some performance hit however.
You can do a large alloc and delete.
char *ptr = new char[50*1024*1024L];
delete[] *ptr;
I doubt if there is going to be any performance difference.