Zpracování streamu - Stream processing

Stream zpracování je programování paradigma, ekvivalentní k toku dat programování , zpracování toku událostí , a reaktivní programování , který umožňuje některé aplikace snáze využívat omezenou formu paralelního zpracování . Takové aplikace mohou používat více výpočetních jednotek, jako je jednotka s plovoucí desetinnou čárkou na jednotce pro zpracování grafiky nebo pole programovatelných bran (FPGA), aniž by mezi těmito jednotkami výslovně řídili alokaci, synchronizaci nebo komunikaci.

Paradigma zpracování streamu zjednodušuje paralelní software a hardware omezením paralelního výpočtu, který lze provádět. Vzhledem k posloupnosti dat ( stream ) je na každý prvek v proudu použita řada operací ( funkce jádra ). Funkce jádra jsou obvykle pipeline , a optimální opětovné místní na čipu paměti se pokus, aby se minimalizovala ztráta šířky pásma, spojené s vnějším interakce paměti. Typické je jednotné streamování , kdy je na všechny prvky ve streamu aplikována jedna funkce jádra. Jelikož abstrakce jádra a streamu odhalují závislosti na datech, nástroje kompilátoru mohou plně automatizovat a optimalizovat úlohy správy na čipu. Hardware pro zpracování streamu může použít scoreboarding , například k zahájení přímého přístupu do paměti (DMA), když jsou známy závislosti. Vyloučení manuální správy DMA snižuje složitost softwaru a související eliminace hardwarově uložených I/O v mezipaměti zmenšuje objem datové oblasti, kterou musí služba zahrnovat specializovanými výpočetními jednotkami, jako jsou aritmetické logické jednotky .

Během osmdesátých let bylo zpracování proudu prozkoumáno v rámci programování toku dat . Příkladem je jazyk SISAL (Streams and Iteration in a Single Assignment Language).

Aplikace

Zpracování streamu je v zásadě kompromisem, který je řízen modelem zaměřeným na data, který funguje velmi dobře pro tradiční aplikace typu DSP nebo GPU (jako je zpracování obrazu, videa a digitálního signálu ), ale méně pro zpracování pro obecné účely s více randomizovaným přístupem k datům ( jako jsou databáze). Obětováním určité flexibility v modelu důsledky umožňují snadnější, rychlejší a efektivnější provádění. V závislosti na kontextu může být design procesoru vyladěn pro maximální účinnost nebo kompromis pro flexibilitu.

Streamové zpracování je vhodné zejména pro aplikace, které vykazují tři aplikační charakteristiky:

  • Compute Intensity , počet aritmetických operací na I/O nebo odkaz na globální paměť. V mnoha aplikacích pro zpracování signálu je dnes hodně přes 50: 1 a roste s algoritmickou složitostí.
  • Paralelismus dat existuje v jádře, pokud je stejná funkce aplikována na všechny záznamy vstupního proudu a řadu záznamů lze zpracovávat současně bez čekání na výsledky z předchozích záznamů.
  • Data Locality je specifický typ časové lokality, který je běžný v aplikacích pro zpracování signálu a médií, kde jsou data produkována jednou, jednou nebo dvakrát přečtena později v aplikaci a nikdy znovu nečtena. Mezilehlé toky předávané mezi jádry i mezilehlá data v rámci funkcí jádra mohou tuto lokalitu zachytit přímo pomocí programovacího modelu zpracování proudu.

Mezi příklady záznamů v rámci streamů patří:

  • V grafice může být každý záznam informací o vrcholu, normálu a barvě pro trojúhelník;
  • Při zpracování obrazu může být každý záznam jeden pixel z obrázku;
  • Ve video kodéru může mít každý záznam 256 pixelů tvořících makroblok dat; nebo
  • Při bezdrátovém zpracování signálu může být každý záznam sledem vzorků přijatých z antény.

U každého záznamu můžeme pouze číst ze vstupu, provádět na něm operace a zapisovat na výstup. Je přípustné mít více vstupů a více výstupů, ale nikdy kousek paměti, který je čitelný i zapisovatelný.

Srovnání s předchozími paralelními paradigmaty

