Optimizing Computer Systems Performance
Optimizing Computer Systems Performance
Program
Op*miza*on
15-‐213:
Introduc0on
to
Computer
Systems
25th
Lecture,
Nov.
23,
2010
Instructors:
Randy
Bryant
and
Dave
O’Hallaron
1
Carnegie Mellon
Today
Overview
Generally
Useful
Op*miza*ons
Code
mo0on/precomputa0on
Strength
reduc0on
Sharing
of
common
subexpressions
Removing
unnecessary
procedure
calls
Op*miza*on
Blockers
Procedure
calls
Memory
aliasing
Exploi*ng
Instruc*on-‐Level
Parallelism
Dealing
with
Condi*onals
2
Carnegie Mellon
Performance
Reali*es
There’s
more
to
performance
than
asympto1c
complexity
3
Carnegie Mellon
Op*mizing
Compilers
Provide
efficient
mapping
of
program
to
machine
register
alloca0on
code
selec0on
and
ordering
(scheduling)
dead
code
elimina0on
elimina0ng
minor
inefficiencies
Don’t
(usually)
improve
asympto*c
efficiency
up
to
programmer
to
select
best
overall
algorithm
big-‐O
savings
are
(oWen)
more
important
than
constant
factors
but
constant
factors
also
maQer
Have
difficulty
overcoming
“op*miza*on
blockers”
poten0al
memory
aliasing
poten0al
procedure
side-‐effects
4
Carnegie Mellon
5
Carnegie Mellon
Code
Mo*on
Reduce
frequency
with
which
computa0on
performed
If
it
will
always
produce
same
result
Especially
moving
code
out
of
loop
void set_row(double *a, double *b,
long i, long n)
{
long j; long j;
for (j = 0; j < n; j++) int ni = n*i;
a[n*i+j] = b[j]; for (j = 0; j < n; j++)
} a[ni+j] = b[j];
6
Carnegie Mellon
int ni = 0;
for (i = 0; i < n; i++) for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) for (j = 0; j < n; j++)
a[n*i + j] = b[j]; a[ni + j] = b[j];
ni += n;
}
8
Carnegie Mellon
9
Carnegie Mellon
10
Carnegie Mellon
200 lower
180
160
140
CPU seconds
120
100
80
60
40
20
0
0 50000 100000 150000 200000 250000 300000 350000 400000 450000 500000
String length
11
Carnegie Mellon
12
Carnegie Mellon
Calling
Strlen
/* My version of strlen */
size_t strlen(const char *s)
{
size_t length = 0;
while (*s != '\0') {
s++;
length++;
}
return length;
}
Strlen
performance
Only
way
to
determine
length
of
string
is
to
scan
its
en0re
length,
looking
for
null
character.
Overall
performance,
string
of
length
N
N
calls
to
strlen
Require
0mes
N,
N-‐1,
N-‐2,
…,
1
Overall
O(N2)
performance
13
Carnegie Mellon
Improving
Performance
void lower(char *s)
{
int i;
int len = strlen(s);
for (i = 0; i < len; i++)
if (s[i] >= 'A' && s[i] <= 'Z')
s[i] -= ('A' - 'a');
}
14
Carnegie Mellon
200
180
160
140
CPU seconds
120
lower
100
80
60
40
20
lower2
0
0 50000 100000 150000 200000 250000 300000 350000 400000 450000 500000
String length
15
Carnegie Mellon
Memory
MaHers
/* Sum rows is of n X n matrix a
and store in vector b */
void sum_rows1(double *a, double *b, long n) {
long i, j;
for (i = 0; i < n; i++) {
b[i] = 0;
for (j = 0; j < n; j++)
b[i] += a[i*n + j];
}
}
Memory
Aliasing
/* Sum rows is of n X n matrix a
and store in vector b */
void sum_rows1(double *a, double *b, long n) {
long i, j;
for (i = 0; i < n; i++) {
b[i] = 0;
for (j = 0; j < n; j++)
b[i] += a[i*n + j];
}
}
Value of B:
double A[9] = init: [4, 8, 16]
{ 0, 1, 2,
4, 8, 16},
i = 0: [3, 8, 16]
32, 64, 128};
Removing
Aliasing
/* Sum rows is of n X n matrix a
and store in vector b */
void sum_rows2(double *a, double *b, long n) {
long i, j;
for (i = 0; i < n; i++) {
double val = 0;
for (j = 0; j < n; j++)
val += a[i*n + j];
b[i] = val;
}
}
19
Carnegie Mellon
Aliasing
Two
different
memory
references
specify
single
loca0on
Easy
to
have
happen
in
C
Since
allowed
to
do
address
arithme0c
Direct
access
to
storage
structures
Get
in
habit
of
introducing
local
variables
Accumula0ng
within
loops
Your
way
of
telling
compiler
not
to
check
for
aliasing
20
Carnegie Mellon
21
Carnegie Mellon
22
Carnegie Mellon
Benchmark
Computa*on
void combine1(vec_ptr v, data_t *dest)
{
long int i; Compute
sum
or
*dest = IDENT; product
of
vector
for (i = 0; i < vec_length(v); i++) { elements
data_t val;
get_vec_element(v, i, &val);
*dest = *dest OP val;
}
}
24
Carnegie Mellon
Benchmark
Performance
void combine1(vec_ptr v, data_t *dest)
{
long int i; Compute
sum
or
*dest = IDENT; product
of
vector
for (i = 0; i < vec_length(v); i++) { elements
data_t val;
get_vec_element(v, i, &val);
*dest = *dest OP val;
}
}
25
Carnegie Mellon
Basic
Op*miza*ons
void combine4(vec_ptr v, data_t *dest)
{
int i;
int length = vec_length(v);
data_t *d = get_vec_start(v);
data_t t = IDENT;
for (i = 0; i < length; i++)
t = t OP d[i];
*dest = t;
}
26
Carnegie Mellon
Opera*on
Results
Addr.
Addr.
Data
Data
Data
Cache
Execu1on
28
Carnegie Mellon
Superscalar
Processor
Defini*on:
A
superscalar
processor
can
issue
and
execute
mul1ple
instruc1ons
in
one
cycle.
The
instruc*ons
are
retrieved
from
a
sequen*al
instruc*on
stream
and
are
usually
scheduled
dynamically.
29
Carnegie Mellon
Nehalem
CPU
Mul*ple
instruc*ons
can
execute
in
parallel
1
load,
with
address
computa0on
1
store,
with
address
computa0on
2
simple
integer
(one
may
be
branch)
1
complex
integer
(mul0ply/divide)
1
FP
Mul0ply
1
FP
Add
30
Carnegie Mellon
31
Carnegie Mellon
* d4
* d5
* d6
* d7
32
Carnegie Mellon
Loop
Unrolling
void unroll2a_combine(vec_ptr v, data_t *dest)
{
int length = vec_length(v);
int limit = length-1;
data_t *d = get_vec_start(v);
data_t x = IDENT;
int i;
/* Combine 2 elements at a time */
for (i = 0; i < limit; i+=2) {
x = (x OP d[i]) OP d[i+1];
}
/* Finish any remaining elements */
for (; i < length; i++) {
x = x OP d[i];
}
*dest = x;
}
34
Carnegie Mellon
Reassociated
Computa*on
x = x OP (d[i] OP d[i+1]); What
changed:
Ops
in
the
next
itera0on
can
be
started
early
(no
dependency)
d0 d1
* Overall
Performance
d2 d3
1 N
elements,
D
cycles
latency/op
* d4 d5 Should
be
(N/2+1)*D
cycles:
* CPE
=
D/2
* d6 d7 Measured
CPE
slightly
worse
for
* FP
mult
*
*
37
Carnegie Mellon
39
Carnegie Mellon
Separate
Accumulators
x0 = x0 OP d[i]; What
changed:
x1 = x1 OP d[i+1]; Two
independent
“streams”
of
opera0ons
1 d0 1 d1
Overall
Performance
* d2 * d3 N
elements,
D
cycles
latency/op
* d4 * d5
Should
be
(N/2+1)*D
cycles:
CPE
=
D/2
* d6 * d7 CPE
matches
predic0on!
* *
What
Now?
*
40
Carnegie Mellon
Limita*ons
Diminishing
returns
Cannot
go
beyond
throughput
limita0ons
of
execu0on
units
Large
overhead
for
short
lengths
Finish
off
itera0ons
sequen0ally
41
Carnegie Mellon
42
Carnegie Mellon
43
Carnegie Mellon
Achievable
Performance
Method! Integer! Double FP!
Operation! Add! Mult! Add! Mult!
Scalar Optimum! 1.00! 1.00! 1.00! 1.00!
Latency Bound! 1.00! 3.00! 3.00! 5.00!
Throughput Bound! 1.00! 1.00! 1.00! 1.00!
44
Carnegie Mellon
45
Carnegie Mellon
46
Carnegie Mellon
Opera*on
Results
Addr.
Addr.
Data
Data
Data
Cache
Execu1on
47
Carnegie Mellon
Branch
Outcomes
When
encounter
condi*onal
branch,
cannot
determine
where
to
con*nue
fetching
Branch
Taken:
Transfer
control
to
branch
target
Branch
Not-‐Taken:
Con0nue
with
next
instruc0on
in
sequence
Cannot
resolve
un*l
outcome
determined
by
branch/integer
unit
Branch
Predic*on
Idea
Guess
which
way
branch
will
go
Begin
execu0ng
instruc0ons
at
predicted
posi0on
But
don’t
actually
modify
register
or
memory
data
80489f3: movl $0x1,%ecx
80489f8: xorl %edx,%edx
80489fa: cmpl %esi,%edx Predict
Taken
80489fc: jnl 8048a25
. . .
49
Carnegie Mellon
51
Carnegie Mellon
Performance
Cost
Mul0ple
clock
cycles
on
modern
processor
Can
be
a
major
performance
limiter
52
Carnegie Mellon
54