Array Based Queuing Locks - Array Based Queuing Locks

Zámek řazení na základě polí (ABQL) je pokročilý zámek algoritmus, který zajišťuje, že se vlákna točí na jedinečných paměťových místech, a tím zajišťuje spravedlivost získávání zámku spolu se zlepšenou škálovatelností.

Přehled

Synchronizace je hlavním problémem při navrhování a programování sdílená paměť[1] multiprocesory. Běžným problémem implementací zámku je vysoké tvrzení o síti kvůli procesorům otáčejícím se na sdíleném synchronizačním příznaku nebo na umístění paměti. Škálovatelnost zámku je tedy významně snížena, pokud jde o počet soupeřících procesorů.

Array Based Queuing Lock je rozšíření k zámek lístku algoritmus, který zajišťuje, že při uvolnění zámku se pokusí zámek získat pouze jeden procesor, čímž se sníží počet mezipaměti chybí. Tohoto efektu lze dosáhnout tím, že se všechny procesory budou otáčet na jedinečných paměťových místech.[2] Jednou analogií používanou k vysvětlení zamykacího mechanismu je štafetový závod, kdy sportovec předá obušek dalšímu sportovi ve frontě, což zajistí, že obušek získá současně pouze jeden sportovec.

ABQL také zaručuje férovost při získávání zámku pomocí a první dovnitř, první ven (FIFO) mechanismus založený na frontách. Kromě toho je množství zneplatnění podstatně menší než implementace zámku založeného na lístku, protože pouze jeden procesor narazí na uvolnění zámku v mezipaměti.

Implementace

Nejdůležitějším požadavkem implementace zámku fronty založeného na poli je zajistit, aby se všechna vlákna točila na jedinečných paměťových místech. Toho je dosaženo s řadou délek rovných počtu vláken, které jsou v rozporu se zámkem. Prvky pole jsou všechny inicializovány na 0 s výjimkou prvního prvku, který má hodnotu 1, čímž je zajištěno úspěšné získání zámku prvním vláknem ve frontě. Při uvolnění zámku je blokování předáno dalšímu vláknu ve frontě nastavením dalšího prvku pole na 1. Požadavky jsou vláknům uděleny v pořadí FIFO.

Příklad pseudokódu je uveden níže.[3]