Základní počítače začaly z paradigmatu sekvenčního spouštění. Tradiční CPU jsou založeny na SISD , což znamená, že koncepčně provádějí vždy jen jednu operaci. S vývojem výpočetních potřeb světa se množství dat, která je třeba spravovat, velmi rychle zvyšovalo. Bylo zřejmé, že model sekvenčního programování se nedokáže vyrovnat se zvýšenou potřebou výpočetního výkonu. Různé úsilí bylo vynaloženo na hledání alternativních způsobů, jak provádět obrovské množství výpočtů, ale jediným řešením bylo využít určitou úroveň paralelního provádění. Výsledkem těchto snah bylo SIMD , programovací paradigma, které umožňovalo aplikovat jednu instrukci na více instancí (různých) dat. SIMD byla většinu času používána v prostředí SWAR . Použitím komplikovanějších struktur by také mohl existovat paralelismus MIMD .

Ačkoli tato dvě paradigmata byla účinná, implementace v reálném světě byly sužovány omezeními od problémů se zarovnáním paměti až po problémy se synchronizací a omezeným paralelismem. Jen několik procesorů SIMD přežilo jako samostatné komponenty; většina byla vložena do standardních CPU.

Zvažte jednoduchý program, který sečte dvě pole obsahující 100 4složkových vektorů (tj. Celkem 400 čísel).

Konvenční, sekvenční paradigma

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

Toto je nejznámější sekvenční paradigma. Variace existují (například vnitřní smyčky, struktury atd.), Ale v konečném důsledku se scvrkávají na tuto konstrukci.

Paralelní paradigma SIMD, zabalené registry (SWAR)

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

To je ve skutečnosti příliš zjednodušené. Předpokládá, že instrukce vector_sumfunguje. Ačkoli se to děje s vnitřními instrukcemi , mnoho informací zde ve skutečnosti není bráno v úvahu, jako je počet vektorových komponent a jejich datový formát. To se provádí pro přehlednost.

Můžete však vidět, že tato metoda snižuje počet dekódovaných instrukcí z numElements * componentsPerElement na numElements . Snižuje se také počet skokových instrukcí, protože smyčka se spouští méněkrát. Tyto zisky vyplývají z paralelního provádění čtyř matematických operací.

Stalo se však to, že zabalený registr SIMD pojme určité množství dat, takže není možné získat větší paralelismus. Zrychlení je poněkud omezeno předpokladem, který jsme provedli při provádění čtyř paralelních operací (toto je běžné pro AltiVec i SSE ).

Paradigma paralelního proudu (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)

V tomto paradigmatu je definována celá datová sada, nikoli každý blok komponent je definován samostatně. Předpokládá se, že popis sady dat je v prvních dvou řádcích. Poté je výsledek odvozen ze zdrojů a jádra. Pro zjednodušení existuje mapování 1: 1 mezi vstupními a výstupními daty, ale nemusí to tak být. Aplikovaná jádra mohou být také mnohem složitější.

Implementace tohoto paradigmatu může interně „rozvinout“ smyčku. To umožňuje škálovat propustnost s komplexností čipů a snadno využívat stovky ALU. Díky eliminaci složitých datových vzorů je velká část této extra energie k dispozici.

Zatímco zpracování proudu je pobočkou zpracování SIMD/MIMD, nesmí být zaměňováno. Ačkoli implementace SIMD mohou často fungovat „streamovacím“ způsobem, jejich výkon není srovnatelný: model předpokládá velmi odlišný způsob použití, který sám o sobě umožňuje mnohem vyšší výkon.

Bylo poznamenáno, že při použití na generických procesorech, jako je standardní CPU, lze dosáhnout pouze 1,5násobného zrychlení. Naproti tomu procesory ad-hoc stream snadno dosahují více než 10násobného výkonu, což je přičítáno zejména efektivnějšímu přístupu k paměti a vyšším úrovním paralelního zpracování.

Přestože model umožňuje různé stupně flexibility, procesory streamů obvykle ukládají určitá omezení velikosti jádra nebo streamu. Například spotřební hardware často postrádá schopnost provádět vysoce přesnou matematiku, postrádá složité řetězy s přesměrováním nebo představuje nižší limity pro počet instrukcí, které lze provést.

