Sunteți pe pagina 1din 18

Étude de cas : SAD

la fonction SAD (Sum of Absolute Difference) est très utilisée en traitement


d’image et vidéo :

int sad(unsigned char a[40], unsigned char b[40])


{
int x;
int sum=0;
for(x=0; x < 40; x++)
sum += abs(a[x] - b[x]);
return sum;
}

2
Algorithme du SAD
Reference
Frame I-1

Source
Frame I
16
x
16 Pixels

64 Pixels
16

16 Pixels

16 * 16 * 3 * 8 bits

64 Pixels

3
Étude de cas
C++ Assembleur

MVK .S 40, A2
int sad (unsigned char a[40], MVK .S 0, A4
unsigned char b[40])
{ loop: LDH .D *A5++, A0
int x; LDH .D *A6++, A1
int sum = 0;
for(x=0 ; x < 40 ; x++) SUB .S A0, A1, A3
sum += abs(a[x] - b[x]); ABS .L A3, A3
return sum; ADD .L A4, A3, A4
} SUB .L A2, 1, A2

[A2] B .S loop

STH .D A4, *A7

4
Code ASM généré à partir du code C++ :
_sad:
MV .D1 A4, A0 ZERO .D1 A3
|| MVKH .S1 0x10000, A2
MV .S1X B4, A4 || ADD .L1X 2, B0, A1
|| MV .S2X A0, B4
L2: ; PIPED LOOP KERNEL
L1: ; PIPED LOOP PROLOG
ABS .L1 A0, A5
LDBU .D1T1 *A4++, A0 || [ B0] B .S2 L2
|| B .S2 L2 || [ A1] LDBU .D1T1 *A4++, A0
|| LDBU .D2T2 *B4++, B5 || [ A1] LDBU .D2T2 *B4++, B5

MVK .S2 0x28, B5 [ A2] MPYSU .M1 2, A2, A2


|| [ A1] SUB .D1 A1, 1, A1
ZERO .S1 A2 || [!A2] ADD .S1 A5, A3, A3
|| SUB .L2 B5, 4, B0 || SUB .L1X B5, A0, A0
|| LDBU .D2T2 *B4++, B5 || [ B0] SUB .D2 B0, 1, B0
|| B .S2 L2
|| LDBU .D1T1 *A4++, A0

5
_sad: MV .D1 A4, A0
On est ici !
MV .S1X B4, A4
|| MV .S2X A0, B4

cycle = 1

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 ? B0 ?
MV A1 ? B1 ?
A2 ? B2 ?
A3 ? B3 ?
A4 &a B4 &b
A5 ? B5 ?
6
_sad: MV .D1 A4, A0
On est ici !
MV .S1X B4, A4
|| MV .S2X A0, B4

Cycle = 2

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 &a B0 ?
MV MV A4, A0 A1 ? B1 ?
MV A2 ? B2 ?
A3 ? B3 ?
A4 &a B4 &b
A5 ? B5 ?
7
LDBU .D1T1 *A4++, A0
|| B .S2 L2 On est ici !
|| LDBU .D2T2 *B4++, B5
MVK .S2 0x28, B5
ZERO .S1 A2
|||| SUB
LDBU .D2T2.L2 B5, 4, B0 B5
*B4++,
|||| LDBU B.D1T1 *A4++,
.S2 A0L2
Cycle = 3

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 &a B0 ?
LDBU
B
MV B4, A4 A1 ? B1 ?
LDBU
MV A0, B4 A2 ? B2 ?
A3 ? B3 ?
A4 &b B4 &a
A5 ? B5 ?
8
|||| LDBU
B .D1T1
.S2 L2*A4++, A0
LDBU .D2T2 *B4++, B5
MVK
ZERO
.S2 0x28, B5
.S1 B5,
A2 4, B0
On est ici !
|||| SUB
LDBU .L2
.D2T2 *B4++, B5
|||| B
LDBU .S2 L2
.D1T1 *A4++, A0

