|
|
Am 18.02.2019 um 00:41 schrieb William F Pokorny:
>> BTW, that "flexible array member" feature won't help you speed up
>> things, as it requires dynamic allocation on the heap, which is
>> super-expensive; whatever you allocate on the stack must necessarily
>> have a fixed size.
>
> OK. Surprised the heap allocation is slower than one on the stack. I
> figured the allocation and free mechanisms were more or less the same -
> just being a difference of where in memory it happened. Guess not?
Definitely not.
On the stack, allocation and release only ever happens at the top of the
stack, and the free area is always a single contiguous block; that's
trivial to keep track of: A single pointer to the current start of the
free region (with most CPUs providing a dedicated register for that: the
Stack Pointer), and some means to detect when you're running past the
end of the memory section you have set aside for the stack (typically
done by setting up a "guard page" at the end of the stack, and crying
bloody murder if that guard page is ever accessed).
At least that's the classic stack implementation; new fancy stuff like
split stacks change the picture, but that's why they're slower.
On the heap, release can happen anywhere anytime, and you may end up
with a gazillion separate blocks of free memory you have to keep track
of, test if you can merge any of them, and search through whenever you
need to allocate memory again to find a region of suitable size. "Heap
fragmentation" being the buzzword there.
> Also surprised allocations on the stack have to be of fixed size. Is it
> so on the function call just one allocation can happen on the stack for
> all the dynamic variables in the function?
It's essentially a matter of the programm language used. If you were to
implement a function in assembler, there is nothing stopping you from
advancing the stack pointer by a computed value (which is all that's
necessary to allocate memory on the stack), provided you later make sure
you revert that change to the stack pointer (and also follow some other
conventions; e.g. some conventions require the stack pointer to be
16-byte aligned when invoking some other function).
As a matter of fact, as I just discovered, C99 _does_ support such a
thing; but it's not "flexible array member" but "variable length
arrays"; and they can't be nested in structs, and C++ did not adopt them.
One reason why C++ did not adopt them is some entirely unrelated
fundamental stumbling block rooted in the C++ type concept. But I guess
they might also mess up - or at least complicate - exception handling;
"stack unwinding" would be the buzzword there.
Post a reply to this message
|
|