Výzkum

Projekty zpracování streamů na Stanfordské univerzitě zahrnovaly projekt Stanford Real-Time Programmable Shading Project, který byl zahájen v roce 1999. Prototyp nazvaný Imagine byl vyvinut v roce 2002. Projekt nazvaný Merrimac běžel zhruba do roku 2004. AT&T také zkoumal procesory vylepšené streamováním, protože jednotky pro zpracování grafiky se rychle vyvíjely v rychlost i funkčnost. Od těchto raných dob byly vyvinuty desítky jazyků pro zpracování streamů a také specializovaný hardware.

Poznámky k programování modelu

Nejbezprostřednější výzva v oblasti paralelního zpracování nespočívá tolik v typu použité hardwarové architektury, ale v tom, jak snadné bude programovat dotyčný systém v reálném světě s přijatelným výkonem. Stroje jako Imagine používají přímý model s jedním vláknem s automatizovanými závislostmi, přidělováním paměti a plánováním DMA . To samo o sobě je výsledkem výzkumu na MIT a Stanfordu při hledání optimálního vrstvení úkolů mezi programátorem, nástroji a hardwarem. Programátoři porazili nástroje při mapování algoritmů na paralelní hardware a nástroje porazily programátory při určování nejchytřejších schémat alokace paměti atd. Obzvláště znepokojivé jsou návrhy MIMD, jako je Cell , u nichž se programátor musí vypořádat s dělením aplikací mezi více jádry a řešit synchronizace procesů a vyvažování zátěže. Účinné vícejádrové programovací nástroje dnes velmi chybí.

Nevýhodou programování SIMD byla otázka Array-of-Structures (AoS) a Structure-of-Arrays (SoA) . Programátoři často chtěli stavět datové struktury se „skutečným“ významem, například:

 // 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...
};

Stalo se, že tyto struktury byly poté sestaveny do polí , aby byly věci pěkně organizované. Toto je řada struktur (AoS). Když je struktura uložena v paměti, kompilátor vytvoří prokládaná data v tom smyslu, že všechny struktury budou souvislé, ale bude existovat konstantní posun mezi, řekněme, atributem „velikost“ instance struktury a stejným prvkem následující instance. Posun závisí na definici struktury (a případně dalších věcech, které zde nejsou brány v úvahu, jako jsou zásady kompilátoru). Existují také další problémy. Například tři proměnné polohy nelze takto SIMDizovat, protože není jisté, zda budou přiděleny v souvislém paměťovém prostoru. Aby bylo zajištěno, že operace SIMD na nich mohou fungovat, musí být seskupeny do „zabaleného paměťového umístění“ nebo alespoň do pole. Další problém spočívá v tom, že „barva“ a „xyz“ budou definovány ve třísložkových vektorových množstvích. Procesory SIMD obvykle podporují pouze 4komponentní operace (až na některé výjimky).

Díky těmto druhům problémů a omezení byla akcelerace SIMD na standardních CPU dost ošklivá. Navrhované řešení, struktura polí (SoA), vypadá takto:

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

Pro čtenáře, kteří nemají zkušenosti s C , znamená '*' před každým identifikátorem ukazatel. V tomto případě budou použity k označení prvního prvku pole, který má být přidělen později. Pro Java programátory je to zhruba ekvivalentní „[]“. Nevýhodou je, že různé atributy lze šířit v paměti. Abychom se ujistili, že to nezpůsobí vynechání mezipaměti, budeme muset aktualizovat všechny různé „červené“, poté všechny „zelené“ a „blues“.

U streamových procesorů se doporučuje použití struktur. Z hlediska aplikace lze všechny atributy definovat s určitou flexibilitou. Když vezmeme GPU jako referenci, je k dispozici sada atributů (nejméně 16). U každého atributu může aplikace uvést počet komponent a formát komponent (ale zatím jsou podporovány pouze primitivní datové typy). Různé atributy jsou pak připojeny k paměťovému bloku, případně definují krok mezi 'po sobě jdoucími' prvky stejných atributů, což efektivně umožňuje prokládaná data. Když GPU zahájí zpracování streamu, shromáždí všechny různé atributy v jedné sadě parametrů (obvykle to vypadá jako struktura nebo „magická globální proměnná“), provede operace a rozptýlí výsledky do některé oblasti paměti pro pozdější použití. zpracování (nebo načítání).

