Live data from Hacker News

Handles Are the Better Pointers (2018)

floooh.github.com

1–10 of 113 posts

Re: Handles Are the Better Pointers (2018)

#3
I am surprised that not every large project uses this technique. If you are running on a 64bit system, the use of 32bit handles instead of pointer results in huge memory savings. You can also put the start addressed of the arrays (the handles are indexing into) anywhere in virtual memory and grow them as needed. Finally you can stripe the data for one object into multiple arrays and use the same handle to index each of them which can improve locality.

Re: Handles Are the Better Pointers (2018)

#4

I am surprised that not every large project uses this technique. If you are running on a 64bit system, the use of 32bit handles instead of pointer results in huge memory savings. You can also put the start addressed of the arrays (the handles are indexing into) anywhere in virtual memory and grow them as needed. Finally you can stripe the data for one object into multiple arrays and use the same handle to index each…

I don't know. The hugest saving from not malloc-ing small objects comes from the memory-chunk overhead I believe. You could do object pools and still use pointer as usual I think with no runtime cost of passing handles to getter-functions. The usual pattern of "wrapping" malloc/free.

Re: Handles Are the Better Pointers (2018)

#5

I am surprised that not every large project uses this technique. If you are running on a 64bit system, the use of 32bit handles instead of pointer results in huge memory savings. You can also put the start addressed of the arrays (the handles are indexing into) anywhere in virtual memory and grow them as needed. Finally you can stripe the data for one object into multiple arrays and use the same handle to index each…

> you can stripe the data for one object into multiple arrays and use the same handle to index each of them which can improve locality.

I wish programming languages made it easy to structure arrays of objects like this. I think Johnathan Blows’s JAI has some kind of transparent support for SoA.

Re: Handles Are the Better Pointers (2018)

#7
There should be a minor law in the spirit of Greenspun’s tenth rule: Every sufficiently performance-sensitive system eventually grows some version of a slab allocator[1].

There’s really no substitute for packing fixed-sized objects together in N big array chunks. If you can operate in a particular context (or entirely) with N=1, you can substitute handles for pointers. For any reasonable # of objects, those handles can be smaller than a pointer and provide even better compaction and thus cache effectiveness.

[1] https://people.eecs.berkeley.edu/~kubitron/courses/cs194-24-...

Re: Handles Are the Better Pointers (2018)

#8

I am surprised that not every large project uses this technique. If you are running on a 64bit system, the use of 32bit handles instead of pointer results in huge memory savings. You can also put the start addressed of the arrays (the handles are indexing into) anywhere in virtual memory and grow them as needed. Finally you can stripe the data for one object into multiple arrays and use the same handle to index each…

I don't know. The hugest saving from not malloc-ing small objects comes from the memory-chunk overhead I believe. You could do object pools and still use pointer as usual I think with no runtime cost of passing handles to getter-functions. The usual pattern of "wrapping" malloc/free.

What about CPU data cache misses due to the fact that malloc doesn't have a concept for how best to organize that data chunk of data based on your application's specific usage pattern?

Re: Handles Are the Better Pointers (2018)

#10
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 load. Deadlines were approaching and as a desperate measure I did the exact opposite the article suggests: I wrapped all the socket calls to only accept pointers to an opaque struct with a single integer and made sure the int was set to a guardian value to indicate invalidation after an error. The culprit was a double-close that normal debugging tools such as Valgrind could not find but my unorthodox refactoring did.

Later I've learnt to love UUID's whenever performance allows. They're not pointers so they don't introduce memory handling issues and they can be easily tracked in e.g. distributed data pipelines and logging systems.

Post reply on HN