Массивке негізделген кезек құлыптары - Array Based Queuing Locks

Массивке негізделген кезек күту (ABQL) жетілдірілген құлыптау жіптердің бірегей жадта айналуын қамтамасыз ететін алгоритм, осылайша масштабталуды жақсартумен бірге құлып алу әділдігін қамтамасыз етеді.

Шолу

Синхрондау жобалау мен бағдарламалаудың негізгі мәселесі болып табылады ортақ жады[1] мультипроцессорлар. Құлыпты іске асырудың жалпы проблемасы - бұл синхрондау жалаушасында немесе жад орнында айналатын процессорларға байланысты жоғары желілік қайшылық. Осылайша құлыптың масштабтылығы бәсекелес процессорлар саны жағынан айтарлықтай төмендейді.

Массивке негізделген кезек құлпы - кеңейту билет құлпы алгоритм, ол құлыпты босату кезінде тек бір процессор кэш санын азайтып, құлыпты алуға тырысады сағыныш. Мұндай әсерге барлық процессорлардың бірегей жад орындарында айналуы арқылы қол жеткізуге болады.[2] Құлыптау механизмін түсіндіру үшін қолданылатын бір ұқсастық - эстафетаны спортшы кезекте тұрған келесі спортшыға беретін эстафета, бұл эстафетаны бір уақытта тек бір спортшының алуына кепілдік береді.

ABQL сонымен қатар a көмегімен құлып алу әділдігіне кепілдік береді бірінші, бірінші (FIFO) кезекке негізделген механизм. Бұған қоса, жарамсыздық мөлшері билетке негізделген құлыпты енгізуден айтарлықтай аз, өйткені тек бір процессор құлыпты босатуда кэш жіберуді жібереді.

Іске асыру

Массивке негізделген кезек құлпын іске асырудың басты талабы - барлық ағындардың бірегей жад орындарында айналуын қамтамасыз ету. Бұған құлыпқа таласатын жіптер санына тең ұзындық массивімен қол жеткізіледі. Массивтің элементтері бірінші мәннен басталатын бірінші элементтен басқа 0-ге дейін инициализацияланған, осылайша кезектегі бірінші ағынмен құлыптың табысты алынуы қамтамасыз етіледі. Құлыптан босату кезінде кезек кезекте келесі жиымға массивтің келесі элементін 1 орнату арқылы беріледі, сұраныстар ағындарға FIFO тапсырысымен беріледі.

Псевдо кодының мысалы төменде келтірілген.[3]