Cycle = 4

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 &a B0 ?
MVK LDBU
B
A1 ? B1 ?
LDBU A2 ? B2 ?
A3 ? B3 ?
A4 &b+1 B4 &a+1
A5 ? B5 ?
9
|||| LDBU
B .D1T1
.S2 *A4++, A0
L2
LDBU .D2T2 *B4++, B5
MVK .S2 0x28, B5 On est ici !
|||| ZERO
SUB .S1 B5,
.L2 A2 4, B0
|||| LDBU
B .D2T2
.S2 *B4++, B5
L2
LDBU .D1T1 *A4++, A0

Cycle = 5

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 &a B0 ?
ZERO
SUB
LDBU
B
MVK 0x28, B5 A1 ? B1 ?
LDBU
B
LDBU A2 ? B2 ?
LDBU A3 ? B3 ?
A4 &b+1 B4 &a+1
A5 ? B5 0x28
10
ZERO .D1 A3
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0, A1 On est ici !!
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5

[ A2] MPYSU .M1 2, A2, A2


|| [ A1] SUB .D1 A1, 1, A1
|| [!A2] ADD .S1 A5, A3, A3
|| SUB .L1X B5, A0, A0
|| [ B0] SUB .D2 B0, 1, B0
Cycle = 6

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 &a B0 0x24
ZERO LDBU
B
ZERO A2 A1 ? B1 ?
MVKH SUB B5, 4, B0
ADD
LDBU A2 0 B2 ?
B
LDBU
A3 ? B3 ?
LDBU A4 &b+2 B4 &a+2
A5 ? B5 0x28
11
ZERO .D1 A3
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0, A1 On est ici !
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5 1ère itération
||
[ A2]
[ A1]
MPYSU .M1 2, A2, A2
SUB .D1 A1, 1, A1
du noyau
|| [!A2] ADD .S1 A5, A3, A3
|| SUB .L1X B5, A0, A0
|| [ B0] SUB .D2 B0, 1, B0
Cycle = 7

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 &a B0 0x24
ABS LDBU
B
ZERO A3 A1 0x26 B1 ?
B MVKH 0x10000, A2
LDBU
LDBU
ADD 2, B0, A1
A2 0x10000 B2 ?
B
LDBU LDBU
A3 0 B3 ?
LDBU A4 &b+2 B4 &a+2
A5 ? B5 0x28
12
ZERO .D1 A3
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0, A1 On est ici !
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5 1ère itération
||
[ A2]
[ A1]
MPYSU .M1 2, A2, A2
SUB .D1 A1, 1, A1
du noyau
|| [!A2] ADD .S1 A5, A3, A3
|| SUB .L1X B5, A0, A0 Cette instruction
|| [ B0] SUB .D2 B0, 1, B0 n’est pas exécuté
Cycle = 8 puisque A2 ≠ 0 [!A2]

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 b[0] B0 0x24
MPYSU
B
LDBU *A4, A0 A1 0x26 B1 ?
SUB B LDBU *B4, B5
ADD LDBU ABS A0, A5
A2 0x10000 B2 ?
B
SUB LDBU LDBU
A3 0 B3 ?
SUB LDBU A4 &b+3 B4 &a+3
A5 abs(&a) B5 a[0]
13
ZERO .D1 A3
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0, A1 On est ici !
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5 2ème itération
||
[ A2]
[ A1]
MPYSU .M1 2, A2, A2
SUB .D1 A1, 1, A1
du noyau
|| [!A2] ADD .S1 A5, A3 ,A3
|| SUB .L1X B5, A0, A0
|| [ B0] SUB .D2 B0, 1, B0
Cycle = 9

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 a[0]- b[0] B0 0x23
ABS MPYSU B L2 A1 0x25 B1 ?
B B
LDBU LDBU
SUB A1, 1, A1
SUB B5, A0, A0
A2 0x10000 B2 ?
B
LDBU LDBU LDBU SUB B0, 1, B0 A3 0 B3 ?
LDBU A4 &b+3 B4 &a+3
A5 ? B5 a[0]
14
ZERO .D1 A3
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0, A1 On est ici !
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5 2ème itération
||
[ A2]
[ A1]
MPYSU .M1 2, A2, A2
SUB .D1 A1, 1, A1
du noyau
|| [!A2] ADD .S1 A5, A3, A3
|| SUB .L1X B5, A0, A0 Cette instruction n’est pas
|| [ B0] SUB .D2 B0, 1, B0
exécutée puisque A2 = 0 [A2]
Cycle = 10

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 b[1] B0 0x23
MPYSU ABS A0, A5 A1 0x25 B1 ?
SUB B B LDBU *A4, A0
ADD LDBU LDBU LDBU *B4, B5
A2 0x0000 B2 ?
B
SUB LDBU LDBU MPYSU 2, A2, A2 A3 0 B3 ?
SUB A4 &b+4 B4 &a+4
A5 abs(a[0]-b[0]) B5 a[1]
15
ZERO .D1 A3
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0 ,A1 On est ici !
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5 3ème itération
||
[ A2]
[ A1]
MPYSU .M1 2, A2, A2
SUB .D1 A1, 1 ,A1
du noyau
|| [!A2] ADD .S1 A5, A3, A3
|| SUB .L1X B5, A0, A0 abs(a[0]-b[0]) + 0
|| [ B0] SUB .D2 B0, 1 ,B0
Cycle = 11

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 a[1]- b[1] B0 0x22
ABS B L2 A1 0x24 B1 ?
B B B SUB A1, 1, A1
LDBU LDBU LDBU ADD A5, A3, A3 A2 0x0000 B2 ?
LDBU LDBU LDBU SUB B5, A0, A0 A3 B3 ?
SUB B0, 1, B0
A4 &b+4 B4 &a+4
A5 abs(a[0]-b[0]) B5 a[1]
16
ZERO .D1 A3
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0, A1 On est ici !
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5 3ème itération
||
[ A2]
[ A1]
MPYSU .M1 2, A2, A2
SUB .D1 A1, 1, A1
du noyau
|| [!A2] ADD .S1 A5, A3, A3
|| SUB .L1X B5, A0, A0 abs(a[0]-b[0]) + 0
|| [ B0] SUB .D2 B0, 1, B0
Cycle = 12

