Il cosmo e il focolare. Opinioni di un cosmopolita

MIPS
II parte
65
Altre condizioni
●
branch less equal (bad)
slt
bne
bne
THEN: add
L: ...
●
if (i <= j) {
/*THEN:*/ f = g + h;
}
/*L:*/
$t1,
$t1,
$s1,
$s3,
$s1, $s2
$zero, THEN
$s2, L
$s4, $s5
#
#
#
#
t1 = i < j
se t1 != 0 (i < j) salta a THEN
se i != j salta a L
f = g + h
branch less equal (good)
–
i <= j → !(j < i)
slt
bne
add
L: ...
$t1,
$t1,
$s3,
$s2, $s1
$zero, L
$s4, $s5
#
#
#
t1 = j < i
se t1 != 0 (j < i) salta a L
f = g + h
66
Esempio: massimo tra due numeri
m = i < j ? j : i;
// alternativamente
if (i < j) m = j;
else m = i;
●
Supponiamo
–
$s0 indirizzo di i
–
$s1 indirizzo di j
–
$s2 indirizzo di m
67
Esempio: massimo tra due numeri
lw
lw
slt
beq
or
j
L: or
E: sw
$t0,
$t1,
$t2,
$t2,
$t3,
E
$t3,
$t3,
0($s0)
0($s1)
$t0, $t1
$zero, L
$t1, $zero
#
#
#
#
#
#
$t0, $zero #
0($s2)
#
Piccola ottimizzazione
lw
lw
slt
beq
sw
j
L: sw
E:
carica i
carica j
test i < j
se no, salta a L
altrimenti t3 = t1 (j)
salta a E
t3 = t0 (i)
salva t3 in m
$t0,
$t1,
$t2,
$t2,
$t1,
E
$t0,
0($s0)
0($s1)
$t0, $t1
$zero, L
0($s2)
0($s2)
#
#
#
#
#
#
#
carica i
carica j
test i < j
se no, salta a L
salva t1 in m
salta a E
salva t0 in m
68
Esempio: inizializzare un array
●
Con indici
int const N = ...;
int A[N];
for (i = 0; i != N; ++i) {
A[i] = 1;
}
●
Supponiamo
–
$s0 indirizzo di A
●
–
indirizzo del primo elemento A[0], &A[0]
$s1 indirizzo di N
69
Esempio: inizializzare un array
●
Con indici
or
lw
L: beq
sll
add
addi
sw
addi
j
E:
$t0,
$t1,
$t0,
$t2,
$t2,
$t3,
$t3,
$t0,
L
$zero, $zero
0($s1)
$t1, E
$t0, 2
$t2, $s0
$zero, 1
0($t2)
1
#
#
#
#
#
t0 = 0 (indice i)
carica N
se i == N vai alla fine
i *= 4
i += A (indirizzo di A[i])
#
#
#
A[i] = 1
++i
vai a inizio loop
70
Esempio: inizializzare un array
●
Con puntatori
int const N = ...;
int A[N] = {...};
int* p = A;
int* A_end = A + N;
while (p != A_end) {
*p = 1;
++p;
}
●
// anche &A[N]
// questo + va avanti di N * 4 byte
// questo ++ va avanti di 4 byte
Supponiamo
–
$s0 indirizzo di A
●
–
indirizzo del primo elemento A[0], &A[0]
$s1 indirizzo di N
71
Esempio: inizializzare un array
●
Con puntatori
or
lw
sll
add
L: beq
addi
sw
addi
j
E:
$t0,
$t1,
$t1,
$t1,
$t0,
$t3,
$t3,
$t0,
L
$s0, $zero
0($s1)
$t1, 2
$t1, $s0
$t1, E
$zero, 1
0($t0)
$t0, 4
#
#
#
#
#
p = A
carica N
N *= 4
N += A (= A_end)
se p == A_end vai alla fine
#
#
#
*p = 1
p += 4
torna all'inizio del loop
72
Indici o puntatori?
…
0
1
&A[0]
A &A[1]
2
3
4
N-1
N
…
elementi dell'array
&A[N]
p
# con indici
or
$t0, $zero, $zero
lw
$t1, 0($s1)
L: beq $t0, $t1, E
sll $t2, $t0, 2
add $t2, $t2, $s0
sw
$zero, 0($t2)
addi $t0, 1
j L
E:
●
…
&A[N-1]
# con puntatori
or
$t0, $s0, $zero
lw
$t1, 0($s1)
sll $t1, $t1, 2
add $t1, $t1, $s0
L: beq $t0, $t1, E
sw
$zero, 0($t0)
addi $t0, $t0, 4
j
L
E:
L'uso diretto dei puntatori riduce i calcoli necessari per determinare
l'indirizzo di memoria dell'elemento i-esimo
–
soprattutto dentro il ciclo
73