Title: Designing User Interfaces Spring 1999
1SE 746-NT Embedded Software Systems
Development Robert Oshana Lecture
27 For more information, please
contact NTU Tape Orders NTU Media
Services (970) 495-6455
oshana_at_airmail.net
tapeorders_at_ntu.edu
2Developing efficient code
3In line functions
- C keyword inline can be added to any function
declaration - Call to compiler to replace calls to indicated
function with copies of the code that is inside - Eliminates runtime overhead associated with the
actual function call
4Table lookups
- switch statement should be used with care
- Each test and jump requires overhead to prosecute
- To improve, put individual cases in order by
their relative frequency of occurrence - Most likely case first
5Hand coded assembly
- Some modules best written in assembly
- Programmer can make very efficient
- Lack of portability, maintainability, etc
- Some projects have restrictions on overall
percentage of use
6Register variables
- Keyword register can be used to declare local
variables - Asks compiler to place the variable in a general
purpose register instead of the stack - Used for frequently used variables to enhance
performance
7Global variables
- More efficient to use a global variable than to
pass a parameter to a function - Eliminates the need to push the parameter onto
the stack before function call and pop and back
off - Can have negative side affects wrt modularity and
reentrancy
8Polling
- IRSs used to improve program efficiency
- Some rare cases in which the overhead associated
with the interrupts causes inefficiencies - Might be better to use polling
9Fixed point arithmetic
- Will pay large penalty for manipulating float
data in the program - Floating point library is a set of subroutines
that emulate a floating point processor - Can take a long time to execute
10Decreasing code size
11Avoid standard library routines
- Avoid using standard library routines
- These try to handle all possible cases
- Can implement a subset of this functionality with
less code
12Native word size
- Every processor has a native word size
- int must always map to that size (ANSI)
- Manipulation of smaller or larger data types
sometimes requires use of additional machine
language instructions
13Goto statements
- Not a good software engineering technique
- Can be used to remove complicated control
structures or to share a block of oft repeated
code
14C
- Not everything is expensive
- public and private are to determine which
methods to call (made at compile time so no
penalty at runtime) - Default parameters penalty free
- Constructors and destructors have a slight
penalty (good price to pay for fewer bugs)
15C
- Constructors eliminate an entire class of C
programming errors wrt uninitialized data
structures
16Other topics in optimization
17The Problem
- Program is written completely in C
- You run it through the compiler
- Dont get the efficiency you need
How do you get this code to run faster without
rewriting the routines in assembly?
18Our Goals Today
- Learn how to use tools to get more efficiency
- Learn guidelines to make code more optimal
- Learn how to get efficiency of assembly code
without writing it yourself
So why do we have problems with C anyway?
19The Trouble With C
- C code must be translated to the native
instruction set of DSP
- DSPs resources are limited (i.e. registers), so
compiler needs to figure out what goes where
- Compiler doesnt know exactly what you want to
do, so it must interpret your code
What do I do to optimize my C code?
20Flow for Optimization
More C Optimization?
Yes
No
No
To Assembly Optimizations
21Flow for Optimization (contd)
22Steps to Optimizing Code
- Run code through C Optimizer, using best
combination of options - Check your Coding Practices using Guidelines
- Examine code for places where you can use DSP
instructions directly - For common DSP routines, replace C functions with
calls to DSP SW libraries
23Using the Optimizer
- The optimizer is a powerful tool for creating
efficient C code
- It must go through very complicated processes to
figure out what your code is doing
- By providing extra information to the optimizer,
we can help to get the best performance possible
in our code
24What Does the Optimizer Do?
- Cost-based register allocation
- Alias disambiguation
- Branch optimizations and control-flow
simplification - Data flow optimizations
- Copy propagation
- Common subexpression elimination
- Redundant assignment elimination
- Expression simplification
25What Does the Optimizer Do?
- Inline expansion of runtime-support library
functions - Induction variable optimizations and strength
reduction - Loop-invariant code motion
- Loop rotation
26Different Levels of Optimization
How do we control what the optimizer does?
- Different Optimizer levels
- o0 - register
- o1 - local
- o2- global
- o3- file
- Program Level (-pm)
- Combines all C files into one before optimizing
27Optimization Levels
Register (-o0 (default))
Local (-o1)
- Performs local copy/constant propagation
- Removes unused assignments
- Eliminates local common expressions
- Simplifies control flow
- Allocates variables to registers
- Eliminates unused code
- Simplifies expressions and statements
- Expands calls to inline functions
Global (-o2)
File (-o3)
- Performs loop optimizations
- Eliminates global common sub-expressions
- Eliminates global unused assignments
- Performs loop unrolling
- Removes functions that are never called
- Simplifies functions with return values that are
never used - Inlines calls to small functions (regardless of
declaration) - Reorders functions so that attributes of called
function are known when caller is optimized - Identifies file-level variable characteristics
28Program Level Optimization
- Combines all files into one before running
optimizer - Optimizer can see all C function inputs and
outputs - Allows further optimization
- If argument in function always has same value, is
replaced with the value and value is passed
instead of the argument - Deletes code for unused return values
- Removes function code for uncalled functions
29Program Level Optimization
- Better optimization of loops since compiler can
determine loop counts that are passed as
parameters - Increases compilation time and rearranges code
significantly, so is usually one of the last
steps in optimization
30Mixing C and Assembly
- To keep variables, have two methods
- Use volatile keyword
- Use different options
- To keep functions, have two methods
- Place FUNC_EXT_CALLED pragma before declaration
or reference
31Mixing C and Assembly
- Potential problems if also have assembly routines
- Optimizer is not aware of them and may cut out
calls to them - Optimizer may cut out variables accessed by them
32Examples of Options
- Indicates if functions in other modules can call
a modules external functions or modify the
modules external variables
33Inlining Code
- For small infrequently called functions it may
make sense to paste them directly into code (i.e.
inline) - Eliminates overhead (register storage and
parameter passing) - Uses more program space, but speeds up execution
- When inlined, optimizer can optimize it in new
context
34Inlining Code
- Two types of inlining
- Static function only placed in code where used
- Normal also has function definition so it can
be called - Two ways to inline code
- Automatic compiler inlines if size is small
enough - Definition-Controlled you specify which
functions to inline
35Optimization Procedures
36Cost-Based Register Allocation
- Allocates registers to user variables and
compiler temporary values according to their
type, use, and frequency - Weights variables used within loops to have
priority over others - Variables whose uses dont overlap can be
allocated to the same register
37Alias Disambiguation
- Aliasing If two or more symbols, pointer
references, or structure references refer to the
same memory location - Often prevents compiler from retaining values in
registers because it cannot be sure that the
register and memory continue to hold the same
values over time - Alias disambiguation is a technique that
determines when two pointer expressions cannot
point to the same location, allowing compiler to
freely optimize such expressions
38Branch Optimizations and Control-Flow
Simplification
- Rearranges linear sequences of operations (basic
blocks) to remove branches or redundant
conditions - Unreachable code is deleted
- Branches to branches are bypassed
- Conditional branches over unconditional branches
are simplified to single conditional branch - Can delete conditional branches if able to
determine condition at build time
39Branch Optimizations and Control-Flow
Simplification
- Switch case lists are analyzed in the same way as
conditional branches and are sometimes eliminated
entirely. - Some simple control flow constructs can be
reduced to conditional instructions, totally
eliminating need for a branch
40Types of Data Flow Optimizations
- Copy propagation
- Replaces references to the variable with its
value - Value can be another variable, a constant, or a
common subexpression - Can result in increased opportunities for
constant folding, common subexpression
elimination, or total elimination of the
variable. - Common subexpression elimination
- When two or more expressions produce the same
value, the compiler computes the value once,
saves it, and reuses it.
41Types of Data Flow Optimizations
- Redundant assignment elimination
- Copy propagation and common subexpression
elimination optimizations often result in
unnecessary assignments to variables (variables
with no subsequent reference before another
assignment or before the end of the function) - Optimizer removes these dead assignments
42Expression Simplification
- Simplifies expressions into equivalent forms,
requiring fewer instructions or registers - Operations between constants are folded into
single constants - For example, a (b 4) (c 1) becomes a b
c 3
43Data Flow Optimizations
- Replace expressions with less costly ones
- Detect and remove unnecessary assignments
- Avoid operations that produce values that are
already computed - Performed both locally (within basic blocks) and
globally (across entire functions)
44Inline Expansion of Functions
- Replaces calls to small functions with inline
code - Saves over-head associated with a function call
- Provides increased opportunities to apply other
optimizations
45Induction Variables and Strength Reduction
- Induction variables variables whose value within
a loop is directly related to the number of
executions of the loop - Array indices and control variables of for loops
are very often induction variables - Strength reduction process of replacing
inefficient expressions involving induction
variables with more efficient expressions - i.e. code that indexes into a sequence of array
elements is replaced with code that increments a
pointer through the array
46Induction Variables and Strength Reduction
- Induction variable analysis and strength
reduction together often remove all references to
your loop control variable, allowing its
elimination entirely
47Loop-Invariant Code Motion
- Identifies expressions within loops that always
compute the same value - Moves computation in front of the loop
- Replaces each occurrence in the loop by a
reference to the precomputed value
48Loop Rotation
- Evaluates loop conditionals at the bottom of
loops - Saves an extra branch out of the loop
- In many cases, the initial entry conditional
checkand the branch are optimized out
49SE 746-NT Embedded Software Systems
Development Robert Oshana End of
lecture For more information, please
contact NTU Tape Orders NTU Media
Services (970) 495-6455
oshana_at_airmail.net
tapeorders_at_ntu.edu