Documente Academic
Documente Profesional
Documente Cultură
1/14
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/
2014/04/07 11:50
3/14
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/
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.
http://cs.curs.pub.ro/wiki/asc/
2014/04/07 11:50
5/14
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/
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)
http://cs.curs.pub.ro/wiki/asc/
2014/04/07 11:50
7/14
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.
Parametrii argp i envp sunt transferai catre programul SPE. Funcia main a programului SPE
ASC Wiki - http://cs.curs.pub.ro/wiki/asc/
asc:lab6:index
http://cs.curs.pub.ro/wiki/asc/asc:lab6:index
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/
2014/04/07 11:50
9/14
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:
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:lab6:index
http://cs.curs.pub.ro/wiki/asc/asc:lab6:index
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/
2014/04/07 11:50
11/14
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
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/
2014/04/07 11:50
13/14
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: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
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/