Sunteți pe pagina 1din 14

2014/04/07 11:50

1/14

Familiarizarea cu arhitectura CELL BE

Familiarizarea cu arhitectura CELL BE


Obiective
n cadrul acestui laborator vom ncepe lucrul pe arhitectura Cell Broadband Engine. Vom programa pe
aceast arhitectura folosind limbajele C/C++ i SDK-urile pentru Cell. Vei nva cum s scriei un
program care s se execute pe toate unitile de calcul i cum s folosii tipurile de date vectoriale
suportate de Cell BE.

Arhitectura Cell Broadband Engine


Arhitectura Cell BE a fost dezvoltat de ctre un consoriu format de Sony, Toshiba i IBM i lansat
comercial n 2005, o dat cu apariia Sony Playstation 3. Caracteristicile acestei arhitecturi au facut ca
utilizarea sa s nu se limiteze doar la consola PS3, ducnd la folosirea sa n domeniul High
Performance Computing. Un exemplu ar fi cel mai puternic supercomputer din 2008, IBM Roadrunner,
care coninea 12,960 de procesoare IBM PowerXCell 8iCell.
Arhitectura procesorului Cell este conceput special pentru a oferi o putere de calcul mare (pentru
vremea respectiv), putnd prelucra datele n mod SIMD, folosind instruciuni i tipuri de date
vectoriale. Un Cell conine un Power Processor Element (PPE) i opt Synergistic Processor Elements
(SPE) interconectate prin magistrala Element Interconnect Bus (EIB) ca n figure 1. Procesorul PPE i
SPE-urile comunic ntre ele, cu spaiul principal de stocare (main storage) i cu elementele I/O prin
intermediul magistralei EIB.

Fig. 1: Diagrama bloc a arhitecturii Cell Broadband Engine}


n acest laborator vom rezuma doar caracteristicile principale ale arhitecturii. Mai multe detalii putei
gsi pe pagina Arhitecturii Cell BE, dar i n link-urile de la referine.

ASC Wiki - http://cs.curs.pub.ro/wiki/asc/

Last update: 2014/04/06 23:09

asc:lab6:index

http://cs.curs.pub.ro/wiki/asc/asc:lab6:index

Componente
Magistrala EIB, prin care comunic PPE-ul i SPE-urile, are o structur bazat pe 4 inele (dou n
sens orar i dou n sens anti-orar) pentru transferul datelor ntre componente. Limea de band
intern a magistralei EIB este de 96 bytes pe ciclu i suport mai mult de 100 de cereri DMA n
ateptare ntre SPE-uri i spaiul principal de stocare (Main Storage).
Power Processor Element conine un procesor de uz general pe 64 de bii bazat pe arhitectura
Power, versiunea 2.02. Pe acesta se pot instala sisteme de operare cum ar fi Linux, i de pe el se
pornesc aplicaiile care ajung s se execute pe SPE-uri. Setului su de instruciuni de tip RISC i-au fost
adugate instruciuni pentru calcul vectorial i un set de 32 registre de 128 bii. Instruciunile
vectoriale sunt executate de ctre o unitate SIMD, iar celelalte instruciuni de ctre unitatea de
execuie pentru numere ntregi, n virgula fix, sau de ctre cea pentru numere n virgula mobil.
PPE-ul este format din Power Porcessor Unit (PPU) i din Power Processor Storage Subsystem (PPSS).
Power Processor Storage Subsystem se ocup cu cererile de acces la memorie venite din partea PPE
sau din partea altor procesoare i dispozitive I/O. Acesta conine un cache de nivel 2 (L2) de 512 KB, o
serie de cozi (queues) i o unitate de interfa cu magistrala (arbitru de magistral).
O versiune modificat a PPE-ului este folosit i n procesoarele Xenon din Xbox 360.
Synergistic Processor Element conine un procesor RISC pe 128 bii cu un set de instruciuni
vectoriale, numit Synergistic Processor Unit (SPU), i un Memory Flow Controller. Acest tip de
arhitectur este potrivit aplicaiilor ce necesit calcul intens asupra unor seturi multiple de date
(stream-uri video, prelucrare imagini etc). SPU-urile sunt procesoare simple fr cache, cu o memorie
local (Local Store) pentru instruiuni i date (256 KB SRAM). Ca structur, procesorul folosete un
banc de 128 registre de 128 bii, o unitate de execuie n virgul mobil i dou uniti n virgul fix.
Aceste uniti execut numai instruciuni vectoriale (SIMD).
SPU-ul execut instruciunile din Local Store i lucreaz cu datele din Local Store. Acesta nu poate
accesa direct memoria principal sau Local Store-urile altor SPE-uri. Pentru a permite transferul de
date ntre PPE i SPE, sau ntre SPE-uri, se folosesc mecanisme precum transfer DMA i mailboxes.
Despre aceste transferuri vom oferi mai multe detalii n laboratoarele urmtoare. Componenta
Memory Flow Controller a SPE-ului este cea care controleaz transferurile de date, fiind conectat la
magistrala EIB.
Pentru un SPE, vom folosi termenul de Main Storage pentru a ne referi la memoria principal
(accesat direct doar de PPU), la Local Store-urile altor SPE-uri i la registrele mapate n memorie
(MMIO).