Execute Reg Valeur Reg Valeur


E1 E2 E3 E4 E5 E6 Done A0 b[2] B0 0x22
ABS A0, A5 A1 0x24 B1 ?
SUB B B LDBU *A4, A0
ADD LDBU LDBU LDBU *B4, B5
A2 0x0000 B2 ?
B
SUB LDBU LDBU A3 B3 ?
SUB A4 &b+5 B4 &a+5
A5 abs(a[1]-b[1]) B5 a[2]
17
ZERO .D1 A3 À quelle itération appartient ce load? i+2
|| MVKH .S1 0x10000, A2
|| ADD .L1X 2, B0, A1
L2: ; PIPED LOOP KERNEL
ABS .L1 A0, A5
|| [ B0] B .S2 L2
Même chose pour ce load
|| [ A1] LDBU .D1T1 *A4++, A0
|| [ A1] LDBU .D2T2 *B4++, B5
À quelle itération appartient cet add? i-1
[ A2] MPYSU .M1 2, A2, A2
|| [ A1] SUB .D1 A1, 1, A1
|| [!A2] ADD .S1 A5, A3, A3
|| SUB .L1X B5, A0, A0 Et ce sub? i
|| [ B0] SUB .D2 B0, 1, B0

On remarque que les données se chargent pour différentes itérations dans le


même noyau. Voyant de près la relation entre les données et les itérations.

Noter qu’on à 4 itérations en parallèle : i-1, i, i+1, i+2

18