4 ms·
>Why would you ever free an object if something else might be pointing at it? Hi, welcome to programming /s This is the crux of the entire issue for high-perf
by xenadu02 9y ago
>Why would you ever free an object if something else might be pointing at it?
Hi, welcome to programming /s
This is the crux of the entire issue for high-performance multi-threaded programs: how to tell when memory can safely be freed without introducing expensive synchronization?
The simple solutions are obvious:
1. Don't share memory
2. Use a lock
The real tricks are in forms of reference counting or garbage collection that avoid taking locks as much as possible. For really high performance you also need to avoid atomic operations and fences as much as possible. A "pause the world" garbage collector is easy (relatively) to get right and you can be confident it will work. Doing a concurrent pauseless GC is another matter entirely. Inserting a memory fence on every write is not great for performance.
For both GC and reference counting schemes weak references are an additional wrinkle. Swift's original weak reference scheme solved this by inverting control and maintaining parallel reference counts: when the last strong reference is released it ran deinit and set a flag in the object header but otherwise left the memory allocated. Only once every weak reference was touched (or itself deallocated) was the memory actually freed. That's trading greater high-water memory usage for performance. (I don't know off-hand why the implementation was changed though).
- smegel 9y ago> 1. Don't share memory 2. Use a lock 3. Have a concept of ownership and make sure all your code follows some basic rules? E.g. if a consumer reads a pointer from a look free queue, it is then responsible for freeing that memory. OP seems to be saying let some other thread free it on some racy assumption that the consumer will be done with it within N nanoseconds. That's not how I would code it.
- haberman 9y agoThe problem is inside the lock-free queue. How do you remove something from a lock-free queue? Usually by reading a pointer to the queue node, then doing a CAS to remove the node from the queue. But another thread can remove that same node and free it before you can do the CAS! If you're just using a lock-free queue, then the hardest part of the problem has been solved for you already. But the person who wrote the lock-free queue had to think about and solve these really tricky problems.
- smegel 9y agoSo how did they solve it?
- haberman 9y agoThere are a number of techniques for solving this: 1. use a GC'd language 2. hazard pointers 3. epoch-based GC 4. collect nodes when a user destroys the structure (user is required to guarantee that destruction is single-threaded). There are probably others.