If I compile Bitcoin Core using the instructions in the README, does the C++ compiler use compiler optimizations for my current CPU, or will it output a "generic" binary, that can run on almost any CPU? For example if my CPU supports the AVX-512 instructions, will the compiler automatically output a suitable binary or does it not take into account any CPU features at all? If so, how can I make sure I have the optimal binary running on my machine?
By default, yes and no.
No, most of the code is compiled for generic target hardware. If you want something optimized for your actual hardware, you can add
-march=native to your compilation flags (e.g. you'd run
./configure CFLAGS="-march=native" CXXFLAGS="-march=native"). This will result in a binary that may not work on other hardware than your own. This likely gives you some performance gains, but is unlikely to have a huge impact, because...
Yes, some code has several variants that are always compiled in, and the optimal one is decided at runtime based on available hardware features. This includes:
- SHA256 versions for SSE4, SSE4.1, AVX2, and SHA-NI exist.
- CRC32 versions (inside LevelDB) for ARM64 and SSE4.2 exist.
- The internal random number generator will use RDRAND/RDSEED if provided by the hardware (in addition to other randomness sources).
Certainly more optimizations are possible for specific hardware or features, but generally this isn't as easy as just turning a compiler flag - it also needs different code to actually make use of it. For example, compiling generic SHA256 code with
-march=native will give a modest speedup, but using code that is designed to make use of the 256-bit wide registers AVX2 can be several times faster in some cases than that, by computing multiple hashes in parallel.