Procesare flux - Stream processing

Procesarea fluxului este oparadigmă de programare computerizată , echivalentă cu programarea fluxului de date , procesarea fluxului de evenimente și programarea reactivă , care permite unor aplicații să exploateze mai ușor o formă limitată de procesare paralelă . Astfel de aplicații pot utiliza mai multe unități de calcul, cum ar fi unitatea cu virgulă mobilă pe o unitate de procesare grafică sau tablouri de poartă programabile pe câmp (FPGA), fără a gestiona în mod explicit alocarea, sincronizarea sau comunicarea între acele unități.

Paradigma de procesare a fluxurilor simplifică software-ul și hardware-ul paralel prin restricționarea calculului paralel care poate fi efectuat. Având în vedere o secvență de date (un flux ), o serie de operații ( funcțiile kernel ) se aplică fiecărui element din flux. Funcțiile kernelului sunt, de obicei , canalizate și se încearcă reutilizarea optimă a memoriei locale pe cip, pentru a minimiza pierderea lățimii de bandă, asociată cu interacțiunea cu memoria externă. Fluxul uniform , unde o funcție de nucleu este aplicată tuturor elementelor din flux, este tipică. Deoarece abstracțiile kernelului și fluxului expun dependențe de date, instrumentele de compilare pot automatiza și optimiza pe deplin sarcinile de gestionare pe cip. Hardware-ul de procesare a fluxului poate utiliza tabloul de bord , de exemplu, pentru a iniția un acces direct la memorie (DMA) atunci când dependențele devin cunoscute. Eliminarea gestionării manuale a DMA reduce complexitatea software-ului, iar o eliminare asociată pentru I / O în cache a hardware-ului, reduce extinderea ariei de date care trebuie implicată cu serviciul de către unitățile de calcul specializate, cum ar fi unitățile logice aritmetice .

În anii 1980, procesarea fluxului a fost explorată în cadrul programării fluxului de date . Un exemplu este limba SISAL (Fluxuri și iterații într-o singură limbă de atribuire).

Aplicații

Procesarea fluxului este în esență un compromis, condus de un model centrat pe date care funcționează foarte bine pentru aplicațiile tradiționale de tip DSP sau GPU (cum ar fi procesarea imaginii, a videoclipului și a semnalului digital ), dar mai puțin pentru procesarea scopurilor generale, cu acces mai randomizat la date ( precum baze de date). Prin sacrificarea unor flexibilități în model, implicațiile permit o execuție mai ușoară, mai rapidă și mai eficientă. În funcție de context, designul procesorului poate fi reglat pentru o eficiență maximă sau un compromis pentru flexibilitate.

Procesarea fluxului este potrivită în special pentru aplicații care prezintă trei caracteristici ale aplicației:

  • Calculați intensitatea , numărul de operații aritmetice per I / O sau referință de memorie globală. În multe aplicații de procesare a semnalului, astăzi este mult peste 50: 1 și crește odată cu complexitatea algoritmică.
  • Paralelismul de date există într-un kernel dacă aceeași funcție este aplicată tuturor înregistrărilor unui flux de intrare și un număr de înregistrări pot fi procesate simultan fără a aștepta rezultatele din înregistrările anterioare.
  • Localitatea datelor este un tip specific de localitate temporală obișnuită în aplicațiile de procesare a semnalului și a mass-media în care datele sunt produse o dată, citite o dată sau de două ori mai târziu în aplicație și nu se mai citesc niciodată. Fluxurile intermediare transmise între nuclee precum și datele intermediare din cadrul funcțiilor nucleului pot capta această localitate direct folosind modelul de programare a procesării fluxului.

Exemple de înregistrări din fluxuri includ:

  • În grafică, fiecare înregistrare ar putea fi vârful, informațiile normale și culorile pentru un triunghi;
  • În procesarea imaginii, fiecare înregistrare ar putea fi un singur pixel dintr-o imagine;
  • Într-un codificator video, fiecare înregistrare poate avea 256 de pixeli formând un macrobloc de date; sau
  • În procesarea semnalului fără fir, fiecare înregistrare ar putea fi o secvență de probe primite de la o antenă.

