intrigued_66
intrigued_66

Reputation: 17220

Increase stack size to use alloca()?

This is two questions overlapping- I wish to try out alloca() for large arrays instead of assigning dynamically-sized arrays on the heap. This is so that I can increase performance without having to make heap allocations. However, I get the impression stack sizes are usually quite small? Are there any disadvantages to increasing the size of my stack so that I can take full advantage of alloca()? Is it The more RAM I have, the larger I can proportionally increase my stack size?

EDIT1: Preferably Linux

EDIT2: I don't have a specified size in mind- I would rather know how to judge what determines the limit/boundaries.

Upvotes: 5

Views: 2739

Answers (4)

Billy ONeal
Billy ONeal

Reputation: 106530

Stack sizes are (by default) 8MB on most unix-y platforms, and 1MB on Windows (namely, because Windows has a deterministic way for recovering from out of stack problems, while unix-y platforms usually throw a generic SIGSEGV signal).

If your allocations are large, you won't see much of a performance difference between allocating on the heap versus allocating on the stack. Sure, the stack is slightly more efficient per allocation, but if your allocations are large the number of allocations is likely to be small.

If you want a larger stack-like structure you can always write your own allocator which obtains a large block from malloc and then handles allocation/deallocation in a stack-like fashion.

#include <stdexcept>
#include <cstddef>

class StackLikeAllocator
{
    std::size_t usedSize;
    std::size_t maximumSize;
    void *memory;
public:
    StackLikeAllocator(std::size_t backingSize)
    {
        memory = new char[backingSize];
        usedSize = 0;
        maximumSize = backingSize;
    }
    ~StackLikeAllocator()
    {
        delete[] memory;
    }
    void * Allocate(std::size_t desiredSize)
    {
        // You would have to make sure alignment was correct for your
        // platform (Exercise to the reader)
        std::size_t newUsedSize = usedSize + desiredSize;
        if (newUsedSize > maximumSize)
        {
            throw std::bad_alloc("Exceeded maximum size for this allocator.");
        }

        void* result = static_cast<void*>(static_cast<char*>(memory) + usedSize);
        usedSize = newUsedSize;
        return result;
    }

    // If you need to support deallocation then modifying this shouldn't be
    // too difficult
}

Upvotes: 10

Alexey Frunze
Alexey Frunze

Reputation: 62048

The default stack size that the main thread of a program gets is a compiler-specific (and/or OS-specific) thing and you should see the appropriate documentation to find out how to enlarge the stack.

It may happen that you may be unable to enlarge the program's default stack to an arbitrarily large size.

You may, however, as it's been pointed out, be able to create a thread at run time with a stack of the size you want.

In any event, there's not much benefit of alloca() over a once allocated large buffer. You don't need to free and reallocate it many times.

Upvotes: 4

Johannes Overmann
Johannes Overmann

Reputation: 5131

The most important difference between alloca() and new / malloc() is that all memory allocated with alloca() will be gone when you return from the current function.

alloca() is only useful for small temporary data structures.

It is only useful for small data structures since big data structures will destroy the cache locality of your stack which will give you a rather big performance hit. The same goes for arrays as local variables.

Use alloca() only in very specific circumstances. If unsure, do not use it at all.

The general rule is: Do not put big data structures (>= 1k) on the stack. The stack does not scale. It is a very limited resource.

Upvotes: 3

Mark Wilkins
Mark Wilkins

Reputation: 41232

To answer the first question: The stack size is typically small relative to the heap size (this would hold true in most Linux applications).

If the allocations you are planning are large relative to the actual default stack size, then I think it would be better to use dynamic allocation from the heap (rather than trying to increase stack sizes). The cost of using the memory (filling it, reading it, manipulating it) is probably going to far exceed the cost of the allocation. It is unlikely that you would see a measurable benefit by allocating from the stack in this scenario.

Upvotes: 2

Related Questions