While in most cases its not necessarily, recently I have taken to reading the generated assembly of my C code every so often, when I’m curious as to the kinds of optimizations my compiler is making. Especially for low level code or functions which are called many times.
Examples include:
- Checking if a change to the C code has any impact on the generated code.
- Checking if the same expression used twice is optimized into one, or if assigning a variable makes a difference.
- Check for changes which may bloat-generated code-size.
Now this is not a perfect method by any means, its possible that some difference in the generated output is a red-herring, because of all sorts of internal logic & thresholds within the compiler, but its still interesting at times.
At this point while looking at the assembly I can lookup each command, but not really read the assembly (amd64 as it happens).
So my question is, has anyone found it useful to learn a certain amount of assembly to write better C code? (or at least get more insights into their code).
- If so, how much is useful to know?
- What kinds of issues did it help you resolve?
Note, the danger here is that one writes C code targeting the assembly which is very specific to the developers own system – any advantage may be lost on a different compiler or architecture, taking that into account, Im still interested in other developers experience
6
Sometimes you need to be able to read some assembly. For example when optimizing code through compiler instrumentation (see for example here). One needs to know what the costs of type casting, data alignment and so on, have for performance.
Also, there are some issues like different function call conventions (pascal vs stdcall) and other system specific issues which are of relevance. Again, it is useful to understand what the compiler does, what the different technologies provide (SSE, AVX,…) and debug some weird problems.
Once you are aware of such problems, you write better code:
- data type awareness (do I need double/long, or does it suffice with float/int)
- avoiding unnecessary casts
Usually one avoids such problems by defining its own types and sticking to conventions. You help the compiler do a better job, and it is also easier to understand/maintain.
1
It is not always useful (but sometimes it can help) to read the generated assembly code. Small tip when compiling with GCC, compile with
g++ -Wall -fverbose-asm -O2 -S somesourcefile.cc
(the -fverbose-asm
gives more readable assembly code)
You may also look at intermediate representations. With g++
try passing -fdump-tree-all
(with your optimization flags). Beware, it gives hundreds of dump file.
BTw, you might find useful my GCC MELT plugin
At last, be aware that generally speaking compilers optimize better than human programmers do.