(I don't know what dynamic execution means, but I am familiar with the out-of-order execution idea)
While the x86-64 instruction set is (nearly) the same between very recent processors and those from five years ago (perhaps with the exception of vector instruction extensions like AVX-512), the optimization rules have changed.
In other words, a machine code program (executable or library) generated and optimized for an i3770 from five years ago won't be the best optimized code for a recent AMD Ryzen (but it will be able to run on that Ryzen 1800x without recompilation, since using the same instruction set). So machine code optimized for Ryzen is not the best for i3770 and vice versa.
But compilers know that, and they can generate optimized code for some particular CPU brand. They then would generate code tailored to specific features of your particular processor (e.g. size and organization of CPU cache, configuration & behavior of its branch predictor, out-of-order execution & pipelines, etc etc etc...)
So you need to update your compiler (it could be important to get a recent version) and pass appropriate options to it.
For GCC, read its optimizing options section, and also the x86 options section.
I recommend (for straight, not cross, compilation) compiling with
gcc -Wall -O2 -march=native on the same machine as the one running your code. If you want to compile into some binary able to run on several brands you need to be more careful.
BTW, some compilers (including GCC...) provide extra builtins (and even x86-specific builtins) to take advantage of processor features not visible to C code; for example
__builtin_prefetch (for explicit CPU cache prefetching), but see this which suggests to avoid using them in general (because compilers are often - but not always - optimizing well enough).
In practice, recent compilers do a pretty good job on optimizations, so I don't think it is worth the trouble to hand-tune code to optimize it even more, but YMMV. It might worth to recompile your (or some free software) source code when upgrading your processor, but you'll usually only win a few percents of performance in doing so.
(IMHO, cache locality matters a lot more, since a major -L3- cache miss is taking as much time as executing more than a hundred of machine instructions; e.g. prefer vectors to linked lists)