Modernější rámce pro zpracování streamů poskytují rozhraní podobné FIFO pro strukturování dat jako doslovný stream. Tato abstrakce poskytuje způsob, jak implicitně specifikovat závislosti na datech, a zároveň umožňuje běhovému/hardwaru plně využít těchto znalostí pro efektivní výpočet. Jednou z dosud nejjednodušších a nejefektivnějších modalit zpracování proudu pro C ++ je RaftLib , který umožňuje propojení nezávislých výpočetních jader dohromady jako grafu toku dat pomocí operátorů proudu C ++. Jako příklad:

#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 );
}

Modely výpočtu pro zpracování proudu

Kromě určování streamovacích aplikací v jazycích na vysoké úrovni byly modely výpočtů (MoC) také široce používány jako modely toku dat a modely založené na procesech.

Obecná architektura procesoru

Historicky CPU začaly implementovat různé úrovně optimalizace přístupu k paměti kvůli stále rostoucímu výkonu ve srovnání s relativně pomalu rostoucí šířkou pásma externí paměti. Jak se tato mezera zvětšovala, bylo velké množství oblasti kostek věnováno skrývání latencí paměti. Vzhledem k tomu, že získávání informací a operačních kódů do těchto několika ALU je drahé, je velmi malá oblast matrice věnována skutečnému matematickému stroji (jako hrubý odhad jej považujte za méně než 10%).

Podobná architektura existuje na stream procesorech, ale díky novému programovacímu modelu je množství tranzistorů vyhrazených pro správu ve skutečnosti velmi malé.

Počínaje z hlediska celého systému proudové procesory obvykle existují v kontrolovaném prostředí. GPU na desce doplňků existují (zdá se, že to platí i pro Imagine ). CPU dělají špinavou práci při správě systémových prostředků, spouštění aplikací a podobně.

Proudový procesor je obvykle vybaven rychlou, efektivní a proprietární paměťovou sběrnicí (nyní jsou běžné příčné přepínače, v minulosti se používalo více sběrnic). Přesné množství paměťových pruhů závisí na rozsahu trhu. Jak je napsáno, stále existuje 64bitová široká propojení (základní úroveň). Většina modelů střední třídy používá rychlou 128bitovou matici přepínačů příčného nosníku (4 nebo 2 segmenty), zatímco modely vyšší třídy nasazují obrovské množství paměti (ve skutečnosti až 512 MB) s mírně pomalejším příčníkem širokým 256 bitů. Naproti tomu standardní procesory od Intel Pentium po některý Athlon 64 mají pouze jednu 64bitovou širokou datovou sběrnici.

Vzory přístupu do paměti jsou mnohem předvídatelnější. Zatímco pole existují, jejich dimenze je při vyvolání jádra pevná. Věc, která se nejvíce shoduje s více směrovými směrovými směry, je řetězec s přesměrováním , který však zaručeně konečně čte nebo zapisuje z konkrétní oblasti paměti (uvnitř proudu).

Kvůli SIMD povaze prováděcích jednotek procesoru proudu (klastry ALU) se očekává, že operace čtení/zápisu budou probíhat hromadně, takže paměti jsou optimalizovány spíše pro velkou šířku pásma než pro nízkou latenci (to je rozdíl oproti Rambus a DDR SDRAM , pro příklad). To také umožňuje efektivní vyjednávání paměťové sběrnice.

Většina (90%) práce streamovacího procesoru se provádí na čipu, což vyžaduje uložení pouze 1% globálních dat do paměti. Tady platí znalost dočasností a závislostí jádra.

