pajplajnyngTakéPipeline processing, Instrukční pipeline, HTTP pipeliningPokročilý

Definice

Pipelining je technika, při které se zpracování rozdělí na několik po sobě jdoucích fází a ty běží současně nad různými položkami, takže se překrývá čekání s prací. Procesor tak začne načítat další instrukci dřív, než dokončí předchozí, a klient pošle další požadavek bez čekání na odpověď. Zvyšuje průchodnost, nikoli latenci jedné položky.

Kategorie: Počítačová architekturaAktualizováno

Nezaměňujte: Pipelining označuje jak zřetězené zpracování instrukcí v procesoru, tak odesílání více požadavků bez čekání na odpověď v síťových protokolech (HTTP, Redis, SMTP), a v datovém světě i řetězec navazujících transformací.

Proč se práce dělí na fáze

Pipelining vychází z pozorování, že jedna operace obvykle projde několika různými stanovišti a každé z nich používá jiné prostředky. Když procesor instrukci načte, dekóduje, vykoná a zapíše výsledek, jednotka pro dekódování stojí ve chvíli, kdy pracuje sčítačka. Rozdělením na fáze se stanoviště zaplní: v každém taktu vstupuje do potrubí nová instrukce a z druhého konce jedna vypadává. Analogie s automobilovou linkou sedí přesně, včetně toho, že celé potrubí běží tempem nejpomalejší fáze.

Co pipelining zrychlí a co ne

Pipelining zvyšuje průchodnost (kolik položek se zpracuje za sekundu), ale latenci jedné konkrétní položky spíš mírně zhoršuje, protože mezi fáze přibývají registry nebo fronty. Pětistupňové potrubí neznamená pětinásobný výkon: praktický zisk snižují bublinové cykly a nerovnoměrné rozdělení práce. U síťových protokolů je efekt jiného druhu: odesláním více požadavků najednou se ušetří násobky RTT, takže se zkrátí i celkový čas, který uživatel vnímá.

Hazardy a to, co s nimi dělá hardware

Souběh fází naráží na tři typy konfliktů. Datový hazard nastane, když instrukce potřebuje výsledek, který ještě není zapsaný; řeší se forwardingem nebo zastavením potrubí. Strukturální hazard znamená, že dvě fáze chtějí tutéž jednotku. Řídicí hazard přichází s podmíněným skokem: procesor v okamžiku načítání ještě neví, kudy se poběží, a proto sází na predikci větvení. Chybná předpověď znamená zahození rozpracovaných instrukcí a znovunaplnění potrubí, což je u dlouhých pipeline řádově desítky taktů.

Kde se stejný princip objevuje mimo procesor

Termín se používá i mimo architekturu čipu. Grafická pipeline posílá vrcholy a fragmenty přes fáze zpracování na GPU. Redis umí přijmout dávku příkazů v jednom zápisu a odpovědět naráz. HTTP/1.1 pipelining definoval odeslání dalšího požadavku před přijetím odpovědi, v praxi ale ztroskotal na blokování v čele fronty (head-of-line blocking) a nekorektních proxy; prohlížeče ho vypnuly a nahradil ho multiplexing v HTTP/2. V datovém inženýrství se pipeline říká i řetězci transformací, kde je paralelismus fází vedlejší, ale myšlenka průtoku zůstává.

Kdy se potrubí nevyplatí

Pipelining dává smysl, když je dat hodně a jednotlivé položky na sobě příliš nezávisí. Silně větvený kód s nepředvídatelnými skoky, krátké dávky nebo případ, kdy klient potřebuje výsledek první operace k sestavení druhé, výhodu smažou. U protokolů navíc platí, že pipelining bez schopnosti odpovědi přerovnat vytváří frontu, kde jedna pomalá položka zdrží všechny za sebou.

Příklady z praxe

  1. Dávka příkazů do Redisu místo tisíce round-tripů

    Klient potřebuje zapsat tisíc klíčů. Bez pipeliningu čeká po každém SET na potvrzení, takže celkový čas je zhruba tisíckrát RTT. S pipeliningem odešle příkazy v několika síťových zápisech a odpovědi přečte naráz, čímž se z minut nad WAN linkou stanou desetiny sekundy. Podmínkou je, že žádný příkaz nepotřebuje výsledek předchozího.

    pipe = r.pipeline(transaction=False)
    for i in range(1000):
        pipe.set(f"key:{i}", i)
    pipe.execute()  # jedno kolo místo tisíce
  2. Chybná predikce větvení vyprázdní potrubí

    Cyklus prochází pole a podmínku vyhodnocuje podle neseřazených hodnot. Prediktor větvení se trefuje zhruba v polovině případů, takže procesor opakovaně zahazuje rozpracované instrukce a naplňuje potrubí znovu. Po seřazení pole se stejný kód bez jediné změny provede výrazně rychleji, protože skok se stane předvídatelným.

    // setřídění pole před tímto cyklem dramaticky
    // sníží počet chybných predikcí
    for (int i = 0; i < n; i++)
        if (data[i] >= 128) sum += data[i];