Pentru fiecare înregistrare putem citi numai de la intrare, putem efectua operații pe ea și scriem la ieșire. Este permis să aveți mai multe intrări și ieșiri multiple, dar niciodată o bucată de memorie care poate fi citită și scrisă.

Comparație cu paradigmele paralele anterioare

Calculatoarele de bază au pornit de la o paradigmă de execuție secvențială. CPU-urile tradiționale sunt bazate pe SISD , ceea ce înseamnă că, în mod conceptual, efectuează o singură operație la un moment dat. Pe măsură ce nevoile de calcul ale lumii au evoluat, cantitatea de date care trebuie gestionată a crescut foarte repede. Era evident că modelul de programare secvențială nu putea face față nevoii crescute de putere de procesare. S-au depus diverse eforturi pentru a găsi modalități alternative de a efectua cantități masive de calcule, dar singura soluție a fost exploatarea unui anumit nivel de execuție paralelă. Rezultatul acestor eforturi a fost SIMD , o paradigmă de programare care a permis aplicarea unei instrucțiuni la mai multe instanțe de date (diferite). De cele mai multe ori, SIMD era folosit într-un mediu SWAR . Folosind structuri mai complicate, s-ar putea avea și paralelism MIMD .

Deși aceste două paradigme au fost eficiente, implementările din lumea reală au fost afectate de limitări de la probleme de aliniere a memoriei la probleme de sincronizare și paralelism limitat. Doar puțini procesoare SIMD au supraviețuit ca componente de sine stătătoare; majoritatea erau încorporate în procesoare standard.

Luați în considerare un program simplu adunând două matrice care conțin 4-component 100 vectori (adică 400 numere în total).

Paradigmă convențională, secvențială

for (int i = 0; i < 400; i++)
    result[i] = source0[i] + source1[i];

Aceasta este paradigma secvențială care este cea mai familiară. Există variații (cum ar fi buclele interioare, structurile și altele), dar în cele din urmă se rezumă la acel construct.

Paradigmă SIMD paralelă, registre împachetate (SWAR)

for (int el = 0; el < 100; el++) // for each vector
    vector_sum(result[el], source0[el], source1[el]);

Acest lucru este de fapt prea simplificat. Presupune că instrucțiunile vector_sumfuncționează. Deși acest lucru se întâmplă cu instrucțiunile intrinseci , multe informații nu sunt luate în considerare aici, cum ar fi numărul de componente vectoriale și formatul lor de date. Acest lucru se face pentru claritate.

Puteți vedea totuși, această metodă reduce numărul de instrucțiuni decodificate de la numElements * componentsPerElement la numElements . Numărul instrucțiunilor de salt este, de asemenea, scăzut, deoarece bucla este rulată de mai puține ori. Aceste câștiguri rezultă din executarea paralelă a celor patru operații matematice.

Totuși, ceea ce s-a întâmplat este că registrul SIMD ambalat deține o anumită cantitate de date, deci nu este posibil să obțineți mai mult paralelism. Accelerarea este oarecum limitată de presupunerea pe care am făcut-o de a efectua patru operații paralele (vă rugăm să rețineți că acest lucru este comun atât pentru AltiVec, cât și pentru SSE ).

Paradigma fluxului paralel (SIMD / MIMD)

// This is a fictional language for demonstration purposes.
elements = array streamElement([number, number])[100]
kernel = instance streamKernel("@arg0[@iter]")
result = kernel.invoke(elements)

În această paradigmă, este definit întregul set de date, mai degrabă decât fiecare bloc component fiind definit separat. Se presupune că descrierea setului de date se află în primele două rânduri. După aceea, rezultatul se deduce din surse și nucleu. Pentru simplitate, există o mapare 1: 1 între datele de intrare și de ieșire, dar acest lucru nu trebuie să fie. Miezul aplicat poate fi, de asemenea, mult mai complex.