http://cs.curs.pub.ro/wiki/asc/

Printed on 2014/04/07 11:50

2014/04/07 11:50

3/14

Familiarizarea cu arhitectura CELL BE

Fig. 2: Componentele principale ale unui PPE i ale unui SPE

Structura unei aplicaii


Cell BE ofer un procesor de uz general cu arhitectura PowerPC (PPE) i 8 procesoare specializate, cu
arhitectura SIMD (SPE). Ca mod de lucru, o aplicaie care folosete att PPE-ul ct i SPE-urile:

conine un program PPE - este executat pe PPE i ncarc i pornete execuia programelor SPE
conine unul sau mai multe programe SPE - programele care sunt executate de ctre SPU-uri
folosete un API pentru C/C++, cu extensii pentru arhitectura Cell
folosete compilatoare diferite pentru programele PPE i SPE

Programele SPE-urilor nu pot fi lansate direct n execuie. Ele pot fi pornite numai din codul
programului PPE.
ntr-un sistem care ruleaz Linux, thread-ul iniial al unui program este un thread Linux care ruleaz
pe PPE. Acest thread poate crea unul sau mai multe task-uri Linux pentru Cell Broadband Engine.
Un task Linux pentru Cell Broadband Engine are unul sau mai multe thread-uri Linux asociate cu
acesta, care ruleaz fie pe PPE (thread-uri PPE), fie pe SPE (thread-uri SPE), n funcie de codul
executabil ncrcat. Un thread SPE este un thread de Linux care ruleaz pe SPE. Acesta are asociat un
context care include starea celor 128 de registre, contorul program si cozile de comenzi pentru MFC.
Sistemul de operare ofer mecanismul i politicile de rezervare a unui SPE disponibil. Acesta are i
rolul de a prioritiza aplicaiile de Linux pentru sistemul Cell Broadband Engine i de a planifica
execuia pe SPE-uri, independent de thread-urile normale Linux. Este de asemenea responsabil i de
ncrcarea runtime-ului, transmiterea parametrilor ctre programele SPE, notificarea n cazul
evenimentelor i erorilor din SPE-uri i asigurarea suportului pentru debugger.

n cadrul laboratoarelor vom folosi sistemele Cell BE puse la dispoziie n cluster, conform tutorialului
de pe wiki: Rulare programe Cell in Cluster
Programele pentru PPE si SPE folosesc compilatoare diferite. Scheletul de laborator ofer un exemplu
de structurare a fiierelor surs ale aplicaiei voastre. Recomandm folosirea de directoare separate,
ASC Wiki - http://cs.curs.pub.ro/wiki/asc/

Last update: 2014/04/06 23:09

asc:lab6:index

http://cs.curs.pub.ro/wiki/asc/asc:lab6:index

unul pentru codul i makefile-ul PPU-ului, i altul pentru programele SPU i makefile-ul acestora.

Programul PPE. Contexte SPE