ABQL_init(int *келесі_билет, int *қызмет ете алады){  *келесі_билет = 0;  үшін (int мен = 1; мен < МАКСИЗМ; мен++)    қызмет ете алады[мен] = 0;  қызмет ете алады[0] = 1; }ABQL_acquire(int *келесі_билет, int *қызмет ете алады){  *my_ticket = алу_және_инц(келесі_билет);  уақыт (қызмет ете алады [*my_ticket] != 1) ; }ABQL_релиз (int *қызмет ете алады){  қызмет ете алады[*my_ticket + 1] = 1;  қызмет ете алады[*my_ticket] = 0; // келесі кездесуге дайындалу}

ABQL-ді жоғарыдағы жалған кодқа енгізу үшін 3 айнымалы, яғни can_serve, next_ticket және my_ticket енгізілген. Әрқайсысының рөлдері төменде сипатталған:

  • қызмет ете алады массив құлыптауды алу кезегінде тұрған ағындар айналатын ерекше жад орындарын ұсынады.
  • келесі_билет жаңа ағынға тағайындалған келесі билет нөмірін білдіреді.
  • my_ticket кезектегі әрбір бірегей жіптің билеттік тізбегін білдіреді.

Инициализация әдісінде (ABQL_init) айнымалы келесі_билет барлық индикаторлары қызмет ете алады бірінші элементтен басқа массив 0-ге дейін инициализацияланған, массивтегі бірінші элементтің инициализациясы қызмет ете алады 1-ге дейін, кезектегі бірінші ағынмен құлыпты сәтті алуды қамтамасыз етеді.

Сатып алу әдісі атомдық жұмыс fetch_and_inc жаңа иірім үшін пайдаланылатын билеттің келесі қол жетімді нөмірін (содан кейін билет нөмірі 1-ге көбейтіледі) алу үшін. Кезектегі жіптер алдыңғы ағынмен my_ticket мәні 1-ге тең болғанша, өз орындарында айналады. Құлыпты алған кезде жіп кіреді маңызды бөлім код.

Жіптің көмегімен құлыпты босатқаннан кейін, басқару элементі келесі массивтегі келесі элементті орнатады: can_serve массивінде келесі элементті 1-ге қояды. Құлыпты алуды күткен келесі ағын енді оны сәтті орындай алады.

ABQL-дің жұмысын төмендегі кестеде жіп маңызды бөлікке бір рет енеді деген болжаммен критикалық бөлімге кіруге үміттенетін 4 процессорды суреттеуге болады.

Орындау қадамдары
келесі_билет
қызмет ете алады
my_ticket (P1)
my_ticket (P2)
my_ticket (P3)
my_ticket (P4)
Түсініктемелер
бастапқыда0[1, 0, 0, 0]0000барлық айнымалылардың бастапқы мәні 0-ге тең
P1: fetch_and_inc1[1, 0, 0, 0]0000P1 құлыпты сәтті сатып алады
P2: fetch_and_inc2[1, 0, 0, 0]0100P2 құлыпты алуға тырысады
P3: fetch_and_inc3[1, 0, 0, 0]0120P3 құлыпты алуға тырысады
P4: fetch_and_inc4[1, 0, 0, 0]0123P4 құлыпты алуға тырысады
P1: can_serve [1] = 1;

can_serve [0] = 0

4[0, 1, 0, 0]0123P1 құлыпты босатады, ал P2 құлыпты сәтті алады
P2: can_serve [2] = 1;

can_serve [1] = 0

4[0, 0, 1, 0]0123P2 құлыпты босатады, ал P3 құлыпты сәтті алады
P3: can_serve [3] = 1;

can_serve [2] = 0

4[0, 0, 0, 1]0123P3 құлыпты босатады, ал P4 құлыпты сәтті алады
P1: can_serve [3] = 04[0, 0, 0, 0]0123P4 құлыпты босатады

Өнімділік көрсеткіштері

Құлыпты іске асыруды талдау үшін келесі өнімділік өлшемдерін пайдалануға болады:

  • Бекітілмеген құлып алу кешігу - Бұл жіптің жоқ кезде құлып алуға болатын уақыты ретінде анықталады дау жіптер арасында. Басқа құлыпты енгізулерден гөрі орындалатын нұсқаулардың санының көп болуына байланысты, ABQL үшін құлыпты иемденудің кідіріс кідірісі жоғары.
  • Трафик - Бұл құлыпқа таласатын жіптер санына байланысты жасалған, автобустық транзакциялар саны ретінде анықталады. Құлыпты босату кезінде тек 1 кэш блогы жарамсыз болады, осылайша бір кэш жіберілмейді. Бұл автобустардың қозғалысын едәуір азайтуға әкеледі.
  • Әділдік - Бұл барлық процессорлардың сатып алуды күтуін қамтамасыз етеді құлыптау мұны олардың сұраныстары берілген тәртіпте жасай алады. Әр жіптің жеке жадында айналатын құлып алу үшін кезекте тұрған жіптердің арқасында әділеттілік қамтамасыз етіледі.
  • Сақтау орны - құлыптау механизмін өңдеуге қажет жад көлемі. Сақтау талабы массивтің ұлғаюына байланысты жіптер санымен өлшенеді қызмет ете алады.

Артықшылықтары

  • ABQL жетілдірілген масштабтылықты ұсынады, өйткені әрбір құлып алу немесе босату тек 1 кэш жіберуді бастайды, нәтижесінде блокты қайта жүктеу үшін кэш жіберуден зардап шегеді.
  • Құлыпты сатып алудың әділдігі кезектерді қолдану арқылы қамтамасыз етіледі, бұл жіптердің олардың жіптері берілген тәртіпте құлыпты сәтті алуына кепілдік береді.

Кемшіліктері

  • ABQL-ді тоқтатуға болатын ағындармен қолдануға болмайды (ұйқы немесе контекст ауыстырып қосыңыз), өйткені құлып алуға бірден дайын емес кез-келген жіп оның артында құлыпты күтіп отырғандардың кідірісін арттырады.

Сондай-ақ қараңыз

Пайдаланылған әдебиеттер

  1. ^ «Ортақ жадты мультипроцессорларда масштабты синхрондау алгоритмдері».
  2. ^ https://cs.unc.edu/~anderson/papers/survey.pdf
  3. ^ Солихин, Ян (2009). Компьютердің параллель архитектурасының негіздері: мультипипалы және көп ядролы жүйелер. 265–267 беттер. ISBN  978-0-9841630-0-7.