Interně má stream procesor několik chytrých komunikačních a řídicích obvodů, ale co je zajímavé, je Stream Register File (SRF). Jedná se koncepčně o velkou mezipaměť, ve které jsou uložena data streamu, která mají být hromadně přenášena do externí paměti. Jako softwarově řízená struktura různých ALU připomínající mezipaměť je SRF sdílen mezi všemi různými klastry ALU. Klíčovým konceptem a inovací, kterou zde Stanfordův čip Imagine provedl, je to, že kompilátor je schopen automatizovat a alokovat paměť optimálním způsobem, plně transparentním pro programátora. Závislosti mezi funkcemi jádra a daty jsou známy prostřednictvím programovacího modelu, který kompilátoru umožňuje provádět analýzu toku a optimálně zabalit SRF. Běžně může tato mezipaměť a správa DMA zabírat většinu plánu projektu, což je něco, co procesor streamu (nebo alespoň Imagine) zcela automatizuje. Testy provedené ve Stanfordu ukázaly, že kompilátor odvedl stejně dobrou nebo lepší práci při plánování paměti, než kdybyste věc ručně vyladili s velkým úsilím.

Existuje důkaz; klastrů může být mnoho, protože se předpokládá, že komunikace mezi klastry je vzácná. Interně však každý klastr může efektivně využívat mnohem nižší množství ALU, protože komunikace uvnitř klastru je běžná, a proto musí být vysoce účinná.

Aby byly tyto ALU načteny daty, je každá ALU vybavena místními soubory registrů (LRF), což jsou v podstatě jeho použitelné registry.

Tento třístupňový vzor přístupu k datům usnadňuje uchování dočasných dat mimo pomalé paměti, a proto je implementace křemíku vysoce účinná a úsporná.

Problémy se smyčkou hardwaru

Přestože lze rozumně očekávat řádově vyšší zrychlení (dokonce i z běžných GPU při streamování), ne všechny aplikace z toho těží. Latence komunikace jsou ve skutečnosti největším problémem. Ačkoli to PCI Express vylepšilo plně duplexní komunikací, zprovoznění GPU (a případně generického stream procesoru) bude možná trvat dlouho. To znamená, že je obvykle kontraproduktivní používat je pro malé datové sady. Protože změna jádra je poměrně nákladná operace, architektura proudu také ukládá sankce pro malé streamy, což je chování označované jako efekt krátkého proudu .

Pipelining je velmi rozšířený a hojně používaný postup na stream procesorech, přičemž GPU mají potrubí přesahující 200 stupňů. Cena za přepnutí nastavení závisí na upravovaném nastavení, ale nyní je považována za vždy drahou. Aby se předešlo těmto problémům na různých úrovních potrubí, bylo zavedeno mnoho technik, jako například „über shadery“ a „texturové atlasy“. Tyto techniky jsou vzhledem k povaze GPU zaměřeny na hru, ale koncepty jsou zajímavé i pro generické zpracování streamů.