n cazul aplicaiilor care sunt compuse din cod care ruleaza pe PPE si cod pentru SPE-uri, programele
PPE sunt cele care iniiaz i controleaz execuia programului(programelor) pentru SPE-uri. API-ul
pentru Cell BE pune la dispoziie structuri de date i funcii pentru lucrul cu contextele SPE. Practic,
programele SPE sunt executate n cadrul unor threaduri SPE care ruleaz ntr-un context, adic au
propriile registre SPU, propriul contor program (PC) i cozi MFC. Din cadrul unui context, thread-ul
unui SPE poate comunica cu alte SPE-uri, cu PPE-ul i cu memoria. De asemenea, este recomandat ca
programele/threadurile executate pe SPU-uri s se axeze pe folosirea capabilitilor de calcul vectorial,
i s nu conin foarte multe branch-uri (SPU-ul nu are branch predictor).
figure 3 prezint paii care sunt efectuai ntr-un program PPE pentru a executa contexte SPE. n
thread-ul principal al programului su PPE-ul utilizeaz thread-uri POSIX, pthreads, pentru a controla
contextele SPE.
1.
2.
3.
4.
5.
6.

PPU-ul creeaz thread-uri folosind pthread_create


PPU-ul creeaz contexte folosind spe_context_create
Programul SPE care trebuie s ruleze ntr-un context este dat folosind spe_program_load
Contextele se pornesc folosind spe_context_run
Se ateapt execuia thread-urilor folosind pthread_join
Dup terminarea execuiei contextelor, deci dup terminarea thread-urilor, se pot distruge
contextele folosind spe_context_destroy

n programul PPE se folosesc variabile de tip spe_context_ptr_t pentru contextul SPE i


pthread_t pentru thread-urile PPE-ului.

Fig. 3: Rularea programelor SPE

http://cs.curs.pub.ro/wiki/asc/

Printed on 2014/04/07 11:50

2014/04/07 11:50

5/14

Familiarizarea cu arhitectura CELL BE

De ce este nevoie de thread-uri pe PPE? pentru c funcia ce pornete contextele, spe_context_run,


este blocanta !
Ce se ntampl dup spe_context_run? Se transfer controlul sistemului de operare, care cere
planificarea efectiva a contextului pe un SPE fizic din sistem. Pe partea de planificare se urmeaz un
model M:N, n care M threaduri SPE sunt distribuite pe N SPU-uri, putnd de asemenea fi preemptate
(ns la intervale mai mari dect threadurile PPU). SPU-urile au o memorie local, Local Store, cu care
lucreaz direct, ele execut instruciuni i folosesc date doar din aceasta. Prin urmare, planificarea
contextului presupune i aducerea codul programului n Local Store-ul SPU-ului.
Variante declarare/folosire contexte:

n funcia thread-ului se pot crea, ncrca, porni i distruge contexte


n main sau n alt funcie se creeaz, ncarc i se dau ca parametru la crearea thread-ului

Exemplu cod PPU n care pornim pe un singur SPU un program care afieaz id-ul SPE-ului. Versiunea
complet a codului, i fiierele Makefile corespunztoare le gsii n scheletul acestui laborator.
void *ppu_pthread_function(void *thread_arg) {
spe_context_ptr_t ctx;
thread_arg_t *arg = (thread_arg_t *) thread_arg;
/* Create SPE context */
if ((ctx = spe_context_create (0, NULL)) == NULL) {
perror ("Failed creating context");
exit (1);
}
/* Load SPE program into context */
if (spe_program_load (ctx, &lab6_spu)) {
perror ("Failed loading program");
exit (1);
}
/* Run SPE context */
unsigned int entry = SPE_DEFAULT_ENTRY;
if (spe_context_run(ctx, &entry, 0, NULL, NULL, NULL) < 0) {
perror ("Failed running context");
exit (1);
}
/* Destroy context */
if (spe_context_destroy (ctx) != 0) {
perror("Failed destroying context");
exit (1);
}
pthread_exit(NULL);
}
int main()
{
ASC Wiki - http://cs.curs.pub.ro/wiki/asc/

Last update: 2014/04/06 23:09

asc:lab6:index

http://cs.curs.pub.ro/wiki/asc/asc:lab6:index

pthread_t thread;
if (pthread_create (&thread, NULL, &ppu_pthread_function, NULL))
perror ("Failed creating thread");
exit (1);
}
/* Wait for SPU-thread to complete execution.
if (pthread_join (thread, NULL)) {
perror("Failed pthread_join");
exit (1);
}

*/

}
Programul pentru SPE:
int main(unsigned long long speid, unsigned long long argp, unsigned long
long envp) {
printf("Hello World! from Cell with id (0x%llx)\n", speid);
return 0;
}

