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: us…
Could you elaborate on what it means to "use memory like tape"?
Common Systems Programming Optimizations and Tricks
21–30 of 98 posts
Re: Common Systems Programming Optimizations and Tricks
#22Very 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: us…
Could you elaborate on what it means to "use memory like tape"?
Re: Common Systems Programming Optimizations and Tricks
#23[1] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
Re: Common Systems Programming Optimizations and Tricks
#24Earlier quoted context omitted.
> 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
One of my favorite system programming tricks is to never believe that a "zero cost abstraction" lives up to the name.
And if you're willing to check your optimizations by reading disassembly, tricks like stuffing tag bits into the bottom of aligned pointer values is pretty routine.
Re: Common Systems Programming Optimizations and Tricks
#25Re: Common Systems Programming Optimizations and Tricks
#26The false-sharing macro in the example expands to __attribute__((alligned(/* etc / )) or __declspec(align(/ etc*/). Is there a reason these are preferred over the alignas specifier introduced in C++ 11?
Re: Common Systems Programming Optimizations and Tricks
#27Earlier quoted context omitted.
One of my favorite system programming tricks is to never believe that a "zero cost abstraction" lives up to the name.
Modern optimizing C++ compilers (especially with Link Time Optimization enabled) are pretty amazing and can very often actually achieve that abstraction collapsing.. But, of course, always measure.
Re: Common Systems Programming Optimizations and Tricks
#28The IBM 360 shipped with 32-bit addresses but only 24 bits decoded. "Hey, there's a whole byte up top that nobody's using today, let's put some stuff there!" When they wanted the address space IBM found themselves architecturally hamstrung, and the cost to dig out was significant.
The 128K Macintosh used a 68000; it had 32-bit addresses but only 24 bits were decoded. "Hey, there's a whole byte up top that nobody's using today, let's put some stuff there!" When Apple needed the address space they found themselves hamstrung by pieces of MacOS that did use those bits, and many applications that did, too. The cost to dig out was significant.
It is practically guaranteed that "Hey, there's 16 whole bits up there that nobody's using today" will wind up the same, because this industry just never learns.
You can do things with lower bits and usually get away with it; many systems put GC tags and type bits down there. But those upper address bits do not belong to you.
Re: Common Systems Programming Optimizations and Tricks
#29Re: Common Systems Programming Optimizations and Tricks
#30Instead 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.
That does not hold for Intel x86 architecture chips, which are perfectly happy to have unaligned integers. As for struct members, the alignment is (of course) "implementation defined", which is the fancy way of throwing up your hands and saying "whatever". (Since C++11 we actually have alignas(), which at least gives manual control)
But that sort of trick is only worth it if you are writing a compiler and its runtime, an interpreter, a memory allocator (in particular GCs) or at the very last some sort of high performance library (you would return your "featured pointer" as an opaque type to the user).