Live data from Hacker News

Ask HN: What should a systems/low-level software engineer know?

news.ycombinator.com

151–160 of 231 posts

Re: Ask HN: What should a systems/low-level software engineer know?

#152

I'm an embedded software engineer. Here's my $0.02 on how to get started: 1. Get a platform you can tinker around with, and recover quickly in case of disaster. Raspberry pi is a good example. 2. Learn how to find and read detailed register-level manuals of the underlying chip you're working on. 3. Learn what a programmer's memory-model is. 4. Learn what peripherals are, and what they do. You may have to dig a bit in…

> 1. Get a platform you can tinker around with, and recover quickly in case of disaster. Raspberry pi is a good example. I'd recommend something cheaper and simpler like the STM32F4 discovery boards. You won't get linux and will have to program via JTAG but the documentation for the STM32F4 is not as overwhelming as Broadcom's.

Does knowledge of the STM32 family apply to other ARM chips?

Re: Ask HN: What should a systems/low-level software engineer know?

#153
post #56

From the top of my head, these are some areas I often would like other system programmers to know better: - Understanding how to write purely event-based programs using e.g. epoll since that will avoid lots of complexity and potential problems compared to throwing threads at everything. - Floating point representation and gotchas ("What Every Computer Scientist Should Know About Floating-Point"). - Unit-testing as pa…

Maybe it is just me, but I've seen this issue multiple times where a programmer used a regular expression thinking they were clever, only to have it backfire later when there was some corner case not covered by their regex (which likely would have obviously been caught if they had just taken the time to write out each case as an if statement). You're usually just gaining complexity in exchange for fewer lines of code…

There’s a fine line between being clever and being a smartass.

Re: Ask HN: What should a systems/low-level software engineer know?

#154
A systems programmer will specialize in subdomains much like any other programmer, but there are some characteristic skills and knowledge that are common across most of them. Systems programmer coding style is driven by robustness, correctness, and performance to a much greater degree than higher up the stack. Most systems programming jobs these days is C/C++ on Linux and will be for the foreseeable future.

- Know how your hardware actually works, especially CPU, storage, and network. This provides the "first principles" whence all of the below are derived and will allow you to reason about and predict system behavior without writing a single line of code.

- Understand the design of the operating system well enough to reimplement and bypass key parts of it as needed. The requirements that would cause you to to build, for example, a custom storage engine also means you aren't mmap()-ing files, instead doing direct I/O with io_submit() on a file or raw block device into a cache and I/O scheduler you designed and wrote. Study the internals of existing systems code for examples of how things like this are done, it is esoteric but not difficult to learn.

- Locality-driven software design. Locality maximization, both spatial and temporal, is the source of most performance in modern software. In systems programming, this means you are always aware of what is currently in your hardware caches and efficiently using that resource. As a corollary, compactness is consistently a key objective of your data structures to a much greater extent than people think about it higher up the stack. One way you can identify code written by systems programmer is the use of data structures packed into bitfields.

- Understand the difference between interrupt-driven and schedule-driven computing models, the appropriate use cases for both, and how to safely design code that necessarily mixes both e.g. multithreading and coroutines. This is central to I/O handling: network is interrupt-driven and disk is schedule-driven. Being explicit about where the boundaries are between these modes in your software designs greatly simplifies reasoning about concurrency. Most common concurrency primitives make assumptions about which model you are using.

- All systems are distributed systems. Part of the systems programmers job is creating the illusion that this is not the case to the higher levels in the stack, but a systems programmer unavoidably lives in this world even within a single server. Knowing "latencies every programmer should know" is just a starting point, it is also helpful to understand how hardware topology interacts with the routing/messaging patterns to change latency -- tail latencies are more important than median latencies.

The above is relatively abstract and conceptual but generalizes to all systems programming. Domains of systems programming have deep and unique knowledge that is specific to the specialty e.g. network protocol stacks, database engines, high performance graphics, etc. Because the physics of hardware never changes except in the details, the abstractions are relatively thin, and the tool chains are necessarily conservative, systems programming skills age very well. The emergence of modern C++ (e.g. C++17) has made systems programming quite enjoyable.

Also, the best way to learn idiomatic systems programming is to read many examples of high-quality systems code. You will see many excellent techniques in the code that you've never seen before that are not documented in book/paper form. I've been doing systems work for two decades and I still run across interesting new idioms and techniques.

Re: Ask HN: What should a systems/low-level software engineer know?

#155

Earlier quoted context omitted.

> 1. Get a platform you can tinker around with, and recover quickly in case of disaster. Raspberry pi is a good example. I'd recommend something cheaper and simpler like the STM32F4 discovery boards. You won't get linux and will have to program via JTAG but the documentation for the STM32F4 is not as overwhelming as Broadcom's.

Does knowledge of the STM32 family apply to other ARM chips?