Příklady

  • The Blitter in the Commodore Amiga is an early (circa 1985) graphics processor possible to combine three source streams of 16 component bit vehicles in 256 ways to produce a output stream collected of 16 component bit vehicles. Celková šířka pásma vstupního proudu je až 42 milionů bitů za sekundu. Šířka pásma výstupního proudu je až 28 milionů bitů za sekundu.
  • Imagine, vedená profesorem Williamem Dallym ze Stanfordské univerzity , je flexibilní architektura, která má být rychlá i energeticky účinná. Projekt, původně koncipovaný v roce 1996, zahrnoval architekturu, softwarové nástroje, implementaci VLSI a vývojovou desku, byl financován společnostmi DARPA , Intel a Texas Instruments .
  • Další Stanfordský projekt s názvem Merrimac je zaměřen na vývoj superpočítače založeného na streamu. Společnost Merrimac má v úmyslu použít architekturu proudu a pokročilé propojovací sítě k zajištění vyššího výkonu za jednotkové náklady než vědecké počítače založené na klastrech postavené ze stejné technologie.
  • Rodina Storm-1 od Stream Processors, Inc , komerční spin-off projektu Stanford's Imagine , byla oznámena během prezentace funkcí na ISSCC 2007. Rodina obsahuje čtyři členy od 30 GOPS do 220 16bitových GOPS (miliardy operací) za sekundu), vše vyrobeno v TSMC 130 nanometrovým procesem. Zařízení se zaměřují na špičkový trh DSP, včetně videokonferencí , multifunkčních tiskáren a zařízení pro digitální video dohled .
  • GPU jsou rozšířené streamovací procesory spotřebitelské třídy navržené hlavně AMD a Nvidia . Různé generace, které je třeba poznamenat z hlediska zpracování proudu:
    • Pre-R2xx/NV2x: žádná explicitní podpora pro zpracování streamu. Operace jádra byly skryty v API a poskytovaly příliš malou flexibilitu pro obecné použití.
    • R2xx/NV2x: operace s jádrovým proudem se staly explicitně pod kontrolou programátora, ale pouze pro zpracování vrcholů (fragmenty stále používaly stará paradigmata). Žádná podpora větvení výrazně omezila flexibilitu, ale mohly být spuštěny některé typy algoritmů (zejména simulace tekutin s nízkou přesností).
    • R3xx/NV4x: flexibilní podpora větvení, přestože stále existují určitá omezení týkající se počtu operací, které mají být provedeny, a přísné hloubky rekurze, stejně jako manipulace s polem.
    • R8xx: Podporuje přidávání/používání vyrovnávacích pamětí a atomových operací. Tato generace je nejmodernější.
  • Název značky AMD FireStream pro produktovou řadu zaměřenou na HPC
  • Název značky Nvidia Tesla pro produktovou řadu zaměřenou na HPC
  • Procesor Cell od STI , aliance Sony Computer Entertainment , Toshiba Corporation a IBM , je hardwarová architektura, která může fungovat jako proud procesor s příslušnou softwarovou podporu. Skládá se z řídicího procesoru, PPE (Power Processing Element, IBM PowerPC ) a sady koprocesorů SIMD, nazývaných SPE (Synergistic Processing Elements), každý s nezávislými čítači programů a pamětí instrukcí, ve skutečnosti stroj MIMD . V nativním modelu programování je veškeré plánování DMA a programů ponecháno na programátorovi. Hardware poskytuje rychlou kruhovou sběrnici mezi procesory pro místní komunikaci. Protože je lokální paměť pro instrukce a data omezená, jediné programy, které mohou tuto architekturu efektivně využívat, buď vyžadují malou paměťovou stopu, nebo dodržují model programování streamu. S vhodným algoritmem může výkon buňky konkurovat čistým stream procesorům, ale to téměř vždy vyžaduje kompletní přepracování algoritmů a softwaru.

Streamovací programovací knihovny a jazyky

Většina programovacích jazyků pro stream procesory začíná jazykem Java, C nebo C ++ a přidává rozšíření, která poskytují konkrétní pokyny, které vývojářům aplikací umožňují označovat jádra a/nebo streamy. To platí také pro většinu stínovacích jazyků , které lze do určité míry považovat za streamovací programovací jazyky.

Nekomerční příklady streamovacích programovacích jazyků zahrnují:

Komerční implementace mají buď obecný účel, nebo jsou vázány na konkrétní hardware prodejcem. Mezi příklady obecných jazyků patří:

Mezi jazyky specifické pro dodavatele patří:

Zpracování na základě událostí

Dávkové zpracování založené na souborech (emuluje část skutečného zpracování streamu, ale obecně mnohem nižší výkon)

Nepřetržité zpracování streamu operátora

Stream Processing Services:

Viz také

Reference

externí odkazy

  1. ^ Chintapalli, Sanket; Dagit, Derek; Evans, Bobby; Farivar, Reza; Graves, Thomas; Holderbaugh, Mark; Liu, Zhuo; Nusbaum, Kyle; Patil, Kishorkumar; Peng, Boyang Jerry; Poulosky, Paul (květen 2016). „Benchmarking Streaming Computation Engines: Storm, Flink and Spark Streaming“. 2016 Mezinárodní sympozium paralelního a distribuovaného zpracování IEEE (IPDPSW) . IEEE. s. 1789–1792. doi : 10.1109/IPDPSW.2016.138 . ISBN 978-1-5090-3682-0. S2CID  2180634 .