O implementare a acestei paradigme poate „derula” o buclă intern. Acest lucru permite transferul la scară cu complexitatea cipului, utilizând cu ușurință sute de ALU-uri. Eliminarea tiparelor de date complexe face disponibilă o mare parte din această putere suplimentară.

În timp ce procesarea fluxului este o ramură a procesării SIMD / MIMD, acestea nu trebuie confundate. Deși implementările SIMD pot funcționa adesea într-un mod "streaming", performanța lor nu este comparabilă: modelul prevede un model de utilizare foarte diferit care permite performanțe mult mai mari de la sine.

S-a observat că atunci când se aplică pe procesoare generice, cum ar fi CPU standard, se poate atinge doar o viteză de 1,5x. În schimb, procesoarele de flux ad-hoc ating cu ușurință performanțe de peste 10 ori, atribuite în principal accesului la memorie mai eficient și nivelurilor mai ridicate de procesare paralelă.

Deși există diferite grade de flexibilitate permise de model, procesoarele de flux impun de obicei unele limitări asupra nucleului sau dimensiunii fluxului. De exemplu, hardware-ului consumatorului îi lipsește adesea capacitatea de a efectua matematică de înaltă precizie, nu are lanțuri complexe de indirecție sau prezintă limite mai mici pentru numărul de instrucțiuni care pot fi executate.

Cercetare

Proiectele de procesare a fluxului de la Universitatea Stanford au inclus Proiectul de umbrire programabilă în timp real Stanford, început în 1999. Un prototip numit Imagine a fost dezvoltat în 2002. Un proiect numit Merrimac a funcționat până în 2004. AT&T a cercetat, de asemenea, procesoare îmbunătățite în flux, deoarece unitățile de procesare grafică au evoluat rapid în atât viteza, cât și funcționalitatea. Începând cu aceste zile, au fost dezvoltate zeci de limbaje de procesare a fluxurilor, precum și hardware specializat.

Note de modelare a programării

Cea mai imediată provocare din domeniul procesării paralele nu rezidă la fel de mult în tipul de arhitectură hardware utilizată, ci în cât de ușor va fi programarea sistemului în cauză într-un mediu real cu performanțe acceptabile. Mașini precum Imagine utilizează un model simplu cu un singur thread cu dependențe automate, alocare de memorie și programare DMA . Acest lucru în sine este un rezultat al cercetărilor de la MIT și Stanford pentru a găsi o stratificare optimă a sarcinilor între programator, instrumente și hardware. Programatorii bat instrumentele în maparea algoritmilor cu hardware-ul paralel, iar instrumentele înfrâng programatorii în stabilirea celor mai inteligente scheme de alocare a memoriei etc. Deosebit de îngrijorătoare sunt proiectările MIMD, cum ar fi Cell , pentru care programatorul trebuie să se ocupe de partiționarea aplicației pe mai multe nuclee și să se ocupe de sincronizarea procesului și echilibrarea sarcinii. Instrumentele eficiente de programare multi-core lipsesc astăzi.

Un dezavantaj al programării SIMD a fost problema Array-of-Structures (AoS) și Structure-of-Arrays (SoA) . Programatorii au dorit adesea să construiască structuri de date cu o semnificație „reală”, de exemplu:

 // A particle in a three-dimensional space.
struct particle_t {
    float x, y, z;          // not even an array!
    unsigned byte color[3]; // 8 bit per channel, say we care about RGB only
    float size;
    // ... and many other attributes may follow...
};

