Array based stack memory efficiency - vector

I know that a stack can be implemented by dynamic array (e.g. std::vector in c++) or linked list.
When the stack is implemented based on dynamic array, the capacity will grow automatically the new item is push into the stack. I'm wondering that when pop out items from stack, will the capacity of the array decrease?
In some applications (e.g path search algorithms), many items will be pushed into the stack first and then pop out. The program ends when the stack is empty. If the capacity of the array didn't decrease, I will have a large empty array when my program ends.

std::stack uses std::deque as container. It's resized as required, both up and down.

Related

Lock free non-allocating collection

I am looking for a collection data structure that is:
thread safe
lock free
non-allocating (amortized or pre-allocated is fine)
non-intrusive
not using exotic intrinsics
Element order does not matter. Stack, queue, bag, anything is fine. I have found plenty of examples that fulfill four of these five requirements, for example:
.NET's List is not thread safe.
If I put a mutex on it, then it's not lock free.
.NET's ConcurrentStack is thread safe, lock free, uses a simple CompareExchange, but allocates a new Node for each element.
If I move the next pointer from the Node to the element itself, then it's intrusive.
Array based lock free data structures tend to require multi-word intrinsics.
I feel like I'm missing something super obvious. This should be a solved problem.
.NET's ConcurrentQueue fulfills all five requirements. It does allocate when the backing storage runs out of space, similar to List<T>, but as long as there is extra capacity, no allocations occur. Unfortunately the only way to reserve extra capacity upfront, is to initialize it with a collection of same size and then dequeuing all the elements.
same is true for .NET's ConcurrentBag

Why is the kernel stack for a unix process placed in the dynamic portion of context

I am reading this book, and in the chapter "The structure of process", while talking about the context of a process, it divides the context iun 2 portions. The static and the dynamic portion. It says that every process has a user stack and a kernel stack, and the kernel stack is placed on the dynamic portion of the context.
The dynamic part of the system-level context of a process consists of a set layers, visualized as a last-in-first-out stack.
and while defining a figure,
The right side of the figure shows the dynamic portion of the context. It consists of several stack frames, where each frame contains the saved register context of the previous layer, and the kernel stack as the kernel executes in that layer.
So, while the user space stack is placed in the static portion of the context, is there any particular reason for the kernel stack to be placed in the dynamic portion?
For me each process has it's static, and dynamic context. For kernel context reference to last dynamic part must be stored in it's static context. That way system can get access to dynamic part. Please look here.
That dynamic context is needed since kernel, and user lands are separated. It can be required to call kernel land, and get back to user land, back and forth. To track that system uses that dynamic part of process context.

Dilemma related to function call's increment of SP

In case of push during function call, why the stack pointer moves to a
smaller value by subtracting 4 times the number of registers to be
pushed on the stack?
I got this while reading Understanding the stack
In the same page, it is clearly mentioned about the memory layout of stack :-
It's useful to think of the following aspects of a stack.
stack bottom The largest valid address of a stack. When a stack is initialized, the stack pointer points to the stack bottom.
stack limit The smallest valid address of a stack. If the stack pointer gets smaller than this, then there's a stack overflow (this
should not be confused with overflow from math operations).
Other sections of memory are used for the program and for the heap
(the section of memory used for dynamic memory allocation).
And, talking about the PUSH operation, subtracting 4 times the number of registers to be pushed on the stack is needed because in MIPS architecture, addresses of sequential words differ by 4. And, the registers are 32 bits(4 bytes) for MIPS I instruction set architecture (ISA) and II ISA.
For our stack of 4-byte (full word) data, adding an item means subtracting four from $sp and storing the item in that address.
Here is what that looks like in code. Say that the value to push on the stack is in register $t0:
# PUSH the item in $t0:
subu $sp,$sp,4 # point to the place for the new item,
sw $t0,($sp) # store the contents of $t0 as the new top.
And, so, you can push one or more registers, by setting the stack pointer to a smaller value (usually by subtracting 4 times the number of registers to be pushed on the stack) and copying the registers to the stack.

Scheduling tool with callbacks

