Live data from Hacker News

Handles Are the Better Pointers (2018)

floooh.github.com

31–40 of 113 posts

Re: Handles Are the Better Pointers (2018)

#31
post #30

Thinking out loud: Since handles refer to offer rather than absolute addresses, this sort of scheme should allow for "serializing" data by memmapping chunks of memory to disk. Obviously, this scheme wouldn't be useful for cross-platform save files, and might not even translate across builds. Still, as long as you have a robust scheme for invalidating data when a new version is deployed, I could see this being useful…

Handles are essentially integer indexes, relative to a base pointer, also implying a certain object size (needed for index multiplication). A nice property therefore is that the base pointer can be different each time the program is started, but the handle stays constant.

So in case that module-private array is mmapped to disk, handles themselves can be serialised, unlike pointers. This can enable quick and easy storage of most of the program state, allowing for a fast recovery afterwards.

Re: Handles Are the Better Pointers (2018)

#32
MacOS 1.0 in 1984 used handles in order to allow the heap to be coalesced more easily (although locked handles and regular pointers often created islands). Given the first Mac had 128K RAM and no MMU, it was highly necessary at the time.

Re: Handles Are the Better Pointers (2018)

#34

Moving away from pointers and using a shared pool of handles with integer indexes will introduce a whole new array of issues. A plain int carries no information about the validity of the object behind that handle because they are carried around as copies, not references. I remember debugging a regression with UNIX network sockets where valid connections were being killed, and the bug was only triggered under heavy lo…

> A plain int carries no information about the validity of the object behind that handle because they are carried around as copies, not references. A pointer is just an integer index to a byte in memory in most computing architectures.

A pointer is an absolute locator of a byte in the address space of a process, while an integer index implies a certain base (start of the module-private array) and a multiplier (object size).

By using handles, "user code" is freed from having to know the base and the multiplier, which allows for a more compact locator that remains constant in case of base/multiplier changes.

Re: Handles Are the Better Pointers (2018)

#35

Earlier quoted context omitted.

In C world yes, in C++ world no, because of weak_ptr.

Weak_ptr in C++ only applies to shared_ptr, which is not used for most C++ pointers. Because of the atomic ops done on each copy, in performance sensitive contexts people aren't going to be using it.

Been there, done that.

I was writing an interpreter using shared ptrs all over the place.

Performance was fine until I linked pthreads, at which point it took a nosedive forcing me to refactor the entire project.

No one really tells you this. People will say don't use shared ptrs because they're slow, which is far from the whole truth. They're pretty darn fast as long as you don't enable threading.

Re: Handles Are the Better Pointers (2018)

#36

MacOS 1.0 in 1984 used handles in order to allow the heap to be coalesced more easily (although locked handles and regular pointers often created islands). Given the first Mac had 128K RAM and no MMU, it was highly necessary at the time.

Yes, and could be a huge pain to develop in. We always wrapped the handles in library calls to assert them, which minimized problems.

Ideas are in a wheel, same ones always coming around again.

Re: Handles Are the Better Pointers (2018)

#37
post #12

Earlier quoted context omitted.

Object pools pale in comparison to striping the data into arrays (or as we call it in the game dev world a Struct of Arrays) when it comes to reduced cache misses.

Given that you iterate over the object fields in a "column like" manner, right? Random access should be slower since an object of say four elements would have to fetch four cache lines.

You're more likely to have the next object cached by the time you access it compared to separate allocations.

The more sequential the access pattern is and the smaller the objects are, the greater benefit.

Re: Handles Are the Better Pointers (2018)

#39

Earlier quoted context omitted.

> A plain int carries no information about the validity of the object behind that handle because they are carried around as copies, not references. The article suggests a handle containing a "plain int" plus a "unique bit pattern", the latter acting like a watermark which is compared to the one in the private array of the corresponding module, preventing dangling accesses. Apart from rare occasional collisions in the…

You are essentially passing an database index key to the getter-function. The only issue I see is that your system has a database integrated into it.

That's probably not a bad way to think about it - in an application that large, dealing with lots of data, needing high performance, it is effectively an application-specific database.

Re: Handles Are the Better Pointers (2018)

#40
post #35

Earlier quoted context omitted.

Weak_ptr in C++ only applies to shared_ptr, which is not used for most C++ pointers. Because of the atomic ops done on each copy, in performance sensitive contexts people aren't going to be using it.

Been there, done that. I was writing an interpreter using shared ptrs all over the place. Performance was fine until I linked pthreads, at which point it took a nosedive forcing me to refactor the entire project. No one really tells you this. People will say don't use shared ptrs because they're slow, which is far from the whole truth. They're pretty darn fast as long as you don't enable threading.

I would go a step farther and say that uncontended shared_ptrs are typically fine. The problem comes in when you have shared_ptrs that are frequently copied in more than one thread. That requires synchronizing the shared state across cores, sometimes across NUMA nodes. That's slow.

The same thing goes for mutexes. Modern, uncontended mutexes are very fast. But they can start sucking resources when you're locking them from multiple threads at the same time.

Post reply on HN