Ceea ce s-a întâmplat este că acele structuri au fost apoi asamblate în tablouri pentru a menține lucrurile frumos organizate. Aceasta este o serie de structuri (AoS). Când structura este așezată în memorie, compilatorul va produce date intercalate, în sensul că toate structurile vor fi adiacente, dar va exista un decalaj constant între, să zicem, atributul „dimensiune” al unei instanțe de structură și același element din următoarea instanță. Decalajul depinde de definiția structurii (și, eventual, de alte lucruri care nu sunt luate în considerare aici, cum ar fi politicile compilatorului). Există și alte probleme. De exemplu, cele trei variabile de poziție nu pot fi SIMD-izate în acest fel, deoarece nu este sigur că vor fi alocate în spațiul de memorie continuu. Pentru a vă asigura că operațiile SIMD pot funcționa pe ele, acestea trebuie grupate într-o „locație de memorie împachetată” sau cel puțin într-o matrice. O altă problemă constă atât în ​​„culoare”, cât și în „xyz”, care urmează să fie definite în cantități vectoriale cu trei componente. Procesoarele SIMD au de obicei suport doar pentru operațiuni cu 4 componente (cu unele excepții însă).

Acest tip de probleme și limitări au făcut ca accelerarea SIMD pe procesoarele standard să fie destul de urâtă. Soluția propusă, structura matricilor (SoA) urmează după cum urmează:

struct particle_t {
    float *x, *y, *z;
    unsigned byte *colorRed, *colorBlue, *colorGreen;
    float *size;
};

Pentru cititorii care nu au experiență cu C , „*” dinaintea fiecărui identificator înseamnă un indicator. În acest caz, ele vor fi folosite pentru a indica primul element al unui tablou, care urmează să fie alocat ulterior. Pentru programatorii Java , acest lucru este aproximativ echivalent cu "[]". Dezavantajul este că diferitele atribute ar putea fi răspândite în memorie. Pentru a ne asigura că acest lucru nu cauzează lipsa cache-ului, va trebui să actualizăm toate diferitele „roșii”, apoi toate „verdele” și „albastru”.

Pentru procesoarele de flux, este încurajată utilizarea structurilor. Din punct de vedere al aplicației, toate atributele pot fi definite cu o anumită flexibilitate. Luând GPU-uri ca referință, există un set de atribute (cel puțin 16) disponibile. Pentru fiecare atribut, aplicația poate indica numărul de componente și formatul componentelor (dar pentru moment sunt acceptate doar tipurile de date primitive). Diferitele atribute sunt apoi atașate la un bloc de memorie, definind eventual un pas între elementele „consecutive” ale acelorași atribute, permițând efectiv date intercalate. Când GPU începe procesarea fluxului, acesta va aduna toate atributele într-un singur set de parametri (de obicei, aceasta arată ca o structură sau o „variabilă globală magică”), efectuează operațiile și împrăștie rezultatele într-o anumită zonă de memorie pentru mai târziu prelucrare (sau recuperare).

Cadrele de procesare a fluxurilor mai moderne oferă o interfață de tip FIFO pentru a structura datele ca un flux literal. Această abstractizare oferă un mijloc de a specifica implicit dependențele de date, permițând în același timp runtime-ului / hardware-ului să profite din plin de aceste cunoștințe pentru un calcul eficient. Una dintre cele mai simple și eficiente modalități de procesare a fluxurilor până în prezent pentru C ++ este RaftLib , care permite conectarea nucleelor ​​de calcul independente împreună ca un grafic al fluxului de date utilizând operatorii de flux C ++. Ca exemplu:

#include <raft>
#include <raftio>
#include <cstdlib>
#include <string>

class hi : public raft::kernel
{
public:
    hi() : raft::kernel()
    {
       output.addPort< std::string >( "0" ); 
    }

    virtual raft::kstatus run()
    {
        output[ "0" ].push( std::string( "Hello World\n" ) );
        return( raft::stop ); 
    }
};

int
main( int argc, char **argv )
{
    /** instantiate print kernel **/
    raft::print< std::string > p;
    /** instantiate hello world kernel **/
    hi hello;
    /** make a map object **/
    raft::map m;
    /** add kernels to map, both hello and p are executed concurrently **/
    m += hello >> p;
    /** execute the map **/
    m.exe();
    return( EXIT_SUCCESS );
}

Modele de calcul pentru procesarea fluxului

În afară de specificarea aplicațiilor de streaming în limbaje de nivel înalt, modelele de calcul (MoC) au fost, de asemenea, utilizate pe scară largă ca modele de flux de date și modele bazate pe procese.