Programele PPU i SPU se compileaz pe maina Cell, pentru execuie trimitei de pe fep, cu qsub,
job-ul pe coada ibm-cell-qs22.q.

API contexte
Pentru a utiliza funciile pentru controlul contextelor trebuie inclus biblioteca libspe2:
#include <libspe2.h>
spe_context_create este funcia care creeaz i iniializeaz un context pentru un thread SPE
care conine informaie persistent despre un SPE logic. Funcia ntoarce un pointer spre noul context
creat, sau NULL n caz de eroare.
spe_context_ptr_t spe_context_create(unsigned int flags,
spe_gang_context_ptr_t gang)

flags - rezultatul aplicarii operatorului OR pe biti pe diverse valori (modificatori) ce se aplica la


crearea contextului. Valori acceptate:
0 - nu se aplic nici un modificator.
SPE_EVENTS_ENABLE - configureaz contextul pentru a permite lucrul cu evenimente (!Foarte
important pentru mailboxes; laboratorul urmator)
SPE_CFG_SIGNOTIFY1_OR - configureaz registrul 1 de SPU Signal Notification pentru a fi n
modul OR; default e in mod Overwrite (OR ntre noul semnal primit i cel deja existent, n loc de o
suprascriere)
SPE_CFG_SIGNOTIFY2_OR - analog SPE_CFG_SIGNOTIFY1_OR, pentru registrul 2 de SPU Signal
Notification

http://cs.curs.pub.ro/wiki/asc/

Printed on 2014/04/07 11:50

2014/04/07 11:50

7/14

Familiarizarea cu arhitectura CELL BE

SPE_MAP_PS - pentru cerere permisiune pentru acces mapat la memoria problem state area
(notata prescurtat PS) a threadului corespunzator SPE-ului. PS contine flagurile de stare pentru
SPEuri i n mod default nu poate fi accesat decat SPE-ul propriu, iar din exterior doar prin cereri
DMA. Dac acest flag e setat, se specific la crearea contextului c PPE vrea acces la memoria PS
a respectivului SPE.
gang - asociaz noul context SPE cu un grup(gang) de contexte, dac e NULL, noul context SPE nu
va fi asociat vreunui grup.

int spe_program_load(spe_context_ptr spe, spe_program_handle_t *program)

spe - contextul SPE n care se va ncarca executabilul


program - o adres valid la un program mapat pe un SPE. Poate fi declarat n cod ca extern
spe_program_handle_t simple_spu, unde simple_spu era numele executabilului pentru SPE.

int spe_context_destroy (spe_context_ptr_t spe)

spe - contextul SPE care va fi distrus.


ntoarce 0 in caz de succes, -1 n caz de eroare.

Trimiterea unor parametri de iniializare ctre SPE


Programul PPE-ului poate comunica cu programele SPE-urilor prin modalitile studiate n laboratorul
8 ( mailbox, transfer DMA, semnale), ns dac este nevoie s trimit doar 1-2 parametri la iniializare,
poate face acest lucru la pornirea contextului.
Funcia de pornire a execuiei contextului este:
#include <libspe2.h>
int spe_context_run(spe_context_ptr_t spe, unsigned int *entry, unsigned int
runflags, void *argp, void *envp, spe_stop_info_t *stopinfo)

spe - pointer ctre contextul SPE care trebuie rulat


