Branch Optimisations
Pipelines offer significant speed up if the pipeline can be kept full.
instr A
instr B
if COND
instr A
instr B
else
instr A
instr B
instr G
instr HDelayed branching
Delayed branching: fetch instructions after the conditional. When executing
Link to originalinstr B, we could start fetchinginstr Gsince it doesn’t depend on the outcome of the conditional statement.Branch prediction
Branch prediction: ==speculatively fetch the next instruction from one of the branches. We could fetch either
instr Corinstr Eand hope we fetch the correct one. If we guess wrong, data has to be removed from registers==.To pick the correct branch (in branch prediction), we can choose a few options: ?
- We could pick randomly, yielding 50% success rate.
- Could use static prediction, hence analyse the code at compile-time, yielding 80% success rate on average. (from SPEC analysis)
- Use dynamic prediction: during run-time keep track of how often each branch is taken and when the conditional is encountered in the future, fetch the most common branch. This does require some training ahead of time.
Code Optimisations
Sometimes performing code optimisations at the software level can yield better results. Some common tips include:
- Use appropriate data types: don’t use say
doublewhenintis fine - Eliminate unnecessary branches: minimise the no. of branches by combining conditions and removing those that will never execute
- Use multiplication instead of division
- Profile programs: identify parts of the program using most CPU time
Compiler Optimisations
In modern high-level languages, the compiler does most of the optimisations for us. Sometimes attempted optimisations may be detrimental, often it’s better to just give the compiler as much information as possible rather than trying to optimising it by hand.