Elprocessament de fluxos és un paradigma deprogramació computacional, equivalent a laprogramacio amb flux de dades,processament de flux d'esdeveniments,[1] iprogramació reactiva, que permet a algunes aplicacions explotar més fàcilment una forma limitada deprocessament paral·lel. Tals aplicacions poden utilitzar unitats computacionals múltiples, com lesFPUs en unGPU ofield programmable gate arrays (FPGAs), sense una assignació de control explicita, sincronització, o comunicació entre les unitats.
El paradigma de processament de fluxos simplifica la paral·lelització del programari i maquinari amb la restricció de la computació paral·lela que es pot realitzar. Donada una seqüència de dades (stream), una sèrie d'operacions (funcions del nucli), s'aplican a cada element de la seqüència.El flux uniforme, on un nucli de la funció s'aplica a tots els elements del flux, és típic. Les funcions del nucli solen ser en canonada, i la memòria local del chip és reutilitzada per a minimitzar l'amplada de banda de la memòria externa. Des del nucli i el flux d'abstraccions exposen les dependències de dades, les eines de compilació poden automatitzar completament i optimitzar les tasques de gestio del chip. El processament de fluxos pot utilitzaralgorismes marcadors, per exemple, per al llançament deDMAs en temps d'execució, quan les dependències són conegudes. L'eliminació de l'administrador de DMA manual redueix la complexitat programari, i l'eliminació de les caches de maquinari redueix la quantitat d'area no dedicada a unitats computacionals com lesALUs.
Durant la dècada de 1980 el flux de processament va ser explorat enprogramació de flux de dades. Un exemple és el llenguatje SISAL (Corrents d'Iteració en una Sola Assignació de Llengua).
El processament de dades és essencialment un compromis, conduït per un model centrat en dades que treballa molt bé per aplicacions tipus GPU o DSP (com imatge, vídeo i processament de senyal digital) però menys per a aquelles de processament de propòsit general amb més accésos de dada aleatoris (com bases de dades). Sacrificant flexibilitat en el model, les implicacions es tornes més fàcils, amb una execució més ràpida i eficaç. Depenent del context, el disseny delprocessador pot ser modificat per obtenir eficàcia màxima o una gran flexibilitat.
El processament de fluxos és especialment adequat per aplicacions que contenen aquestes 3 característiques:
Exemples dels rècords dins de corrents inclouen:
Per cada referència només podem llegir de l'entrada, fer operacions amb aquestes dades, i escriure a la sortida. Podem tenir entrades múltiples i sortides múltiples, però mai un troç de memòria que es pugui llegir i escriure.
Els ordinadors bàsics van començar d'un paradigma d'execució seqüencial. LesCPUs tradicionals estan basades enSISD, el qual significa que conceptualment fan només una operació a la vegada. Mentre les necessitats informàtiques han anat evolucionant, la quantitat de dades a ser tractades augmenta molt de pressa. Va resultar obvi que el model de programació seqüencial no podria suportar la necessitat de més capacitat de processament. S'han produït diversos esforços per trobar maneres alternatives per actuar amb quantitats massives de dades computacionals però l'única solució era explotar algun nivell d'execució paral·lela. El resultat d'aquells esforços van ser el SIMD, un paradigma de programació que va permetre aplicar una instrucció a casos múltiples de (diferent) dades. Gairebé sempre, SIMD era utilitzat en un entorn deSWAR. Per utilitzar estructures més complexes, també es podria utilitzar paral·lelismeMIMD.
Encara que aquests dos paradigmes eren eficients, les implementacions del món real estaven plenes de limitacions des d'alineament de memoria a problemes de sincronització i el paral·lelisme limitat. Només uns pocs processadors SIMD van sobreviure com a components independents; la majoria van ser incrustats en les CPU estàndard.
Penseu un programa simple suma de dues matrius que contenen 100vectors de 4 components (és a dir 400 números en total).
for(inti=0;i<100*4;i++)result[i]=source0[i]+source1[i];
Aquest es el paradigma sequencial mes comú. Existeixesn variants (com bucles interns i altres estructures), però en última instància es redueixen a aquesta estructura.
for(intel=0;el<100;el++)// for each vectorvector_sum(result[el],source0[el],source1[el]);
Això esta simplificat. Asumeix que la instruccióvector_sum funciona. Tot i que això és el que succeeix amb lescaracterístiques intrínseques d'instrucció, molta de la informació en realitat no es te en compte com el nombre de components de vector i el seu format de dades. Això es fa per a major claredat.
Es pot veure però, aquest mètode redueix el nombre d'instruccions descodificades de numElements * componentsPerElement a numElements. El nombre d'instruccions de salt també es redueix, ja que el bucle s'executa menys vegades. Aquestes millores són el resultat de l'execució paral·lela de les quatre operacions matemàtiques.
El que va passar però, és que el registre SIMD empaquetat té una certa quantitat de dades, de manera que no és possible obtenir més paral·lelisme. La velocitat és una mica limitada per la suposició de que hem fet quatre operacions paral·leles (tingueu en compte que això és comú per a tots dosAltiVec iSSE).
// This is a fictional language for demonstration purposes.elements=arraystreamElement([number,number])[100]kernel=instancestreamKernel("@arg0[@iter]")result=kernel.invoke(elements)
En aquest paradigma, es defineix el conjunt de dades, en lloc de cada bloc de components sent definit per separat. Descrivim el conjunt de dades en les dues primeres files. Després d'això, el resultat s'infereix de les fonts i el nucli. Per simplicitat, hi ha un mapejat 1: 1 entre les dades d'entrada i sortida, però això no té per què ser així. Els nuclis aplicats poden ser molt més complexos.
Una implementació d'aquest paradigma pot "desenrotllar" un bucle intern. Això permet que el rendiment escali fàcilment amb la complexitat de xip utilitzant centenars de ALUs.[2][3] L'eliminació de patrons de dades complexes fa que gran part d'aquesta energia addicional estigui disponible.
Tot i que el processament de flux és una branca de processament SIMD / MIMD, no s'han de confondre entre elles. Tot i que les implementacions de SIMD poden treballar usualment com a "flux", el seu rendiment no és comparable: el model preveu un patró d'ús molt diferent que permet molt més rendiment per si mateix. S'ha observat que quan aquest s'aplica en els processadors genèrics com ara CPU estàndard, només un augment de velocitat 1,5x pot ser assolit.[4] Per contra, processadors de flux ad-hoc arriben fàcilment a obtenir sobre 10x de rendiment, això s'atribueix principalment a l'accés a memòria més eficient i més alts nivells de processament en paral·lel.[5]
Encara que hi ha diversos graus de flexibilitat permesa pel model, els processadors de flux generalment imposen algunes limitacions en la mida del nucli o ample del flux. Per exemple, el maquinari del consumidor sovint no té la capacitat de realitzar operacions matemàtiques d'alta precisió, no té cadenes de indirecció complexes o presenta límits inferiors sobre el nombre d'instruccions que poden ser executades.
Entre els projectes de processament de flux de laUniversitat Stanford s'inclouen "Stanford Real-Time Programmable Shading Project" el cual va començar al 1999.[6] Un prototip anomenat Imagine[7] que es va desenvolupar a l'any 2002. Un projecte anomenat Merrimac va funcionar fins al voltant de 2004.[8]AT&T també va investigar processadors de flux millorada com lesunitats de processament gràfic evolucionat ràpidament, tant en velocitat i funcionalitat. Des d'aquests primers dies dels llenguatges de processament de flux dotzenes s'han desenvolupat, així com maquinari especialitzat.
El repte més immediat en l'àmbit de processament en paral·lel no resideix tant en el tipus d'arquitectura de maquinari utilitza sino en quant fàcil serà programar el sistema en qüestió en un entorn real amb un rendiment acceptable. Màquines com Imagine utilitzen un model d'un sol fil amb dependències automatitzades, assignació de memòria i programació de DMA. Això en si mateix és el resultat de la investigació al MIT i Stanford a la recerca d'una superposició de tasques 'òptima' entre el programador, eines i maquinari. Els programadors van superar a les eines en algoritmes de mapeig per paral·lelitzar el maquinari, i les eines van superar als programadors a l'hora d'esbrinar els esquemes més intel·ligents d'assignació de memòria, etc. En concret els dissenys MIMD com araCell, per als quals el programador necessita fer front a la partició d'aplicació a través de múltiples nuclis i tractar amb sincronització de processos i l'equilibri de càrrega. Les eines de programació multi-nucli eficients d'avui no tenen prou avanç.
Un inconvenient de la programació SIMD es el tema de laMatriu de Estructures (MdE) i també el deestructura de matrius (EdM). Els programadors sovint volien construir estructures de dades amb un significat 'real', per exemple:
// A particle in a three-dimensional space.structparticle_t{floatx,y,z;// not even an array!unsignedbytecolor[3];// 8 bit per channel, say we care about RGB onlyfloatsize;// ... and many other attributes may follow...};
El que va passar és que aquestes estructures van ser acoblades en matrius per mantenir les coses ben organitzades. Això ésmatriu d'estructures (AOS). Quan l'estructura es presenta en la memòria, el compilador produirà dades entrellaçades, en el sentit que totes les estructures seran contigües, però que hi haurà un desplaçament entre elles, per exemple, l'atribut "mida" d'una instància d'estructura i el mateix constant de la següent instància. El desplaçament depèn de la definició de l'estructura (i possiblement altres coses no es considera aquí com les polítiques del compilador). També hi ha altres problemes. Per exemple, les tres variables de posició no es poden vectoritzar en SIMD d'aquesta manera, perquè no és segur que s'assignaran a l'espai de memòria contínua. Per fer operacions SIMD per poder-hi treballar, s'agruparan en una 'posició de memòria packed' o almenys en una matriu. Un altre problema és tant "color" com "xyz" que es definiran en quantitats vectorials de tres components. Els processadors SIMD generalment tenen suport per a operacions de només 4 components (amb algunes excepcions però).Aquest tipus de problemes i limitacions van fer SIMD acceleració en les CPU estàndard bastant desagradables. La solució proposada, l'estructura de les matrius (SOA) segueix com:
structparticle_t{float*x,*y,*z;unsignedbyte*colorRed,*colorBlue,*colorGreen;float*size;};
Per als lectors no experimentats amb C, el '*' abans de cada identificador significa un punter. En aquest cas, es poden utilitzar per apuntar al primer element d'una matriu, que ha de ser assignat més tard. Per als programadors deJava, això és més o menys equivalent a "[]". L'inconvenient aquí és que els diversos atributs podrien estendre a la memòria. Per assegurar que això no causa fallades de memòria caché, haurem d'actualitzar tots els diversos "Red", llavors tots els "Green" i "Blue".
Per processadors de flux, es recomana l'ús d'estructures. Des del punt de vista d'aplicació, tots els atributs es poden definir amb certa flexibilitat. Prenent com a referència les GPU, hi ha un conjunt d'atributs (almenys 16) disponible. Per a cada atribut, l'aplicació pot indicar el nombre de components i el format dels components (però només els tipus de dades primitius són suportats ara per ara). Els diversos atributs s'uneixen llavors a un bloc de memòria, possiblement definint un salt entre els elements 'consecutius' dels mateixos atributs, el que permet intercalar dades efectivament. Quan la GPU comença el processament de flux, reunirà els diversos atributs en un únic conjunt de paràmetres (en general això s'assembla a una estructura o una "variable global màgica"), porta a terme les operacions i dispersa els resultats a una àrea de memòria per a processar-la més endavant (o recuperar-la).
Més marcs de processament de flux moderns proporcionen una interfície similar a la FIFO per estructurar les dades com un flux continu. Aquesta abstracció proporciona un mitjà per especificar les dependències de dades de forma implícita al mateix temps que permet el temps d'execució i al maquinari poder treure el màxim profit d'aquest coneixement per a la computació eficient. Una de les modalitats de processament de flux més simples i més eficients fins a la data per a C ++, ésRaftLib.RaftLib permet la vinculació dels nuclis de còmput independents junts com un gràfic de flux de dades usant operadors de flux C ++. Com un exemple:
#include<raft>#include<raftio>#include<cstdlib>#include<string>classhi:publicraft::kernel{public:hi():raft::kernel(){output.addPort<std::string>("0");}virtualraft::kstatusrun(){output["0"].push(std::string("Hello World\n"));return(raft::stop);}};intmain(intargc,char**argv){/** instantiate print kernel **/raft::print<std::string>p;/** instantiate hello world kernel **/hihello;/** make a map object **/raft::mapm;/** add kernels to map, both hello and p are executed concurrently **/m+=hello>>p;/** execute the map **/m.exe();return(EXIT_SUCCESS);}
A més d'indicar les aplicacions de flux en un llenguatge d'alt nivell, els models de càlcul (MdC) també han estat àmpliament utilitzats com a models de flux de dades i models basats en processos.
Històricament, les CPU van començar a aplicar diferents nivells d'optimitzacions d'accés a memòria, a causa del cada vegada major rendiment en comparació amb un creixement relativament lent de l'amplada de banda de la memòria externa. Com es va ampliar aquesta separació, grans quantitats de l'àrea es van dedicar a amagar les latències de memòria. Ja que anar a buscar la informació i codis d'operació als pocs ALU és car, molt poca àrea es dedica a la maquinària matemàtica real (com una estimació aproximada, consideren que és menys del 10%).
Una arquitectura similar existeix en processadors de flux, però gràcies al nou model de programació, la quantitat de transistors dedicada a la gestió és en realitat molt baixa.
Començant des d'un punt de tot el sistema de vista, els processadors de flux generalment existeixen en un entorn controlat. Les GPU les trobem com una placa de complement. Les CPU fan la feina bruta de la gestió dels recursos del sistema, executant aplicacions i demés.
El processador de flux està generalment equipat amb un bus ràpid, eficient, i de memòria pròpia (els interruptors creuats ara són comuns, els busos múltiples es feien servir en el passat). La quantitat exacta de vies de memòria depèn de la gamma del mercat. Tal com està escrit, encara hi ha interconnexions de 64 bits d'ample (nivell d'entrada). La majoria dels models de gamma mitjana utilitzen una matriu ràpida de 128 bits (4 o 2 segments), mentre que els models de gamma alta despleguen enormes quantitats de memòria (en realitat fins a 512 MB) amb un interruptor creuat lleugerament més lent que és de 256 bits d'ample. Per contra, els processadors estàndard d'Intel Pentium o algunsAthlon 64 només tenen un únic bus de dades de 64 bits d'ample.
Els patrons d'accés de memòria són molt més predictibles. Encara que existeixen matrius, la seva dimensió es fixa en la invocació del nucli. La cosa que més s'apropa a un adreçament indirecte de punter múltiple és una cadena indirecta, però, que es garanteix per llegir o escriure, finalment, d'una àrea de memòria específica (dins d'un flux).
Per la naturalesa SIMD de les unitats d'execució del processador de flux (clústers ALU), de lectura/escriptura S'espera que les operacions passin en paquets, de manera que la memòria estigui optimitzada per a una gran amplada de banda en lloc de baixa latència (això és una diferència respecte aRambus iDDR SDRAM, per exemple). Això també permet negociacions eficients del bus de memòria.
La major part (90%) d'un treball d'un processador de flux es realitza en el xip, requerint només 1% de les dades globals per a ser emmagatzemats en la memòria. Això és on conèixer els temporals del nucli i les dependències ens pot ajudar.
Internament, un processador de flux compta amb alguns circuits de comunicació i gestió intel·ligents, però el que és interessant és elStream Register File (SRF). Això és conceptualment una gran caché en què s'emmagatzemen les dades per a ser transferides a la memòria externa en paquets. Com una estructura controlada per programari de memòria caché similar a les diversosALU, la SRF és compartida entre tots els diferents grups d'ALU. El concepte clau i la innovació aquí, fetes amb xips Imagine de Stanford és que el compilador és capaç d'automatitzar i assignar memòria de forma òptima, totalment transparent per al programador. Les dependències entre les funcions del nucli i les dades es coneix a través del model de programació que permet que el compilador dugui a terme anàlisis de flux i de manera òptima empaquetar els SRFs. Comunament, aquesta memòria caché i la gestió de DMA poden ocupar la major part de la programació d'un projecte, cosa que el processador de flux (o almenys Imagine) automatitza totalment. Les proves realitzades a Stanford van demostrar que el compilador va fer un treball tan bo o millor en la memòria de programació que s'afinés personalment amb molt d'esforç.
Hi ha proves; no pot haver-hi una gran quantitat d'agrupacions perquè la comunicació inter-cluster se suposa que és estranya. Però internament, cada grup pot explotar de manera eficient una quantitat molt menor de ALUs perquè la comunicació intra-cluster és comú i, per tant, ha de ser altament eficient.
Per mantenir aquests ALU en comunicació amb les dades, cada ALU està equipada amb arxius de registre local (ARL), que són bàsicament els seus registres utilitzables.
Aquest patró d'accés a dades de tres nivells, fa que sigui fàcil de mantenir les dades temporals lluny de memòries lentes, de manera que l'aplicació de silici té una alta eficiència i estalvi d'energia.
Malgrat un ordre de magnitud d'acceleració pot ser raonablement esperat (fins i tot de les GPU corrents quan es calcula mitjançant transmissió), no totes les aplicacions es beneficien d'això. Les latències de comunicació són en realitat el problema més gran. Encara quePCI Express va millorar això amb les comunicacions full-duplex, fer servir una GPU (i, possiblement, un processador de fluxos genèric) nescessitara possiblement treballar durant llargs períodes. Això vol dir que en general és contraproduent usar-los per a petits conjunts de dades. A causa que el canvi del nucli és una operació bastant costosa l'arquitectura de flux també te sancions per petits fluxos, un comportament conegut com l'efecte del flux curt.
Pipelining és una pràctica molt estesa i molt utilitzada en processadors de flux, la GPU que ofereix pipelines de més de 200 etapes. El cost per canviar la configuració depèn de la configuració que ha de ser modificada, però ara es considera que és sempre costós. Per evitar aquests problemes en els diferents nivells de la canonada, moltes tècniques s'han desplegat com "shaders über" i "texture atlases". Aquestes tècniques estan enfocades a jocs per la naturalesa de les GPU, però els conceptes són interessants per al processament de flux genèric també.
La majoria dels llenguatges de programació per a processadors de flux comencen amb Java, C ++ o C i afegeixen extensions que proporcionen instruccions específiques per permetre que els desenvolupadors d'aplicacions puguin etiquetar els nuclis i / o fluxos de dades. Això també s'aplica allenguatges de ombrejat, que es poden considerar llenguatges de programació de flux fins a un cert punt.
Exemples de llenguatges de programació de fluxos no comercials poden ser:
Les implementacions comercials són, o bé de proposit general o lligats a un maquinari específic que aporta el proveïdor. Exemples de llenguatges de proposit general poden ser:
Llenguatges específics del proveïdor inclouen:
Processament basat en arxius per lots (emula alguns de processament de fluxos real, però amb un objectiu de rendiment molt més baix en general)
Serveis de proessament de flux: