At last a young guy who goes straight to the point with the foundamentals of real programming, instead of playing around with Python & Co. 👏🏻 BT W I started enjoying your videos with the Clay series. Great job!!!
Thanks! This topic is a bit advanced so it's tricky to find a balance between explaining too little or too much 😅 This is part of a series I'm making, so perhaps by the end I'll be able to construct something like a "skill tree" that you can follow in order from beginner -> advanced
It's a funny idea right? Want to hear something really cursed? Arrays and structs are also technically a type of arena, because all the array items or struct members get allocated / deallocated together 😂
Nice video! I don't agree that stacks are arenas, even if they are similar. Arenas afaiu can store the allocated data in any place (in order of allocation which is in general non-determinstic), and arenas can grow if necessary. Stack frames on the other hand are not only fixed size, the exact location of each object is known at compile time. Maybe you can view them as an extreme specialization of an arena, but then you could just as well say a byte buffer is an arena.
It would be so if programming physics were flat. A request-scoped arena should probably solve 95% of passed reference resolution. A runtime-scoped arena should maintain state-aware constituents. However, in such a physics, threads are antagonists - ok for JS/TS and Python philosophy - not ok for C-like. When trying to solve threads, you end up with Rust again. Although threads might be ambiguous for non-OS-level apps, a process-like simplification is enough - share data, not objects, and thus forget concurrency. That would be true-parallel async. The final physics: [1] async - pseudo-parallel, thus concurrency-safe with object exchange; [2] process - true-parallel with data exchange, thus out of the concurrency scope; [3] threads - true-parallel with shared objects and concurrency; [4] RUSTification.
That's a good question! And the answer is usually: more than you could ever possibly need 😁 Given that "allocation" is just an abstraction over the virtual memory provided by the OS, memory that you allocate won't actually be committed to real, physical memory until you write to it. So if you write a C program that mallocs 100 terabytes of memory but only uses 1 megabyte, only around 1 megabyte of physical memory will actually get used.
@@nicbarkeragain if you don't want to rely on the kernel to smartly allocate the memory, you can allocate a fairly big block, and then if that block fills up, allocate another one elsewhere in memory and have a linked list of blocks essentially, with large block sizes the number of allocations and deallocations will still be quite small
Came here from Clay. Good introduction to the topic, but I can't help myself: it is not true since that in C++ you need to manually remember to deallocate memory. Smart pointers make that a non-issue. RAII, in general, makes that a non-issue in the general case.
idk this doesnt sound like a good advise to me, (talking about c# gc). In general u want to avoid allocating big objects since they are treated in a special way and could cause fragmentation and instead u should focus on implementing small, short lived object that will get gc in their gen0 and cause little to none overhead for the gc.. (take for example an immutable design)
To clarify, this video isn't suggesting that you use an Arena in an environment where there is also a garbage collector 🙂 Arenas are one of the alternatives to a garbage collector in non managed environments, like C / C++ or C# with the garbage collector switched off.
It is not a good advice for C++ either. Arenas forfeit destructors and efficiency gains compared to object pools are negligible. This technique is only applicable to a language without compiler enforced lifetime control.
I don't understand how to manage non-memory resources and prevent reference leaks with arenas. Also, what problem are they trying to solve? Disposal is already automated everywhere but in C. Allocation efficiency is achieved with object pools.
I can only assume that an object pool is another term for arena. If the pool only holds one object type, you have a homogeneous arena. What problem are they trying to solve? Performance: a) One large allocation is faster than many smaller allocations if your program deals with a large volume of allocations (hundreds+). No shortage of articles complaining about the performance impact of many small mallocs vs one large malloc. b) Localization when all the objects you need for your web request (using example from video) are stored close together in the memory arena. These can lead to fewer cache misses. How to prevent reference leaks? You don't use arenas for all memory allocations. I think zig demonstrated an amazing example in game programming, since functions that allocate must take an allocator as an argument (i think i got the right language). Within the scope of a function call, a memory arena is allocated for all the work it needs to do. Any transient functions will receive an allocator against that single memory arena. When the function completes, it frees up the temporary memory (aka arena) it needed. If objects in the arena need to persist, they must be copied out of the arena which would be a nightmare if objects in the arena hold pointers to other objects in the arena.
@charetjc object pools usually have a global lifetime. They preallocate and reuse memory and resources but don't usually force-dispose it. Basically, it is a flyweight pattern - a cached allocator. So, they do not provide a robust localization but are compatible with references. The examples imply manual and explicit decision-making on where to store what, while video suggests arena could be used to relieve programmers from resource management. How is this a relief or optimization or help if it adds a ton of cognitive overhead?
At last a young guy who goes straight to the point with the foundamentals of real programming, instead of playing around with Python & Co. 👏🏻
BT W I started enjoying your videos with the Clay series. Great job!!!
Subbed. High quality video, you have a method of explaining that is very easy to understand.
Thanks! This topic is a bit advanced so it's tricky to find a balance between explaining too little or too much 😅 This is part of a series I'm making, so perhaps by the end I'll be able to construct something like a "skill tree" that you can follow in order from beginner -> advanced
Stack frames are just arenas (but in the stack instead of heap)! 🤯🤯
It's a funny idea right? Want to hear something really cursed? Arrays and structs are also technically a type of arena, because all the array items or struct members get allocated / deallocated together 😂
You have a very good videos dude .... kudos ..
Thanks, I appreciate that!
Yes, this is the way! Cant wait to see more
Don't worry, there's a lot more of these types of videos coming 😁
@@nicbarkeragain hehehee, gained a sub man
@@Oi-mj6dv 😎
Nice video!
I don't agree that stacks are arenas, even if they are similar. Arenas afaiu can store the allocated data in any place (in order of allocation which is in general non-determinstic), and arenas can grow if necessary. Stack frames on the other hand are not only fixed size, the exact location of each object is known at compile time. Maybe you can view them as an extreme specialization of an arena, but then you could just as well say a byte buffer is an arena.
Funnily enough, I agree with you that a byte buffer is an arena 😁
ZIG mentioned let's go boys!
somewhere, Andrew Kelley just sneezed.
It would be so if programming physics were flat. A request-scoped arena should probably solve 95% of passed reference resolution. A runtime-scoped arena should maintain state-aware constituents. However, in such a physics, threads are antagonists - ok for JS/TS and Python philosophy - not ok for C-like. When trying to solve threads, you end up with Rust again.
Although threads might be ambiguous for non-OS-level apps, a process-like simplification is enough - share data, not objects, and thus forget concurrency. That would be true-parallel async. The final physics: [1] async - pseudo-parallel, thus concurrency-safe with object exchange; [2] process - true-parallel with data exchange, thus out of the concurrency scope; [3] threads - true-parallel with shared objects and concurrency; [4] RUSTification.
How do you know how much space to allocate
That's a good question! And the answer is usually: more than you could ever possibly need 😁
Given that "allocation" is just an abstraction over the virtual memory provided by the OS, memory that you allocate won't actually be committed to real, physical memory until you write to it.
So if you write a C program that mallocs 100 terabytes of memory but only uses 1 megabyte, only around 1 megabyte of physical memory will actually get used.
thanks
@@underflowexception you're welcome!
@@nicbarkeragain if you don't want to rely on the kernel to smartly allocate the memory, you can allocate a fairly big block, and then if that block fills up, allocate another one elsewhere in memory and have a linked list of blocks essentially, with large block sizes the number of allocations and deallocations will still be quite small
Came here from Clay. Good introduction to the topic, but I can't help myself: it is not true since that in C++ you need to manually remember to deallocate memory. Smart pointers make that a non-issue. RAII, in general, makes that a non-issue in the general case.
Looking forward to see Implementation in C
I'm going to do a video soon with an in depth explanation of how I use Arenas in C, so stay tuned!
@@nicbarkeragain I will.
so, like. just a struct?
idk this doesnt sound like a good advise to me, (talking about c# gc).
In general u want to avoid allocating big objects since they are treated in a special way and could cause fragmentation and instead u should focus on implementing small, short lived object that will get gc in their gen0 and cause little to none overhead for the gc.. (take for example an immutable design)
To clarify, this video isn't suggesting that you use an Arena in an environment where there is also a garbage collector 🙂 Arenas are one of the alternatives to a garbage collector in non managed environments, like C / C++ or C# with the garbage collector switched off.
It is not a good advice for C++ either. Arenas forfeit destructors and efficiency gains compared to object pools are negligible. This technique is only applicable to a language without compiler enforced lifetime control.
I don't understand how to manage non-memory resources and prevent reference leaks with arenas. Also, what problem are they trying to solve? Disposal is already automated everywhere but in C. Allocation efficiency is achieved with object pools.
I can only assume that an object pool is another term for arena. If the pool only holds one object type, you have a homogeneous arena.
What problem are they trying to solve?
Performance:
a) One large allocation is faster than many smaller allocations if your program deals with a large volume of allocations (hundreds+). No shortage of articles complaining about the performance impact of many small mallocs vs one large malloc.
b) Localization when all the objects you need for your web request (using example from video) are stored close together in the memory arena. These can lead to fewer cache misses.
How to prevent reference leaks?
You don't use arenas for all memory allocations. I think zig demonstrated an amazing example in game programming, since functions that allocate must take an allocator as an argument (i think i got the right language). Within the scope of a function call, a memory arena is allocated for all the work it needs to do. Any transient functions will receive an allocator against that single memory arena. When the function completes, it frees up the temporary memory (aka arena) it needed. If objects in the arena need to persist, they must be copied out of the arena which would be a nightmare if objects in the arena hold pointers to other objects in the arena.
@charetjc object pools usually have a global lifetime. They preallocate and reuse memory and resources but don't usually force-dispose it. Basically, it is a flyweight pattern - a cached allocator. So, they do not provide a robust localization but are compatible with references. The examples imply manual and explicit decision-making on where to store what, while video suggests arena could be used to relieve programmers from resource management. How is this a relief or optimization or help if it adds a ton of cognitive overhead?