Arhitectura generică a procesorului

Din punct de vedere istoric, procesoarele au început să implementeze diferite niveluri de optimizare a accesului la memorie datorită performanțelor în continuă creștere în comparație cu lățimea de bandă a memoriei externe în creștere relativ lentă. Pe măsură ce acest decalaj s-a extins, cantități mari de suprafață au fost dedicate ascunderii latențelor de memorie. Deoarece preluarea de informații și coduri de opțiuni pentru aceste câteva ALU-uri este costisitoare, foarte puțină zonă a matriței este dedicată utilajelor matematice reale (ca o estimare aproximativă, considerați-o ca fiind mai mică de 10%).

O arhitectură similară există pe procesoarele de flux, dar datorită noului model de programare, cantitatea de tranzistoare dedicată gestionării este de fapt foarte mică.

Începând dintr-un întreg punct de vedere al sistemului, procesoarele de flux există de obicei într-un mediu controlat. GPU-urile există pe o placă de completare (acest lucru pare să se aplice și pentru Imagine ). CPU-urile fac treaba murdară de a gestiona resursele sistemului, de a rula aplicații și altele.

Procesorul de flux este de obicei echipat cu o magistrală de memorie rapidă, eficientă și proprietară (comutatoarele transversale sunt acum comune, mai multe autobuze au fost folosite în trecut). Cantitatea exactă de benzi de memorie depinde de gama pieței. După cum este scris, există încă interconectări largi pe 64 de biți în jur (entry-level). Majoritatea modelelor mid-range folosesc o matrice de comutare rapidă pe 128 biți (4 sau 2 segmente), în timp ce modelele high-end implementează cantități uriașe de memorie (de fapt, până la 512 MB) cu o transversală ușor mai lentă, cu o lățime de 256 biți. În schimb, procesoarele standard de la Intel Pentium la unele Athlon 64 au doar o singură magistrală de date pe 64 de biți.

Modelele de acces la memorie sunt mult mai previzibile. În timp ce matricele există, dimensiunea lor este fixată la invocarea nucleului. Lucrul care se potrivește cel mai bine cu o indirecție cu pointer multiplu este un lanț de indirecție , care este totuși garantat pentru a citi sau a scrie în cele din urmă dintr-o anumită zonă de memorie (în interiorul unui flux).

Datorită naturii SIMD a unităților de execuție a procesorului de flux (clustere ALU), se așteaptă ca operațiile de citire / scriere să se desfășoare în bloc, astfel încât amintirile sunt optimizate pentru lățime de bandă mare mai degrabă decât pentru latență scăzută (aceasta este o diferență față de Rambus și DDR SDRAM , pentru exemplu). Acest lucru permite, de asemenea, negocieri eficiente cu magistrala de memorie.

Cea mai mare parte (90%) din lucrarea unui procesor de flux se face pe cip, necesitând doar 1% din datele globale să fie stocate în memorie. Aici plătește cunoașterea temporarelor și dependențelor kernelului.

Intern, un procesor de flux prezintă câteva circuite inteligente de comunicare și gestionare, dar ceea ce este interesant este fișierul de înregistrare a fluxului (SRF). Conceptual, acesta este un cache mare, în care datele fluxului sunt stocate pentru a fi transferate în memoria externă în bloc. Ca o structură controlată de software asemănătoare cache-ului pentru diferitele ALU-uri , SRF este partajat între toate diferitele clustere ALU. Conceptul cheie și inovația realizate aici cu cipul Imagine de la Stanford sunt că compilatorul este capabil să automatizeze și să aloce memoria într-un mod optim, complet transparent pentru programator. Dependențele dintre funcțiile kernelului și datele sunt cunoscute prin modelul de programare care permite compilatorului să efectueze analize de flux și să împacheteze în mod optim SRF-urile. În mod obișnuit, acest cache și gestionarea DMA pot prelua majoritatea programului unui proiect, lucru automatizat în totalitate de procesorul de flux (sau cel puțin Imagine). Testele efectuate la Stanford au arătat că compilatorul a făcut o treabă la fel de bună sau mai bună la programarea memoriei decât dacă ați reglat lucrul cu mult efort.