ABQL_init(int *next_ticket, int *can_serve){  *next_ticket = 0;  pro (int i = 1; i < MAX. VELIKOST; i++)    can_serve[i] = 0;  can_serve[0] = 1; }ABQL_acquire(int *next_ticket, int *can_serve){  *my_ticket = fetch_and_inc(next_ticket);  zatímco (can_serve [*my_ticket] != 1) ; }ABQL_release (int *can_serve){  can_serve[*my_ticket + 1] = 1;  can_serve[*my_ticket] = 0; // připravte se na příště}

Pro implementaci ABQL do výše uvedeného pseudokódu jsou zavedeny 3 proměnné, a to can_serve, next_ticket a my_ticket. Role každého z nich jsou popsány níže:

  • can_serve pole představuje jedinečná umístění paměti, na která se vlákna čekající ve frontě na akvizice zámku točí.
  • next_ticket představuje další dostupné číslo tiketu, které je přiřazeno novému vláknu.
  • my_ticket představuje vlákno lístku každého jedinečného vlákna ve frontě.

V metodě inicializace (ABQL_init) proměnná next_ticket je inicializován na 0. Všechny prvky can_serve pole kromě prvního prvku se inicializuje na 0. Inicializace prvního prvku v poli can_serve na 1, zajišťuje úspěšné získání zámku prvním vláknem ve frontě.

Metoda získání používá atomová operace fetch_and_inc k načtení dalšího dostupného čísla tiketu (poté se číslo tiketu zvýší o 1), které nové vlákno použije k roztočení. Vlákna ve frontě se točí na svých místech, dokud hodnota my_ticket není nastavena na 1 předchozím vláknem. Po získání zámku vlákno vstupuje do kritická sekce kódu.

Při uvolnění zámku vláknem je ovládací prvek předán dalšímu vláknu nastavením dalšího prvku v poli can_serve na 1. Další vlákno, které čekalo na získání zámku, to nyní může úspěšně provést.

Fungování ABQL lze znázornit v následující tabulce za předpokladu, že 4 procesory soupeřící o vstup do kritické sekce za předpokladu, že vlákno vstoupí do kritické sekce pouze jednou.

Prováděcí kroky
next_ticket
can_serve
my_ticket (P1)
my_ticket (P2)
my_ticket (P3)
my_ticket (P4)
Komentáře
zpočátku0[1, 0, 0, 0]0000počáteční hodnota všech proměnných je 0
P1: fetch_and_inc1[1, 0, 0, 0]0000P1 se pokusí a úspěšně získá zámek
P2: fetch_and_inc2[1, 0, 0, 0]0100P2 se pokusí získat zámek
P3: fetch_and_inc3[1, 0, 0, 0]0120P3 se pokusí získat zámek
P4: fetch_and_inc4[1, 0, 0, 0]0123P4 se pokusí získat zámek
P1: can_serve [1] = 1;

can_serve [0] = 0

4[0, 1, 0, 0]0123P1 uvolní zámek a P2 úspěšně získá zámek
P2: can_serve [2] = 1;

can_serve [1] = 0

4[0, 0, 1, 0]0123P2 uvolní zámek a P3 úspěšně získá zámek
P3: can_serve [3] = 1;

can_serve [2] = 0

4[0, 0, 0, 1]0123P3 uvolní zámek a P4 úspěšně získá zámek
P1: can_serve [3] = 04[0, 0, 0, 0]0123P4 uvolní zámek

Metriky výkonu

K analýze implementací zámku lze použít následující výkonnostní kritéria:

  • Nekontrolované získávání zámku latence - Je definován jako čas, který vlákno potřebuje k získání zámku, když žádný neexistuje tvrzení mezi vlákny. Kvůli relativně většímu počtu prováděných instrukcí na rozdíl od jiných implementací zámku je latence získávání nekontrolovaného zámku pro ABQL vysoká.
  • Provoz - Je definován jako počet generovaných transakcí sběrnice, který je závislý na počtu vláken v soupeření o zámek. Při uvolnění zámku je zneplatněn pouze 1 blok mezipaměti, což má za následek jednu chybějící mezipaměť. Výsledkem je mnohem menší provoz autobusů.
  • Spravedlnost - Zajišťuje, že všichni procesory čekající na získání zámek jsou schopni tak učinit v pořadí, v jakém jsou jejich žádosti vydány. Kvůli vláknům čekajícím ve frontě na získání zámku s každým vláknem otáčejícím se na jednotlivém paměťovém místě je zajištěna spravedlnost.
  • Úložný prostor - Množství paměti potřebné pro zpracování blokovacího mechanismu. Požadavek na úložiště se mění s počtem vláken kvůli zvětšení velikosti pole can_serve.

Výhody

  • ABQL nabízí vylepšenou škálovatelnost, protože každé získání nebo uvolnění zámku spustí pouze 1 mezipaměť mezipaměti, což má za následek, že mezipaměť mezipaměti bude muset znovu načíst pouze mezipaměť.
  • Spravedlivost akvizice zámku je zajištěna díky použití fronty, která zajišťuje, že vlákna získají zámek úspěšně v pořadí, v jakém jsou jejich vlákna vydána.

Nevýhody

  • ABQL by neměl být používán s vlákny, která mohou být pozastavena (režim spánku nebo kontext switch), protože jakékoli vlákno, které není okamžitě připraveno k získání zámku, zvýší latenci všech těch, kteří za ním čekají na zámek.

Viz také

Reference

  1. ^ „Algoritmy pro škálovatelnou synchronizaci na víceprocesorech se sdílenou pamětí“.
  2. ^ https://cs.unc.edu/~anderson/papers/survey.pdf
  3. ^ Solihin, Yan (2009). Základy paralelní počítačové architektury: vícečipové a vícejádrové systémy. 265–267. ISBN  978-0-9841630-0-7.