Časté omyly

MýtusPipeline s pěti fázemi je pětkrát rychlejší.
Ve skutečnostiZrychlení je vždy menší než počet fází. Takt určuje nejpomalejší fáze, mezi stupni přibývá režie registrů a hazardy i chybné predikce vkládají prázdné cykly.
MýtusPipelining zkracuje dobu zpracování jedné položky.
Ve skutečnostiPipelining zvyšuje průchodnost, ne latenci jedné položky. Jedna instrukce projde potrubím stejně dlouho nebo o něco déle; profit je v tom, že jich je uvnitř současně několik.
MýtusHTTP pipelining je běžně používaný způsob, jak zrychlit web.
Ve skutečnostiHTTP/1.1 pipelining sice standard umožňuje, ale hlavní prohlížeče ho kvůli blokování v čele fronty a nekompatibilním proxy nemají zapnutý. Praktickým řešením je multiplexing v HTTP/2 a HTTP/3.

Časté dotazy

Jak souvisí pipelining s délkou pipeline u moderních CPU?
Delší pipeline umožňuje vyšší taktovací frekvenci, protože každá fáze dělá méně práce a stihne se v kratším taktu. Cena je vyšší postih za chybnou predikci větvení: čím delší potrubí, tím víc rozpracovaných instrukcí se při špatném odhadu zahodí. Historicky se ukázalo, že extrémně dlouhé pipeline naráží na spotřebu i na tento postih, takže současné návrhy hledají kompromis a kombinují pipelining s vícenásobným vydáváním instrukcí a přeuspořádaným během.
Kdy pipelining na úrovni protokolu nepomůže?
Pipelining nepomůže, pokud další požadavek závisí na odpovědi předchozího, protože klient nemá co odeslat dopředu. Nepomůže ani u velmi malého počtu operací, kde režie dávkování převáží úsporu jednoho round-tripu, ani na velmi rychlé lince s nízkou latencí, kde je RTT zanedbatelné oproti práci na serveru. Problém nastává také tehdy, když protokol vyžaduje odpovědi ve stejném pořadí jako požadavky: jedna pomalá operace pak blokuje celou frontu.
Je pipelining totéž co paralelismus?
Pipelining je specifická forma paralelismu, kde současně běží různé fáze nad různými položkami, nikoli táž práce na více jednotkách. Klasický paralelismus zdvojuje výpočetní zdroje, aby dvě položky prošly celým zpracováním nezávisle. Pipelining naopak zdroje nezdvojuje, jen je nenechá stát naprázdno. Obojí se běžně kombinuje: superskalární procesor má více pipeline vedle sebe a v každé z nich probíhá zřetězené zpracování.
Jak poznám, že aplikace zbytečně čeká a hodil by se pipelining?
Typickým příznakem je nízké vytížení CPU i databáze při dlouhé celkové době běhu a velký počet drobných požadavků v profilu. Když trasování ukáže tisíce volání trvajících jednotky milisekund, kde většinu času tvoří síťové čekání, je pipelining nebo dávkování na místě. Pomůže spočítat, kolik round-tripů operace udělá: pokud roste lineárně s počtem záznamů, jde o klasický problém N+1, který se řeší dávkou, pipeliningem nebo jedním hromadným dotazem.

Zdroje

  1. Instruction pipelining(otevře se v novém okně)Wikipedia
  2. Redis pipelining(otevře se v novém okně)Redis
  3. RFC 9112: HTTP/1.1(otevře se v novém okně)IETF, 2022
  4. Connection management in HTTP/1.x(otevře se v novém okně)MDN Web Docs

Související pojmy

Potřebujete to vyřešit v praxi?

Poradíme, jak na to ve vašem projektu

Vysvětlit pojem je jedna věc, navrhnout kolem něj funkční řešení druhá. Ozvěte se a probereme, co dává smysl u vás.