Live data from Hacker News

Common Systems Programming Optimizations and Tricks

paulcavallaro.com

1–10 of 98 posts

Re: Common Systems Programming Optimizations and Tricks

#2
Good article. Basics that everyone can benefit from knowing.

Just one nit/warning... breaking coarse locks into fine-grained locks can be taken too far. There is a point of diminishing returns where you end up spending increased time acquiring/releasing/waiting-for locks. At some point you want to clump together under a single lock resources that tend to often be used together, even if you often end up locking an extra resource or two unnecessarily. As always, benchmark workloads are your friends.

Re: Common Systems Programming Optimizations and Tricks

#4
post #2

Good article. Basics that everyone can benefit from knowing. Just one nit/warning... breaking coarse locks into fine-grained locks can be taken too far. There is a point of diminishing returns where you end up spending increased time acquiring/releasing/waiting-for locks. At some point you want to clump together under a single lock resources that tend to often be used together, even if you often end up locking an ext…

Taken to the extreme, ONE lock in Python. :)

Re: Common Systems Programming Optimizations and Tricks

#6
post #3

Instead of repurposing top bits you can also repurpose the Bits beyond alignment. E.g 32 bit integers are aligned to 4 bytes, so you can use the lower two bits of pointers to them instead.

As someone who's worked on old Macs and has also done lots of 32 -> 64-bit porting, this is the sort of trick that works wonderfully...until it doesn't. And then you've got a nightmare on your hands.

I'm not saying never do that (ok, maybe I am...) But definitely think long and hard about how long your code will be around before you do it.

Re: Common Systems Programming Optimizations and Tricks

#7
post #3

Instead of repurposing top bits you can also repurpose the Bits beyond alignment. E.g 32 bit integers are aligned to 4 bytes, so you can use the lower two bits of pointers to them instead.

As someone who's worked on old Macs and has also done lots of 32 -> 64-bit porting, this is the sort of trick that works wonderfully...until it doesn't. And then you've got a nightmare on your hands. I'm not saying never do that (ok, maybe I am...) But definitely think long and hard about how long your code will be around before you do it.

> As someone who's worked on old Macs and has also done lots of 32 -> 64-bit porting, this is the sort of trick that works wonderfully...until it doesn't. And then you've got a nightmare on your hands.

That's why you hide the trick behind a zero-cost abstraction which checks at compile-time if the platform supports this

Re: Common Systems Programming Optimizations and Tricks

#8
post #4
post #2

Good article. Basics that everyone can benefit from knowing. Just one nit/warning... breaking coarse locks into fine-grained locks can be taken too far. There is a point of diminishing returns where you end up spending increased time acquiring/releasing/waiting-for locks. At some point you want to clump together under a single lock resources that tend to often be used together, even if you often end up locking an ext…

Taken to the extreme, ONE lock in Python. :)

I know this is a joke, but you still need locks in Python

Re: Common Systems Programming Optimizations and Tricks

#9
post #8
post #4

Earlier quoted context omitted.

Taken to the extreme, ONE lock in Python. :)

I know this is a joke, but you still need locks in Python

Theoretically not necessarily the referenced GIL, though. There are conceptually alternative models; see Microsoft doc[0] on apartment threading model, or Tcl[1].

[0] https://docs.microsoft.com/en-us/windows/win32/com/processes...

[1] https://stackoverflow.com/questions/45799121/runtimeerror-ca...

Re: Common Systems Programming Optimizations and Tricks

#10
Very good article, facts looked correct and it had useful advice.

I'd add, keep things local. Don't access memory (or cache) outside core (L1 & L2), NUMA region or processor socket boundary unnecessarily.

Keep networking, GPU, etc. code in same NUMA region where the physical adapters are.

Use memory like tape, stream through. CPU branch predictors love that kind of access pattern.

Oh, and perhaps most importantly: use a profiler that can access CPU internal performance counters. Do this on different system types, from low power laptops to servers with 2 or more CPU sockets.

One annoying thing, though. Remember that the fastest thing in a microbenchmark might not be the fastest thing on a real system when different code modules fight for shared limited resources, like memory bandwidth, caches and inter-core communication links.

Post reply on HN