上QQ阅读APP看书,第一时间看更新
How can you help the compiler?
How can we help the compiler, after it has done so much for us? We already mentioned the first and perhaps most important thing to do—write understandable, maintainable code.
We have seen in the examples in this chapter that we can trust the compiler to transform a readable but suboptimal code into a more performant one. So primum non nocere (first don't harm), so to speak.
But there are more specific measures we can take, like the following:
- Use compiler options: First, we will want to use the -O option to set the optimization level (typically 2 or 3, note that 3 can sometimes perform worse than 2!). Giving a compiler more context by specifying the target architecture may also help. We might also try to enable loop unrolling, speeding function calls by omitting frame pointers, enabling noncompliant but fast floating-point mathematics and more. Get to know your (compiler's) options!
- Use compiler directives: You might want to use compiler-specific function attributes, examples of which we have already seen in the section on inlining. We could also, for example, change the default call convention to the faster fastcall in that way.
- Use intrinsic functions: Intrinsics are functions for which implementations are provided directly by the compiler. On the one hand, they allow us to use some low-level functionality (for example, _mm_prefetch() for doing manual memory prefetching); on the other hand, the compiler knows everything about their implementation which facilitates many optimizations!
The two last techniques are not very portable and not very pretty, so pay the price only if you desperately need to optimize that single spot! However, there is another, less intrusive technique which will give a compiler more knowledge about the code, as discussed in the next section.