Ask HN: Going low-level – what to learn next?
I've been interested in (relatively) low-level programming for quite some time. I know C, I can read assembly (write - not so much) and I have basic understanding of CPU (registers, cache, stack and whatnot). What should I read or learn next to be able to reason about things like cache usage of a C program or possible low-level microoptimizations?
It's still just a hobby for me for the most part, so it's not that I'm trying to prematurely optimize some production code. I'm just interested in how it all works under the hood.
58 comments
[ 4.3 ms ] story [ 112 ms ] threadhttps://wiki.osdev.org/ is a good source for getting a hold in OS development
http://asmirvine.com/index.htm
At least that's my experience :-).
[0] https://handmade.network
[1] https://handmadecities.com
I've recently enjoyed Game Engine Architecture, mostly because there is an interesting mix using low level techniques to solve problems a normal application wouldn't be required to fix.
Game development in general is case for tuning yourself to when you should utilize high level programming techniques, and when required dropping into low level optimization to solve local problems.
Learn how to use a profiler like Linux' perf, VTune or Apple's Instruments. Which means interpreting the results of it to optimise your code.
This comes to mind: https://www.morling.dev/blog/one-billion-row-challenge/
Read how others have done it. Here's an example in Java that goes relatively low-level to squeeze out performance: https://questdb.io/blog/billion-row-challenge-step-by-step/
Also, learn Rust.
It doesn't really matter what it is, it could be porting FeeeRTOS to your toaster, writing a kernel driver for something, reversing some device protocol, implementing something on an FPGA or building some embedded device or hacking another one into something else. Just get stuck into something and feel the gravity of your open interests.
Nothing you learn along the way will be a waste.
Learning Lua is a great way to get introduced to a lot of low-level concepts, from bytecode to VM's to language design and beyond.
Its just such a great tool, please don't deny yourself this wonderful experience. Get the VM, put it in something - or find a VM somewhere in something already, and have a lot of fun. And don't forget to make sure you know what a sparse array is, and why pairs() and why ipairs() .. you'll be glad you did!
PS - don't fall for the hype, you can do someTable[0] = "first", someTable[1] = "second" all you like .. :)
Some simple things you can do:
* Get yourself a suitable embedded development system - I would recommend anything ESP32'ish that suits your fancy such as a Liligo or Watchy ESP32-based watch, or PineTime if thats more up your alley - and then write some little apps for it.
* Get to know Godbolt with a great deal of intimacy, just as a general approach to understanding what is going on:
https://godbolt.org/
* Invest a little workbench time in some of the various embedded frameworks out there - platformio, FreeRTOS, etc. and, very important: learn the Tooling And Methodology techniques that these frameworks manifest.
* Invest some workbench time in the RETRO Computing Scene. Seriously, you can still learn extremely valuable principles of tooling and methodology from an 8-bit retro system from the 80's. Get your favourite platform, get all its tools onboard, engage with its community - you will learn a lot of things that are still entirely relevant, in spite of the changes over the decades.
* Get into the F/OSS tooling/methdology flow - find software projects that are interesting to you, find their repositories, learn to clone and build and test locally, and so on. There are so many fantastic projects out there for which low-level skills can be developed/fostered. Get onboard with something that interests you.
Good luck!
https://www.computerenhance.com/p/table-of-contents
Learn how it works, try adding a new instruction or implementing an extension.
I learned assembly so I could disassemble and understand programs.
I learned C so I could use all the libraries that people had made and their frameworks than later because C++, Objective C, C#, java, python and other derivatives.
I wanted to manipulate images, speech and video and using high level programming language was so inefficient so I continued using C.
I learned FPFGAs again because I needed efficiency or the things I wanted to do like controlling robots did not work at all(they moved so sluggishly).
I love learning things, but that was never enough for me to learn something deeply when problems appear.
My suggestion would be to find something that can be improved on in daily life and then learn the skills necessary to make that improvement, to include the trades more physical in nature, such as woodworking, 3D printing, etc. Then, combine those skills with, say, programming embedded devices, etc. or whatever else is needed to accomplish the task.
This ultimately provides a diverse skill-set, feeds the desire to learn, and provides legitimate improvements to quality of life - both tangible and intangible.
https://sysprog21.github.io/lkmpg/
https://blog.sourcerer.io/writing-a-simple-linux-kernel-modu...
If you want to "go low" in the way hardware works, you could try and write an interrupt handler on an embedded device.
If you want to "go low" in how optimizations work in application development, you could try and implement microbenchmarks and look at flamegraphs.
https://github.com/brendangregg/FlameGraph
https://bheisler.github.io/criterion.rs/book/index.html
1. The best source of low-level information on things like operating systems (writing your own) etc is https://wiki.osdev.org/Expanded_Main_Page
2. Compiler related low-level should include a read through Crafting Interpreters (https://craftinginterpreters.com/), even if all you're going to do is create compiled languages.
3. Hardware type low-level (where you build your own logic) is a long and ultimately non-rewarding path. I would suggest https://eater.net/8bit/
All those links are only starting points; use them to find a direction in which to head.
[EDIT: I also recommend writing a eBPF module for linux - easier than writing a kernel module, with just as much low-level hooks as you might need].
eBPF is great for some things and is "easier" for some things but kernel modules are able to do _way_ more by design.