I try to develop amateur web games (just for fun) and I'm looking for a tool that allows me to (with a use case) :
Enqueue items in a system, with a finish_at property. Typically, it would be used for the units production queue ;
Be able to alter the finish_at property of an item. Eh, if the frostwyrm attacks the barrack, its production is temporarily stopped ;
Be able to setup callback on the progression (at given percentages). When a player builds a Wonder, I want to notify his ennemies about the progress ;
Do you know such a tool ? If you don't, what technologies can you recommend to me in order to built that ?
Thanks a lot !
I'd go for a doubly linked list, where each node can be a member of multiple different lists at the same time:
struct node
{
struct node *factory_prev;
struct node *factory_next;
struct node *finish_prev;
struct node *finish_next;
struct node *progress_prev;
struct node *progress_next;
};
The first list links all the items produced by this factory; the list base is with the factory object. When the factory is attacked, you can walk this list to find all items that are now delayed, so you can take them out of the other lists.
The second list links all items being produced, ordered by the time they are finished. Looking at the first element can tell you in O(1) whether an item is finished.
The third list links all items that broadcast progress events, again sorted by when the next such event occurs. This mechanism is very similar to the "finish" list and could theoretically be merged, however having a separate, shorter list allows you to find the items that need progress broadcasts faster.
As these are doubly linked lists, as soon as you have a pointer to a node you know how to unlink it from all other lists as well. Be aware that in a multithreaded program you might need some form of locking still.
The alternative would be to reschedule items that have been delayed at the time when they would ordinarily have been produced; this is however pretty difficult to get right for items that also have progress reports.

OutOfMemoryException

I have an application that is pretty memory hungry. It holds a large amount of data in some big arrays.
I have recently been noticing the occasional OutOfMemoryException. These OutOfMemoryExceptions are occurring long before my application (ASP.Net) has used up the 800mb available to it.
I have track the issue down to the area of code where the array is resized. The array contains a structure that is 74bytes in size. (I know that you shouldn't create struct's that are bigger than 16bytes), but this application is a port from a Vb6 application). I have tried changing the struct to a class and this appears to have fixed the problem for now.
I think the reason that changing to a class solves the problem has to do with the fact that when using a struct and the array is resized, a segment of memory that is large enough to store the new array needs to be reserved (e.g. (currentArraySize + increaseBySize)*74) cannot be found. This leads to the OutOfMemoryException.
This isn't the case with a class as each element of the array only needs 8bytes to store a pointer to the new object.
Is my thinking correct here?
Your assumptions regarding how arrays are stored are correct. Changing from struct to class will add a bit of overhead to each instance and you'll loose the advantages of locality as all data must be collected via a reference, but as you have observed it may solve your memory problem for now.
When you resize an array it will create a new one to hold the new data, then copy over the data, and you will have two copies of the same data in memory at the same time. Just as you expected.
When using structs the array will occupy the struct size * number of elements. When using a class it will only contain the pointer.
The same scenario is also true for List which increase in size over time, thus it's smart to initialize it with the expected number of items to avoid resizing and copying.
On 32bit systems you will hit outofmem around ~800mb, as you are aware of. One solution you can try is to but your structs on disk and read them when needed. Since they are a fixed size you can easily jump into the correct position at the file.
I have a project on Codeplex for handling large amounts of data. It has a type of Array with possibility for autogrowing, which might help your scenario if you run into problems with keeping it all in memory again.
The issue you are experiencing might be caused by fragmentation of the Large Object Heap rather than a normal out of memory condition where all memory really is used up.
See http://msdn.microsoft.com/en-us/magazine/cc534993.aspx
The solution might be as simple as growing the array by large fixed increments rather than smaller random increments so that as arrays are freed up the blocks of LOH memory can be reused for a new large array.
This may also explain the struct->class issue as the struct is likely stored in the array itself while the class will be a small object on the small object heap.
The .NET Framework 4.5.1, has the ability to explicitly compact the large object heap (LOH) during garbage collection.
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
See more info in: GCSettings.LargeObjectHeapCompactionMode
And a question about it: Large Object Heap Compaction, when is it good?

Resources