Există dovezi; pot exista o mulțime de clustere, deoarece se presupune că comunicarea inter-cluster este rară. Cu toate acestea, la nivel intern, fiecare cluster poate exploata în mod eficient o cantitate mult mai mică de ALU, deoarece comunicarea intra-cluster este comună și, prin urmare, trebuie să fie extrem de eficientă.

Pentru a păstra acele ALU preluate cu date, fiecare ALU este echipată cu fișiere de registre locale (LRF), care sunt practic registrele sale utilizabile.

Acest model de acces la trei niveluri de date face ușor să păstreze datele temporare departe de amintirile lente, făcând astfel implementarea siliciului extrem de eficientă și de economisire a energiei.

Probleme hardware-in-the-loop

Deși se poate aștepta în mod rezonabil o accelerare a ordinii de mărime (chiar și de la GPU-urile obișnuite atunci când calculează în mod streaming), nu toate aplicațiile beneficiază de acest lucru. Latențele de comunicare sunt de fapt cea mai mare problemă. Deși PCI Express a îmbunătățit acest lucru cu comunicațiile full-duplex, funcționarea unui GPU (și, eventual, a unui procesor generic de flux) va dura mult timp. Aceasta înseamnă că este de obicei contraproductiv să le folosiți pentru seturi de date mici. Deoarece schimbarea nucleului este o operațiune destul de costisitoare, arhitectura fluxului atrage penalități pentru fluxurile mici, un comportament denumit efectul fluxului scurt .

Pipelining este o practică foarte răspândită și foarte utilizată pe procesoarele de flux, cu GPU-uri cu conducte care depășesc 200 de etape. Costul pentru comutarea setărilor depinde de modificarea setării, dar acum este considerat a fi întotdeauna scump. Pentru a evita aceste probleme la diferite niveluri ale conductei, au fost implementate multe tehnici, cum ar fi „über shaders” și „atlasuri de textură”. Aceste tehnici sunt orientate spre joc datorită naturii GPU-urilor, dar conceptele sunt interesante și pentru procesarea generică a fluxurilor.