entry - input: punctul de intrare, adic valoarea iniial a Intruction Pointer-ului de pe SPU, de unde
va ncepe programul execuia. Dac aceast valoare e SPE_DEFAULT_ENTRY, punctul de intrare va
fi obinut din imaginea de context SPE incarcat.
runflags - diferite flaguri (cu OR pe biti intre ele) care specific o anumit comportare n cazul
rulrii contextului SPE:
0 - default, nici un flag.
SPE_RUN_USER_REGS - registrele de setup r3, r4 si r5 din SPE vor fi iniializate cu 48 octei (16
pe fiecare din cei 3 regitrii) specificai de pointerul argp.
SPE_NO_CALLBACKS - SPE library callbacks pentru registre nu vor fi executate automat. Acestea
includ i PPE-assisted library calls oferite de SPE Runtime library.
argp - un pointer (opional) la date specifice aplicaiei. Este pasat SPE-ului ca al doilea argument din
main.
envp - un pointer (opional) la date specifice environmentului. Este pasat SPE-ului ca al treilea
argument din main.
stopinfo - un pointer (opional) la o structur de tip spe_stop_info_t. Aceasta structur
conine informaii despre modul n care s-a terminat execuia SPE-ului.

Parametrii argp i envp sunt transferai catre programul SPE. Funcia main a programului SPE
ASC Wiki - http://cs.curs.pub.ro/wiki/asc/

Last update: 2014/04/06 23:09

asc:lab6:index

http://cs.curs.pub.ro/wiki/asc/asc:lab6:index

primete trei parametri:


int main(unsigned long long speid, unsigned long long argp, unsigned long
long envp)

speid - identificatorul thread-ului SPE


argp (optional) - date primite de la PPE (argp-ul din spe_context_run)
envp (optional) - date primite de la PPE (envp-ul din spe_context_run)

Comunicare PPU - SPU-uri prin parametrii functiei main


Exemplu
...in programul PPE...
int i = 10;
if (spe_context_run(args->spe, &entry, 0, (void*)i, NULL, NULL) < 0)
....
...in programul SPE...
int main(unsigned long long speid, unsigned long long argp, unsigned long
long envp)
{
printf("Am primit %d\n", (int) argp);
}

Tipuri de date
PPU-ul i SPU-ul lucreaz att cu date scalare ct i cu date vector, ns tipurile de date i
instruciunile SIMD sunt diferite.

http://cs.curs.pub.ro/wiki/asc/

Printed on 2014/04/07 11:50

2014/04/07 11:50

9/14

Familiarizarea cu arhitectura CELL BE

Tipuri de date PPU


PPE-ul (PowerPC Processor Element) conine un procesor cu arhitectura PowerPC i cu o extensie de
instruciuni pentru calcul vectorial, Vector/SIMD Multimedia Extension. Astfel, pe lng tipurile de date
cu care lucreaz instruciunile PowerPC, procesorul suport i tipuri de date vector folosite de
instruciunile SIMD. ntr-un program PPU se pot amesteca instruciuni scalare cu instruciuni SIMD.
Din punct de vedere al arhitecturii, ca s suporte toate aceste instruciuni, procesorul conine:

3 uniti de calcul care funcioneaz concurent, una pentru operaii n virgul fix, una pentru
operaii n virgul mobil i una pentru operaii vectoriale
registre pentru uz general (32 x 64 bii), pentru operaii n virgul mobil (32 x 64 bii) i registre
pentru instruciuni vectoriale (32 x 128 bii). n registrele pentru instruciuni vectoriale se pun date
care au fost declarate de tip vector.

Datele de tip vector sunt utilizate de ctre operaiile SIMD, i au urmtoarele proprieti:

sunt aliniate in memorie la 16 Bytes


din date de tip scalar se poate face cast la un tip de date vector
dintr-un tip de date vector se poate face cast la un alt tip de date vector

vector
vector
vector
vector
vector
vector
vector
vector
vector
vector
vector
vector
vector
vector

Tipul de date
Descriere
Valori
unsigned char
16 x valori fara semn pe 8 bii 0 255
signed char
16 x valori fara semn pe 8 bii -128 127
bool char
16 x valori boolene pe 8 bii 0 (false), 255 (true)
unsigned short
8 x valori fara semn pe 16 bii 0 65535
unsigned short int 8 x valori fara semn pe 16 bii 0 65535
signed short
8 x valori cu semn pe 16 bii -32768 32767
signed short int 8 x valori cu semn pe 16 bii -32768 32767
bool short
8 x valori boolene pe 16 bii 0 (false), 65535 (true)
bool short int
8 x valori boolene pe 16 bii 0 (false), 65535 (true)
unsigned int
4 x valori fara semn pe 32 bii 0 232 - 1
signed int
4 x valori cu semn pe 32 bii -232 232 - 1
bool int
4 x valori fara semn pe 32 bii 0 (false), 232 - 1 (true)
float
4 x 32-biti single precision
IEEE-754 values
pixel
8 x valori cu semn pe 16 bii 1/5/5/5 pixel

PPE-ul suport doar modul big-endian pentru ordonarea octeilor tuturor tipurilor de date, ceea ce
nseamn c byte-ul cel mai semnificativ este byte-ul 0, cum este ilustrat i n imaginea urmtoare,
pentru date de tip vector:

ASC Wiki - http://cs.curs.pub.ro/wiki/asc/

Last update: 2014/04/06 23:09

asc:lab6:index

http://cs.curs.pub.ro/wiki/asc/asc:lab6:index

Tipuri de date SPU


SPU-ul, procesorul din SPE, are o arhitectur SIMD, iar instruciunile i tipurile de date sunt diferite de
cele ale PPU-ului. Majoritatea instruciunilor lucreaz cu operanzi de tip vector, ns unele suport i
operanzi scalari. SPU-ul lucreaz cu 128 de registre a 128 de bii.
Tipurile de date scalare pentru SPU sunt:

Byte 8 bii
Halfword 16 bii
Word 32 bii
Doubleword 64 bii
Quadword 128 bii

SPU-ul suport o parte din tipurile de date vector suportate i de PPU, la care se adaug cateva tipuri
corespunztoare unor valori de mai mult de 32 de bii (n limita a 128 bii, e.g. vector double care are
dou valori pe 64 de bii).

vector
vector
vector
vector
vector
vector
vector
vector
vector
vector
qword

Tipul de date
Descriere
unsigned char
16 x valori fara semn pe 8 bii
signed char
16 x valori fara semn pe 8 bii
unsigned short
8 x valori fara semn pe 16 bii
signed short
8 x valori cu semn pe 16 bii
unsigned int
4 x valori fara semn pe 32 bii
signed int
4 x valori cu semn pe 32 bii
unsigned long long 2 x 64-bit unsigned doublewords
signed long long 2 x 64-bit signed doublewords
float
4 x 32-bit single-precision floating-point numbers
double
2 x 64-bit double-precision floating-point numbers
quadword (16-byte)

Atunci cnd pe SPU se utilizeaz scalari, acetia sunt stocai n registre conform unei poziii indicate
de ctre preferred scalar spot, aa cum este ilustrat n figura urmtoare:

http://cs.curs.pub.ro/wiki/asc/

Printed on 2014/04/07 11:50

2014/04/07 11:50

11/14

Familiarizarea cu arhitectura CELL BE

Alinierea datelor
Pentru a crea variabile vector sau array-uri de variabile vector din array-uri de scalari, trebuie inut
cont de alinierea acestora n memorie. SPE i PPE folosesc vectori de 128 de bii pentru instruciuni
SIMD. Pentru a putea utiliza instruciunile SIMD (Single Instruction Multiple Data), arhitectura Cell are
nevoie de o anumit poziionare a datelor n memorie, i anume, acestea trebuie s fie aliniate n
memorie la o limit de 16 bytes (quadword) sau multiplu de 16 bytes.
Astfel, array-urile create n programul PPE i SPE trebuie s fie aliniate la adrese multiplu de 16 octei
folosind keyword-ul __attribute__((aligned(16))) (n cazul alocrii statice)
int v[16] __attribute__((aligned(16)));
Ca alinierea s funcioneze, variabila trebuie s fie global sau local funciei, dar static, deoarece
alocarea normal pe stiv se face la runtime.
Pentru date alocate dinamic, folosim funciile malloc_align i free_align din libmisc.h (+
biblioteca libmisc.a - trebuie inclus flagul -lmisc) pentru alocare aliniat, astfel:
input = (float*)malloc_align(N*sizeof(float),7); // aliniere la 2^7 = 128
bytes