Yes and no. Some of the general part features will be familiar (in the sense that an ARM Cortex M[X] is the same as any other Cortex M[X].

In reality every vendor's peripherals, and more importantly HAL and associated drivers and libs, will be different. But if you've done it once learning another vendor's way of life is a bit like learning a new programming language; it's just syntax.

Broadly most (IE communication, ADC, watchdog, etc) peripherals will be similar but there are definitely places where the differences will be larger. I'd expect those to be largely focused on clock trees, interrupt architectures, power modes, etc.

So short answer I agree with parent, get a cheap board and learn some stuff. If you like it, go from there. Do NOT choose a Cortex A though unless you want to really dig into embedded Linux. Systems at that level are way, way more complex and if the goal is to learn "everything about this processor" that will be especially difficult.

Re: Ask HN: What should a systems/low-level software engineer know?

#156
I'd start with everything by Hennessy and Patterson. That should cover most of how CPUs and memory systems work.

I grew up with Tannenbaum for networking, though most people went toward Comer and Stevens. Maybe there's something even more current.

I honestly don't know anything as good for storage, which is funny since it's my own specialty. I can try to cobble together a reading list if you'd like.

Something on operating systems. Vahalia for an overview, Bach for System V, gang of four for BSD. Yes, study something besides Linux ... but do study Linux as well. Not sure which books are good for that.

Something on compilers. Is the dragon book still the go-to reference here?

Even if you don't work in those specific areas, that should give you the grounding to study more. I'd also throw in something on databases, but don't know a specific book/author. Distributed systems much like storage: definitely learn, can't think of a good single source, can create a list if you want (I think I did one for a colleague not too long ago).

Good luck!

Re: Ask HN: What should a systems/low-level software engineer know?

#157
post #48
post #24

Earlier quoted context omitted.

I don't do embedded systems, but as a self-respecting software engineer, I am intending to develop proficiency in C/C++ over this next year. Does anybody have any recommended books/courses/projects?

I highly recommend Computer Systems: A Programmer's Perspective for learning C. In particular chapter 3 of that book is what made it all click for me. Understanding how C is translated down into assembly is incredibly useful for understanding pointers and reasoning about your code. EDIT. The book also comes with a collection of excellent projects, which the authors have made freely available online at http://csapp.cs…

Agreed! The labs are very informative and fun. One of my favorite undergrad courses used this book/labs ~10 years ago. Glad to see it is still being used!

Re: Ask HN: What should a systems/low-level software engineer know?

#158
For High Throughput compute, and cache correctness. Here are the primers I can give. None of these are required. Strong langauge, cs, interpersonal skills, team inter-interoperability, and commitment to quality (via unit and integration testing, and skill working with liners) can get you a lot further.

The resources I'm linking are supplementary to the above, and you'll likely encounter them in the wild. But they'll help you build a base of knowledge, and give you terminology to search for, and work with.

- What Every Programmer should know about memory: https://people.freebsd.org/~lstewart/articles/cpumemory.pdf

- Cache Obviousness: https://www.youtube.com/watch?v=bY8f4DSkQ6M (the suggestions, and terminology are important)

- Parallelism: (This is a good primer, there are a lot of complementary posts linked on the site) https://preshing.com/20120612/an-introduction-to-lock-free-p... https://preshing.com/20120913/acquire-and-release-semantics/

- If you plan on working with linux these is an excellent reference: http://man7.org/linux/man-pages/dir_section_2.html remember there is no magic in Linux, everything eventually has to go through a system call. So if you learn the systemcalls, you can can learn how things work :)

- Fog's optimization resources are awesome: https://www.agner.org/optimize/

- MIT courseware: https://www.youtube.com/watch?v=ytpJdnlu9ug&list=PLUl4u3cNGP... https://www.youtube.com/watch?v=HtSuA80QTyo&list=PLUl4u3cNGP...

- This cheat sheet is worth committing to memory: http://www.bigocheatsheet.com/ the reference links are also great for building up knowledge

- I highly recommend CMU DB open course ware: (intro) https://www.youtube.com/watch?v=vyVGm_2iFwU&list=PLSE8ODhjZX... (advanced) https://www.youtube.com/watch?v=poEfLYH9W2M&list=PLSE8ODhjZX...

This should give you a good primer on Concurrency, and DB's. For networking likely a basic TLA+ certification class will be 99% review, but for the things it isn't will offer great insight.

Re: Ask HN: What should a systems/low-level software engineer know?

#159
Watch Mike Acton’s CppCon 2014 talk on Data Oriented Design. His advice may not be at all applicable to whatever field you end up in (and it’s a deliberately contentious talk) but IMO it’s essential for a systems level programmer to have enough understanding of the related concepts to be able to argue about them convincingly.

Re: Ask HN: What should a systems/low-level software engineer know?

#160

I'm an embedded software engineer. Here's my $0.02 on how to get started: 1. Get a platform you can tinker around with, and recover quickly in case of disaster. Raspberry pi is a good example. 2. Learn how to find and read detailed register-level manuals of the underlying chip you're working on. 3. Learn what a programmer's memory-model is. 4. Learn what peripherals are, and what they do. You may have to dig a bit in…

Emphasis on 8. If you are writing code that directly controls hardware, then your software is the abstraction.

Hardware is physical and can be quirky. Signals take real clock time to settle down and your CPU is probably much faster than the transition time. Hardware can and does have bugs just like software. A bad ground pin can make your hardware do “impossible” things.

You need to have much more awareness of the context your code runs in the further down the stack you go.

Post reply on HN