Exemple

  • Blitter în Commodore Amiga este un procesor grafic timpuriu (circa 1985) capabil de a combina trei fluxuri sursă de 16 biți vectori componente în 256 moduri de a produce un flux de ieșire format din 16 biți vectori componente. Lățimea de bandă totală a fluxului de intrare este de până la 42 de milioane de biți pe secundă. Lățimea de bandă a fluxului de ieșire este de până la 28 de milioane de biți pe secundă.
  • Imagine, condus de profesorul William Dally de la Universitatea Stanford , este o arhitectură flexibilă menită să fie atât rapidă, cât și eficientă din punct de vedere energetic. Proiectul, conceput inițial în 1996, a inclus arhitectură, instrumente software, o implementare VLSI și o placă de dezvoltare, a fost finanțat de DARPA , Intel și Texas Instruments .
  • Un alt proiect Stanford , numit Merrimac, vizează dezvoltarea unui supercomputer bazat pe flux. Merrimac intenționează să utilizeze o arhitectură de flux și rețele avansate de interconectare pentru a oferi mai multă performanță pe cost unitar decât computerele științifice bazate pe cluster construite din aceeași tehnologie.
  • Familia Storm-1 de la Stream Processors, Inc , un spin-off comercial al proiectului Imagine de la Stanford , a fost anunțată în timpul unei prezentări de caracteristici la ISSCC 2007. Familia conține patru membri variind de la 30 GOPS la 220 GOPS pe 16 biți (miliarde de operațiuni pe secundă), toate fabricate la TSMC într-un proces de 130 nanometri. Dispozitivele vizează segmentul de vârf al pieței DSP , inclusiv conferințe video , imprimante multifuncționale și echipamente de supraveghere video digitală .
  • GPU-urile sunt procesoare de flux larg răspândite, destinate consumatorilor, proiectate în principal de AMD și Nvidia . Diverse generații care trebuie remarcate din punct de vedere al procesării fluxului:
    • Pre-R2xx / NV2x: nu există suport explicit pentru procesarea fluxului. Operațiunile kernelului au fost ascunse în API și au oferit prea puțină flexibilitate pentru utilizare generală.
    • R2xx / NV2x: operațiunile fluxului de nucleu au devenit explicit sub controlul programatorului, dar numai pentru procesarea vârfurilor (fragmentele foloseau încă vechi paradigme). Niciun suport de ramificare nu a împiedicat grav flexibilitatea, dar unele tipuri de algoritmi ar putea fi rulate (în special, simularea fluidelor de precizie redusă).
    • R3xx / NV4x: suport flexibil de ramificare, deși există încă unele limitări cu privire la numărul de operații de executat și adâncimea strictă de recursivitate, precum și la manipularea matricei.
    • R8xx: acceptă adăugarea / consumul de tampoane și operații atomice. Această generație este stadiul tehnicii.
  • Denumirea mărcii AMD FireStream pentru linia de produse care vizează HPC
  • Nume de marcă Nvidia Tesla pentru linia de produse care vizează HPC
  • Procesorul Cell de la ITS , o alianță de Sony Computer Entertainment , Toshiba Corporation , și IBM , este o arhitectură hardware care poate funcționa ca un procesor de flux , cu suport software adecvat. Se compune dintr-un procesor de control, PPE (Power Processing Element, un IBM PowerPC ) și un set de coprocesoare SIMD, numite SPE (Synergistic Processing Elements), fiecare cu contoare de programe independente și memorie de instrucțiuni, de fapt o mașină MIMD . În modelul de programare nativ, toate programările DMA și program sunt lăsate la latitudinea programatorului. Hardware-ul oferă o magistrală de apel rapidă printre procesoare pentru comunicații locale. Deoarece memoria locală pentru instrucțiuni și date este limitată, singurele programe care pot exploata eficient această arhitectură fie necesită o amprentă mică de memorie, fie aderă la un model de programare a fluxului. Cu un algoritm adecvat, performanța celulei poate rivaliza cu cea a procesorelor de flux pur, cu toate acestea, acest lucru necesită aproape întotdeauna o reproiectare completă a algoritmilor și a software-ului.

Stream biblioteci și limbaje de programare

Majoritatea limbajelor de programare pentru procesoarele de flux încep cu Java, C sau C ++ și adaugă extensii care oferă instrucțiuni specifice pentru a permite dezvoltatorilor de aplicații să eticheteze nucleele și / sau fluxurile. Acest lucru se aplică și majorității limbajelor de umbrire , care pot fi considerate limbaje de programare a fluxurilor într-o anumită măsură.

Exemple necomerciale de limbaje de programare a fluxului includ:

Implementările comerciale sunt fie de uz general, fie legate de hardware-ul specific de către un furnizor. Exemple de limbi cu scop general includ:

Limbile specifice furnizorului includ:

Procesare bazată pe evenimente

Procesare bazată pe fișiere batch (emulează o parte din procesarea curentă a fluxului, dar performanțe mult mai scăzute în general)

Procesare continuă a fluxului de operator

Servicii de procesare a fluxului:

Vezi si

Referințe

linkuri externe

  1. ^ Chintapalli, Sanket; Dagit, Derek; Evans, Bobby; Farivar, Reza; Graves, Thomas; Holderbaugh, Mark; Liu, Zhuo; Nusbaum, Kyle; Patil, Kishorkumar; Peng, Boyang Jerry; Poulosky, Paul (mai 2016). „Motoare de calcul de analiză comparativă: Streaming, Storm, Flink și Spark”. 2016 IEEE International Parallel and Distributed Processing Symposium Workshops (IPDPSW) . IEEE. pp. 1789–1792. doi : 10.1109 / IPDPSW.2016.138 . ISBN 978-1-5090-3682-0. S2CID  2180634 .