SPU intrinsics
Att PPU-ul ct i SPU-ul suport seturi de instruciuni pentru calcule vectoriale (SIMD), iar API-ul de C
pentru Cell-BE ofer dou seturi de funcii, intrinsics, ca wrappere peste aceste instruciuni. n cadrul
acestui laborator ne axm pe lucrul cu operaiile vectoriale pe SPE-uri.
Toate funciile pentru SPU ncep cu spu_(mapare 1:n cu instr assembler) sau si_(mapare 1:1 cu
instruciuni assembler), n timp ce cele pentru PPU ncep cu vec_. Pentru a folosi funciile SPU-ului
trebuie inclus biblioteca spu_intrinsics.
#include <spu_intrinsics.h>
Tabelele urmtoare conin o parte din funciile folosite pentru operaii cu date de tip vector. Lista
complet acestora o putei gsi n documentaie, i include i funcii ce nu in direct de lucrul cu
vectori.
Operaii aritmetice, logice i de control:
Funcie
spu_add(a, b)
spu_sub(a, b)
spu_mul(a, b)
ASC Wiki - http://cs.curs.pub.ro/wiki/asc/

Descriere
a+b, a i b de tip vector
a-b, a i b de tip vector
a*b, a i b de tip vector float/double

Last update: 2014/04/06 23:09

asc:lab6:index

http://cs.curs.pub.ro/wiki/asc/asc:lab6:index

spu_madd(a, b, c)
a*b + c, a, b, c de tip vector
spu_nmadd(a, b, c)
-a*b - c, a, b, c de tip vector
spu_msub(a, b, c)
a*b - c, a i b de tip vector
spu_nmsub(a, b, c)
-(a*b - c), a i b de tip vector
spu_avg(a, b)
byte average(a,b), a i b de tip vector
spu_and(a, b), spu_nand(a,b) a and b, not(a and b), a i b de tip vector
spu_or(a, b), spu_nor(a,b) a or b, not(a or b) , a i b de tip vector
spu_xor(a, b)
a xor b, a i b de tip vector
spu_cmpeq(a, b)
compara a==b, a i b de tip vector
spu_cmpgt(a, b)
compara a>b, a i b de tip vector
Rezultatele intoarse de aceste funcii sunt tot variabile de tip vector. Nu toate tipurile de vector pot fi
folosite pentru toate operaiile, verificai documentaia nainte de a le folosi.
n locul apelrii funciilor, se pot folosi i operatorii +,-,*,/.
Exist funcii pentru lucru cu scalari i vectori, dar i funcii ce opereaz pe elementele dintr-o
variabila vector.
Funcie
Descriere
d = spu_splats(a)
se replic scalarul a ntr-un vector d
d = spu_extract(a, element) sau
se extrage un element scalar din vector
d = a[element]
d = spu_insert(a, b, element) sau
se insereaz scalarul a pe poziia element n vector b
b[element] = a
se transform scalarul a ntr-o variabil vector d,
d = spu_promote(a, element)
punndu-l pe poziia element

Exemple vectorizare
Exemplu de cast de la un array de scalari la un array de vectori:
unsigned int a1[8] = {10, 20, 30, 40, 50, 60, 70, 80};
vector unsigned int *v1 = (vector unsigned int *)a1;
Exemplu de vectorizare a unei bucle, n care, datorit faptul c folosim variabile vector, se fac mai
puine operaii/iteraii.
#define N 8
...
unsigned int a[N] __attribute__ ((aligned(16))) = {10, 20, 30, 40, 50, 60,
70, 80};
unsigned int b[N] __attribute__ ((aligned(16))) = {1, 2, 3, 4, 5, 6, 7, 8};
unsigned int c[N] __attribute__ ((aligned(16)));
....
/* lucru cu scalari */
http://cs.curs.pub.ro/wiki/asc/

Printed on 2014/04/07 11:50

2014/04/07 11:50

13/14

Familiarizarea cu arhitectura CELL BE

for (i = 0; i < N; i++){


c[i] = a[i] + b[i];
}
/* lucru cu vectori */
vector unsigned int *va = (vector unsigned int *) a;
vector unsigned int *vb = (vector unsigned int *) b;
vector unsigned int *vc = (vector unsigned int *) c;
int n = N/(16/sizeof(unsigned int));
for (i = 0; i < n; i++){
// N/4 iteraii
vc[i] = va[i] + vb[i]; // putea fi folosit si vc[i] = spu_add(va[i],
vb[i])
}
int i;
for (i=0; i<N; i+=4)
printf("%d %d %d %d ", c[i], c[i+1], c[i+2], c[i+3]);
Dac n exemplul anterior dimensiunea vectorilor nu era multiplu de 4, atunci restul elementelor
trebuia nmulite ca scalari sau fcut 'padding' la vectori.

Exerciii
Primele dou exerciii se vor testa local (compilai cu flag-ul -lpthread), restul pe Cell. Scheletul
de laborator este pentru exerciiile de Cell. Pentru Cell compilai folosind Makefile-ul din
rdcina arhivei.
1. (2p) Folosind phtreads scriei un program in C ce afieaz Hello World! din fiecare thread.
Creai 10 astfel de threaduri.
man 3 pthread_create
man 3 pthread_join
man 3 pthread_exit
Hint: vedei i exemplul de cod din laborator, de la PPU, unde se creaz un thread.
Hint: despre Thread-uri Linux puteti citi i n laboratorul 8 SO
2. (1p) Modificai programul anterior pentru a permite transferul de parametri catre thread. Definii
structura thread_param cu cmpul index de tip int. Trimitei fiecarui thread indexul su folosind
aceast structur. Metoda thread-ului va avea ca parametru aceasta structura.
3. (3p) Scheletul de cod conine un program ppu i un program spu. Programul lab6_ppu porneste
un context SPU, iar programul lab6_spu afieaz id-ul acestuia. Modificai codul PPU-ului astfel
nct s porneasc acelai program pe toate SPU-urile.
Hint: putei afla numrul de SPE-uri folosind: spe_cpu_info_get(SPE_COUNT_USABLE_SPES,
-1);
4. (2p) Modificai codul de la exerciiul anterior astfel nct s transmitei fiecrui SPE un index.
Programul SPE-ului va afisa indexul primit.
transmiterea parametrilor este descris n seciunea Trimiterea unor parametri de initializare
catre spe
5. (2p) Lucrul cu tipuri vector i operaiile vectoriale: n programul pentru SPE din scheletul de cod
avei declarae 3 array-uri. Convertii aceste array-uri la tipul vector i efectuai urmtoarele

ASC Wiki - http://cs.curs.pub.ro/wiki/asc/

Last update: 2014/04/06 23:09

asc:lab6:index

http://cs.curs.pub.ro/wiki/asc/asc:lab6:index

operaii pe acestea:
a) scalai valorile array-ul A cu 0.5, salvnd rezultatul n array-ul B
b) comparai array-urile B i C i afiai rezultatul comparaiei.
Hint: vedei exemplul de transformare dintr-un array de scalari ntr-un array de vectori din
subseciunea Exemple Vectorizare
Hint: pentru operaia de comparare folosii o funcie descris n tabelul din seciunea SPU
Intrinsics
pentru a observa output-ul mai uor, este suficient s rulai exerciiul acesta doar pe 1-2 SPE-uri.

Resurse

Responsabilul acestui laborator: Adriana Drghici


PDF laborator
Tutorial Cell - Rulare programe Cell in Cluster
Schelet laborator
Soluie laborator

Referine

Practical Computing on the Cell Broadband Engine - carte foarte util pentru descrierea arhitecturii
i a modului de programare pe Cell
Cell BE Programming Tutorial - n capitolul 3 gsii lista de C/C++ instrinsics.
SPE Runtime Management Library
Cell BE Programming Handbook Including PowerXCell 8i
SIMD Math Library Specification for Cell BE
IBM Cell Redbook, searchable
Informaii adiionale despre arhitectura CELL BE
Documentaia este disponibil i local pe masinile cell in /opt/cell/sdk/docs nsoit de
exemple in /opt/cell/sdk/src/*.tar

From:
http://cs.curs.pub.ro/wiki/asc/ - ASC Wiki
Permanent link:
http://cs.curs.pub.ro/wiki/asc/asc:lab6:index
Last update: 2014/04/06 23:09

http://cs.curs.pub.ro/wiki/asc/

Printed on 2014/04/07 11:50

S-ar putea să vă placă și