Dynamická vyrovnávací pamět perzistentních datových struktur Dynamic Cache Memory for a Persistent Data Structures

Podobné dokumenty
Systém adresace paměti

Mezipaměti počítače. L2 cache. L3 cache

Přidělování paměti II Mgr. Josef Horálek

Architektury počítačů a procesorů

Semestrální práce 2 znakový strom

1. Databázové systémy (MP leden 2010)

Operační systémy. Přednáška 9: Správa paměti III

Výukový materiál Hardware je zaměřený především na výuku principů práce hardwaru a dále uvádí konkrétní příklady použití.

Procesy a vlákna - synchronizace

Přednáška. Správa paměti II. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Paměťový podsystém počítače

Kapitola 10: Diskové a souborové struktury. Klasifikace fyzických médií. Fyzická média

Operační systémy. Jednoduché stránkování. Virtuální paměť. Příklad: jednoduché stránkování. Virtuální paměť se stránkování. Memory Management Unit

09. Memory management. ZOS 2006, L.Pešička

Relační DB struktury sloužící k optimalizaci dotazů - indexy, clustery, indexem organizované tabulky

Správy cache. Martin Žádník. Vysoké učení technické v Brně, Fakulta informačních technologií v Brně Božetěchova 2, Brno

Princip funkce počítače

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Základní datové struktury

Systém souborů (file system, FS)

Kapitola 13: Transakce. Koncept transakce. ACID vlastnosti

Management procesu I Mgr. Josef Horálek

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Řízení IO přenosů DMA řadičem

Principy operačních systémů. Lekce 6: Synchronizace procesů

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

Architektura Intel Atom

Databáze Bc. Veronika Tomsová

Obsah. Kapitola 1 Hardware, procesory a vlákna Prohlídka útrob počítače...20 Motivace pro vícejádrové procesory...21

3. úloha - problém batohu metodami branch & bound, dynamické programování, heuristika s testem

Přidělování zdrojů (prostředků)

Časová a prostorová složitost algoritmů

Paměti cache. Cache může být realizována softwarově nebo hardwarově.

Principy operačních systémů. Lekce 3: Virtualizace paměti

Složitost algoritmů. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava

ČVUT FEL X36PAA - Problémy a algoritmy. 4. úloha - Experimentální hodnocení algoritmů pro řešení problému batohu

Algoritmy a datové struktury

Základy programování. Úloha: Eratosthenovo síto. Autor: Josef Hrabal Číslo: HRA0031 Datum: Předmět: ZAP

Spojová implementace lineárních datových struktur

Složitosti základních operací B + stromu

2. úkol MI-PAA. Jan Jůna (junajan)

Program a životní cyklus programu

Struktura a architektura počítačů (BI-SAP) 11

Lineární datové struktury

Administrace Oracle. Práva a role, audit

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

TGH07 - Chytré stromové datové struktury

Dynamické datové struktury IV.

Správa paměti. doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 /

Pohled do nitra mikroprocesoru Josef Horálek

Nový způsob práce s průběžnou klasifikací lze nastavit pouze tehdy, je-li průběžná klasifikace v evidenčním pololetí a školním roce prázdná.

Dynamické datové struktury III.

Přednáška. Správa paměti I. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Databáze I. 5. přednáška. Helena Palovská

Činnost počítače po zapnutí

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

Profilová část maturitní zkoušky 2013/2014

2010/2011 ZS P i r i nc č py po ít č čů a PAMĚŤOVÝ ĚŤ SUBSYSTÉM z pohledu OS OS

Technické informace. PA152,Implementace databázových systémů 4 / 25. Projekty. pary/pa152/ Pavel Rychlý

1/1 ČESKÁ ZEMĚDĚLSKÁ UNIVERZITA V PRAZE PROVOZNĚ EKONOMICKÁ FAKULTA PŘIJÍMACÍ ŘÍZENÍ 2017/2018

Struktura pamětí a procesů v DB Oracle. Radek Strnad

IB111 Úvod do programování skrze Python

Přednáška. Správa paměti III. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Algoritmy a datové struktury

Systém souborů Mgr. Josef Horálek

ÚVOD DO OPERAČNÍCH SYSTÉMŮ. Správa paměti. Přímý přístup k fyzické paměti, abstrakce: adresový prostor, virtualizace, segmentace

Cvičení č. 3. Sdílené prostředky a synchronizace Program Banka. 4 body

1 Osobní počítač Obecně o počítačích Technické a programové vybavení... 4

Universita Pardubice Fakulta elektrotechniky a informatiky. Mikroprocesorová technika. Semestrální práce

Přednáška. Vstup/Výstup. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Přidělování CPU Mgr. Josef Horálek

SQL tříhodnotová logika

Překladač a jeho struktura

Paralelní programování

Popis programu EnicomD

04 - Databázové systémy

Iterační výpočty. Dokumentace k projektu č. 2 do IZP. 24. listopadu 2004

Datové struktury 2: Rozptylovací tabulky

Paralení programování pro vícejádrové stroje s použitím OpenMP. B4B36PDV Paralelní a distribuované výpočty

Disková pole (RAID) 1

Disková pole (RAID) 1

Operační systémy 2. Struktura odkládacích zařízení Přednáška číslo 10

Operační systémy. Správa paměti (SP) Požadavky na SP. Spojování a zavedení programu. Spojování programu (linking) Zavádění programu (loading)

Jako pomůcka jsou v pravém dolním rohu vypsány binární kódy čísel od 0 do 15 a binární kódy příkazů, které máme dispozici (obr.21). Obr.

Využití OOP v praxi -- Knihovna PHP -- Interval.cz

Přednáška. Systémy souborů. FAT, NTFS, UFS, ZFS. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Algoritmy výpočetní geometrie

Výpočet v módu jádro. - přerušení (od zařízení asynchronně) - výjimky - softvérové přerušení. v důsledku událostí

Operační systémy 2: Zápočtové úkoly

Při překrývání se využívá toho, že ne všechny moduly programu jsou vyžadovány současně. Jakmile skončí využívání jednoho

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Procesy a vlákna (Processes and Threads)

8.2 Používání a tvorba databází

Uživatelský manuál. Aplikace GraphViewer. Vytvořil: Viktor Dlouhý

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

Úvod. Programovací paradigmata

Základní pojmy. Program: Algoritmus zapsaný v programovacím jazyce, který řeší nějaký konkrétní úkol. Jedná se o posloupnost instrukcí.

Michal Krátký. Tvorba informačních systémů, 2008/2009. Katedra informatiky VŠB Technická univerzita Ostrava. Tvorba informačních systémů

UNIVERZITA PARDUBICE

Transkript:

VŠB Technická univerzita Ostrava Fakulta elektrotechniky a informatiky Katedra informatiky Dynamická vyrovnávací pamět perzistentních datových struktur Dynamic Cache Memory for a Persistent Data Structures 2015 Bc. Radim Holek

Abstrakt Cílem této diplomové práce je navrhnout a implementovat dynamickou vyrovnávací pamět perzistentních datových struktur. Takováto pamět je důležitou součástí každého databázového systému. Umožňuje systému přistupovat k datům v databázi, které jsou uloženy na disku, mnohem rychleji, než by tomu bylo bez vyrovnávací paměti. Dále jsou v práci popsány základní komponenty databázových systémů. Součástí práce je i porovnání vytvořené vyrovnávací paměti s jinou již existující vyrovnávací pamětí. Vyvinutá vyrovnávací pamět bude sloužit jako náhrada stávající vyrovnávací paměti databázového systému RadegastDB. Klíčová slova: vyrovnávací pamět, databázový systém, LRU-K, Least recently used, algoritmy pro nahrazování stránek, RadegastDB Abstract The goal of this thesis is to design and implement dynamic cache memory for a persistent data structures. Cache is an important part of every database system. It allows database system to access data in database, which are stored on disk, much quicker than without cache. There is also brief description of components of database systems. Thesis also contains comparison of implemented cache memory with an existing one. Implemented cache memory will serve as replacement of current cache memory in database system RadegastDB. Keywords: cache memory, database system, LRU-K,Least recently used, page replacement algorithms, RadegastDB

Seznam použitých zkratek a symbolů LFU Least frequently used LRU Least recently used LRU-K Least recently used - K OS Operační systém

1 Obsah 1 Úvod 6 1.1 Cíle práce...................................... 6 1.2 Důvod vzniku práce............................... 6 1.3 Uspořádání práce................................. 6 2 Databázové systémy 8 2.1 Relační databáze................................. 8 2.2 Ukládání na disk a souborový systém..................... 8 3 Vyrovnávací paměti 11 3.1 Ideální algoritmus a náhodné nahrazování.................. 11 3.2 Cyklické nahrazování............................... 12 3.3 Druhá šance.................................... 13 3.4 Not Recently Used (NRU)............................ 14 3.5 Least Frequently Used (LFU).......................... 14 3.6 Least Recently Used (LRU)............................ 15 3.7 Least Recently Used K (LRU-K)......................... 17 3.8 Ukládání stránek................................. 19 4 Více-vláknové aplikace 21 4.1 Problémy s více vlákny.............................. 21 5 Vlastní implementace 24 5.1 Návrh systému.................................. 24 5.2 Části cnodecache................................. 24 5.3 Zamykání stránek................................. 26 5.4 Čistící vlákno................................... 26 5.5 Změna velikosti vyrovnávací paměti...................... 27 5.6 Načítání stránky.................................. 28 5.7 Podpora více-vláknového přístupu....................... 33 5.8 Mazání starých cnodeinfo........................... 33 6 Porovnání implementací 36 6.1 Změny rozhraní.................................. 36 6.2 Porovnání funkcionalit.............................. 36 6.3 Porovnání výkonu................................ 38 6.4 Test změny velikosti............................... 43 7 Závěr 45 7.1 Zhodnocení výkonu............................... 45 7.2 Další použití vyrovnávací paměti........................ 46 8 Reference 47

Přílohy 48 2

3 Seznam tabulek 1 Počet přístupů v čase t 6.............................. 15 2 Poslední přístupy v čase t 4............................ 16 3 Přístupy v čase t 4................................. 18 4 Statistiky testovaného B-stromu pevné délky................. 39 5 Test B-stromu pevné délky............................ 39 6 Test B-stromu pevné délky bez synchronizace................. 40 7 Statistiky testovaného B-stromu variabilní délky............... 41 8 Test B-stromu variabilní délky.......................... 41 9 Test B-stromu variabilní délky bez synchronizace............... 41 10 Test B-stromu pevné délky s čekáním..................... 42 11 Test B-stromu variabilní délky s čekáním................... 43 12 Test zvětšení velikosti vyrovnávací paměti.................. 44 13 Test Zmenšení velikosti vyrovnávací paměti................. 44

4 Seznam obrázků 1 Struktura databázového systému [3]...................... 9 2 Pozice vyrovnávací paměti v rámci RadegastDB............... 25 3 Struktura systému................................. 25 4 Problém se synchronizací............................ 34

5 Seznam algoritmů 1 Obecný postup vyrovnávací paměti....................... 12 2 Cyklické nahrazování - UvolniStranku..................... 13 3 LFU - UvolniStranku................................ 15 4 LFU - DokonciAlgoritmus............................. 15 5 LRU - UvolniStranku................................ 16 6 LRU - DokonciAlgoritmus............................ 16 7 LRU-K - UvolniStranku.............................. 19 8 LRU-K - DokonciAlgoritmus........................... 20 9 Změna velikosti vyrovnávací paměti....................... 29 10 Postup při načítání existující stránky....................... 30 11 Postup při načítání nové stránky......................... 31 12 ZiskejVolnyBlokPameti.............................. 32 13 ZiskejKandidata.................................. 32

6 1 Úvod 1.1 Cíle práce Cílem této diplomové práce je implementovat vyrovnávací pamět pro relační databázový systém. Vyrovnávací pamět je důležitou součástí každého databázového systému. Slouží k zvýšení propustnosti databázového systému tím, že sníží počet diskových operací. Konkrétně se bude jednat o vyrovnávací pamět pro databázový systém RadegastDB vyvíjený Katedrou informatiky Fakulty elektrotechniky a informatiky Vysoké školy báňské - Technické univerzity Ostrava. Součástí práce je i prozkoumání možností implementace dynamických vyrovnávacích pamětí a algoritmů pro nahrazování stránek v paměti. A to jak obecných algoritmů, tak algoritmů navržených přímo pro použití v databázových systémech. Popsány jsou i důvody proč není vhodné použití obecných algoritmů pro databázové systémy. 1.2 Důvod vzniku práce Databázový systém RadegastDB sice již obsahuje vyrovnávací pamět. Nicméně tato implementace nedisponuje funkcemi, které mohou být potřebné pro vylepšení funkčnosti databázového systému RadegastDB. Hlavním cílem a důvodem vzniku práce je vytvoření nové implementace vyrovnávací paměti RadegastDB, která bude moci nahradit stávající implementaci, a která rozšíří funkčnost vyrovnávací paměti systému RadegastDB. Přidaná funkčnost bude spočívat hlavně v: Možnosti měnit velikost vyrovnávací paměti za běhu Dřívějším ukládání stránek se špinavými daty Umožnění více-vláknového přístupu k vyrovnávací paměti Hlavním cílem je rozšíření funkčnosti a možností vyrovnávací paměti, nikoliv zvýšení výkonu a propustnosti paměti. 1.3 Uspořádání práce Druhá kapitola je věnována krátkému přestavení databázových systémů a jejich nejdůležitějších komponent. Třetí kapitola práce je věnována vysvětlení potřeby vyrovnávací paměti a popisu existujících algoritmů pro nahrazování stránek v paměti. Je zde popsána i vhodnost jednotlivých algoritmů pro použití v rámci databázového systému. Čtvrtá kapitola je věnována popisu problémů více vláknových aplikací a technik, které slouží k jejich řešení. Pátá kapitola práce je věnována popisu implementace vyrovnávací paměti. V této části jsou vyobrazeny a popsány důležité prvky vyrovnávací paměti stejně tak jako použité postupy a algoritmy. A také popisy nejdůležitějších algoritmů použitých v nové implementaci.

Šestá kapitola je věnována porovnání nové implementace vyrovnávací paměti se stávající implementací v rámci databázového systému RadegastDB. Jsou zde popsány rozšiřující funkce nové implementace oproti implementaci stávají a je zde provedeno porovnání výkonu a propustnosti jednotlivých implementací. 7

8 2 Databázové systémy V době, kdy se převážná většina údajů z různých oborů lidské činnosti zpracovává počítačově a data se ukládají v digitální podobě jsou potřeba úložiště dat, která zvládnou uchovat velké množství dat a dokážou mezi těmito daty rozumně vyhledávat. Existuje celá řada možností, jak data ukládat. Od pouhé struktury souborů na disku po rozsáhlé databázové systémy. Jedním z dnes nejpoužívanějších typů databázových systémů jsou relační databázové systémy. 2.1 Relační databáze Relační databázové systémy slouží k ukládání dat, aniž by se musel uživatel (či aplikace, která systém využívá) nějak zásadně zajímat o způsob uložení. Umožňují ukládat téměř neomezené množství dat, ačkoliv jsou omezeny hardwarem počítače, na kterém je systém spuštěn, a provádět poměrně snadné a rychlé vyhledání v uložených datech. Databázový systém se skládá z několika komponent. Jednoduchý diagram komponent je vidět na obrázku 1. Jak je vidět z obrázku, databázový systém se obvykle skládá z uživatelského rozhraní, které slouží pro zadávání příkazů do databáze, komponenty pro zpracování dotazu (Query procesor), komponenty pro správu úložiště (Storage manager) a samotného diskového úložiště [1]. Query procesor vyhodnocuje dotazy, které přichází z uživatelského rozhraní. Provádí převod dotazu z textové formy, ve které je zadán uživatelem, do strojově zpracovatelné formy, optimalizaci dotazu, samotné zpracování dotazu a předání výsledku zpět uživatelskému rozhraní. Storage manager řídí přístup k perzistentní datové struktuře, kde jsou uložena samotná data. Jednou z jeho nejdůležitějších částí je vyrovnávací pamět, jejíž funkce je podrobněji popsána v kapitole 3. Další důležitou částí je manažer souběhu (Transaction manager), který zabraňuje vzniku konfliktů při souběžném přístupu ke sdíleným prostředkům a tím zabrání vzniku ne-konzistence mezi daty. Jednou z možností jak konfliktům předcházet je zamykání stránek. Spočívá v zabránění přístupů ke sdíleným prostředkům více než jednomu procesu najednou. Nemůže se pak stát, že by jeden proces měnil data jinému procesu pod rukama. Diskové úložiště obsahuje systémová data, která jsou potřeba pro provoz databáze, např. struktura databáze, nastavení, atd., statistická data, indexy a uživatelská data samotná. Pokud není databáze extrémně malá, pak je jasné, že největší část budou tvořit právě uživatelská data a indexy. 2.2 Ukládání na disk a souborový systém Pokud by měl Query procesor při vykonávání dotazu přistupovat pouze k jedné hodnotě dat o velikosti několika bytů byla by tato operace značně náročná, protože by dostával údaje ze Storage manageru po malých částech, což by se projevilo na výkonu i komplexitě programu. Často se totiž stává, že Query procesor potřebuje i data sousední, například proto, že provádí výpis všech hodnot pro jednu entitu reálného světa. Proto se většinou

Obrázek 1: Struktura databázového systému [3] 9

uživatelská data skládají do bloků dat, které mají stanovenou velikost. Pokud pak Query procesor potřebuje nějakou hodnotu z datového úložiště, tak požádá o načtení celého bloku, ze které si požadovanou hodnotu získá sám. Skládání do bloků zároveň zjednoduší práci Storage manageru tím, že nebude muset provádět tolik operací. Nutnost skládat data do bloku zároveň souvisí se souborovým systémem operačního systému. Každý OS, který pracuje s diskem, nepracuje s jednotlivými byty na disku, ale ukládá je po blocích, které mají pevnou velikost. Tyto bloky mají většinou velikost 2048 bytů. Velikost databázové stránky je tedy volena jako násobek velikost diskového bloku. Nejčastěji 2048, 4096 nebo 8192 bytů tak, aby načtení jedné stránky bylo co nejefektivnější. 10

11 3 Vyrovnávací paměti Většina dnešních databázových systémů ukládá data, která obsahuje, do nějakého perzistentního datového úložiště. Typicky se jedná o disk. Rychlost čtení a zápisu na disk je velmi malá v porovnání s rychlostí čtení a zápisu z operační paměti počítače. A to i u disků typu SSD, které jsou značně rychlejší než pevné disky. Proto by bylo vhodné používat disk pouze jako úložiště dat pro případ výpadku nebo odstávky systému a s daty pracovat v operační paměti počítače. V současné době je 1GB v operační paměti výrazně dražší než 1GB na diskovém úložišti. Proto není vždy možné zajistit dostatečné množství operační paměti pro celou databázi a je třeba vhodně nahrazovat již nepotřebné části databáze v paměti jinými. Tato kapitola se věnuje popisu algoritmů pro nahrazování stránek v obecné vyrovnávací paměti i algoritmů vhodných pro vyrovnávací paměti databázových systémů. Existují situace, ve kterých se databáze chová odlišně než běžná vyrovnávací pamět. V další části předpokládejme, že databáze je rozdělena na databázové stránky o pevné velikosti, které představují z pohledu přístupu k disku atomickou část databáze. U obecných algoritmů pro nahrazování stránek předpokládejme stránky o pevné velikosti. Předpokládejme, že vyrovnávací pamět má vždy kapacitu rovnou násobku velikosti stránky souborového systému, takže se do ní vejde přesně x databázových stránek, kde x je celé číslo. Dále předpokládejme, že při startu je vyrovnávací pamět volná. Obecný postup je popsán v algoritmu 1. Při každém požadavku na načtení databázové stránky se zkontroluje, zda již není ve vyrovnávací paměti (řádky 3 a 4) a pokud ne, tak se uvolní databázová stránka (řádek 7), pokud je modifikována, tak se změny uloží (řádky 8 a 9), a požadovaná stránka se načte z disku na uvolněný blok paměti (řádek 11). Provedou se funkce spojené s použitým algoritmem (řádek 12) a poté se databázová stránka předá předá ke zpracování. Funkce UvolniStranku a DokonciAlgoritmus jsou specifické pro jednotlivé algoritmy a popsané v následujících kapitolách. Některé z popisovaných algoritmů můžou být použity i pro implementaci virtuální paměti operačního systému. Virtuální pamět slouží ke zvětšení fyzické operační paměti využitím diskového prostoru. Správné identifikace nejméně potřebných stránek je důležitá i v tomto případě. Existuje řada algoritmů pro nahrazování stránek ve vyrovnávací paměti [7]. V této kapitole jsou popsány nejdůležitější z nich. 3.1 Ideální algoritmus a náhodné nahrazování Ideální algoritmus pro výběr nepotřebné stránky by měl vybrat takovou stránku, která bude potřeba nejdále v budoucnosti a tedy uplyne nejvíce času mezi jejím smazáním a dalším načtením. Ovšem vytvořit takovýto algoritmus bez podrobnější znalosti potřeb systému, které nelze u databázového systému určit, není možné. Program nemůže dopředu vědět, o která data uživatel požádá. Proto je třeba zvolit nějaký jiný přístup. Příklad Mějme vyrovnávací pamět s kapacitou dva. V čase t 1 je načtena stránka s 1. V čase t 2 je načtena stránka s 2. V čase t 3 má být načtena stránka s 3 a protože je vyrovnávací

12 Algoritmus 1: Obecný postup vyrovnávací paměti 1 Funkce NactiStranku(CisloStranky) 2 if!jestrankavevyrovnavacipameti(cislostranky) then 3 if JeVyrovnavaciPametiVolna then 4 VolnyBlokVyrovnavaciPameti = VolnyBlok; 5 else 6 CisloStrankyKOdstraneni = UvolniStranku(); 7 if JeModifikovana(CisloStrankyKOdstraneni) then 8 UlozNaDisk(CisloStrankyKOdstraneni); 9 VolnyBlokVyrovnavaciPameti =VyrovnavaciPamet[CisloStrankyKOdstraneni]; 10 NactiZDisku(CisloStranky,VolnyBlokVyrovnavaciPameti); 11 DokonciAlgoritmus(CisloStranky); 12 return VyrovnavaciPamet[CisloStranky]; pamět plná, musí být některá stránka odstraněna. Víme, že stránka s 1 bude znovu vyžádána v čase t 23 a stránka s 2 bude znovu vyžádána v čase t 15. Z vyrovnávací paměti bude tedy odstraněna stránka s 1, protože bude znovu vyžádána nejdále v budoucnosti. Jedním z nejjednodušších přístupů k nahrazování stránek je náhodné nahrazování. Pokud ve vyrovnávací paměti dojde místo je vybrána náhodná stránka a ta je nahrazena. Již z principu je je jasné, že takový algoritmus není příliš efektivní, protože nejvíce i nejméně používaná stránka budou mít stejnou pravděpodobnost pro nahrazení. Příklad Mějme vyrovnávací pamět s kapacitou dva. V čase t 1 je načtena stránka s 1. V čase t 2 je načtena stránka s 2. V čase t 3 má být načtena stránka s 3 a protože je vyrovnávací pamět plná, musí být některá stránka odstraněna. Za použití pseudonáhodného algoritmu je vybrána stránka s 2. Nyní mějme stejnou situaci. Pamět s kapacitou dva. V čase t 1 je načtena stránka s 1 a v čase t 2 je načtena stránka s 2. Ovšem nyní je pro odstranění vybrána stránka s 1 Algoritmus bude tedy muset nějakým způsobem sledovat a zaznamenávat historii přístupu k disku a na jejím základě vybírat nejvíce vhodné stránky. 3.2 Cyklické nahrazování Jednoduchých přístupem k problému je nahrazování stránek cyklickým způsobem. Pokud dojde místo ve vyrovnávací paměti, tak se nahradí nejstarší stránka, tedy ta, která byla načtena jako první. Spočívá tedy ve vytvoření jakési fronty stránek k nahrazení a principu First-in First-out.

13 Tento postup nezohledňuje důležitost stránky v rámci databáze, takže stránky s velmi častým přístupem budou nahrazeny se stejnou pravděpodobností jako stránky, které jsou vyžádány zřídka. Z toho důvodu je tento algoritmus velmi neefektivní. V algoritmu 2 je načrtnut obecný postup tohoto algoritmu při načítání stránky z vyrovnávací paměti. Funkce UvolniStranku je volána z obecného postupu v algoritmu 1. Na řádku 2 se vybírá nejstarší stránka. Příklad 1 Mějme vyrovnávací pamět s kapacitou dva. V čase t 1 je načtena stránka s 1. V čase t 2 je načtena stránka s 2. V čase t 3 má být načtena stránka s 3 a protože je vyrovnávací pamět plná, tak bude z paměti odstraněna stránka s 1. Příklad 2 Mějme vyrovnávací pamět s kapacitou dva. V čase t 1 je načtena stránka s 1. V čase t 2 je načtena stránka s 2.V čase t 3 je opět načtena stránka s 1. V čase t 4 má být načtena stránka s 3 a protože je vyrovnávací pamět plná, tak bude z paměti odstraněna stránka s 1, přestože byla použita jako poslední a je pravděpodobné, že bude použita znovu. Algoritmus 2: Cyklické nahrazování - UvolniStranku 1 Funkce UvolniStranku() 2 CisloStrankyKOdsraneni = NejstarsiStranka.Cislo; 3 return CisloStrankyKOdsraneni; 3.3 Druhá šance Mírně upravenou verzí cyklického nahrazování je algoritmus Druhá šance (anglicky - Second chance). Spočívá ve vytvoření indikátoru přístupu ke stránce. Počátečně je nastaven na 1 a při přístupu k dané stránce se nastaví na 1. Při potřebě odstranění stránky z vyrovnávací paměti dojde ke kontrole stránky, která je první ve frontě, na indikátor přístupu. Pokud je nastaven na 0, tak je stránka odstraněna. Pokud je nastaven na 1, tak je stránka přesunuta na konec fronty a indikátor přístupu je nastaven na 0. Mohlo by se zdát, že zde může dojít k zacyklení, ale není to možné. Pokaždé, když databázová stránka dostane druhou šanci, tak je referenční bit nastaven na 0, takže při dalším výběru této stránky už druhou šanci nedostane. Příklad Mějme vyrovnávací pamět s kapacitou dva. V čase t 1 je načtena stránka s 1. V čase t 2 je načtena stránka s 2. V čase t 3 má být načtena stránka s 3 a protože je vyrovnávací pamět plná, tak se zkontroluje indikátor přístupu stránky s 1, která je první ve frontě. Indikátor je nastaven na 1, takže stránka je posunuta na konec fronty a indikátor nataven na 0. Další ve frontě je stránka s 2, která má rovněž nastaven indikátor přístupu na 1, takže je také posunuta na konec fronty a její indikátor přístupů nastaven na 0. Další ve frontě bude opět stránka s 1, protože již bylo dosaženo konce původní fronty. Stránka s 1 má nyní nastaven indikátor přístupu na 0, takže je odstraněna z paměti.

14 3.4 Not Recently Used (NRU) Jedním z možných algoritmů je i Not Recently Used (dále NRU) - Nedávno nepoužitá stránka [6]. Princip spočívá v existenci dvou bitů pro každou stránku - referenční a modifikační bit, které jsou inicializačně nastaveny na 0. Pokaždé, když je ke stránce přistoupeno, je nastaven referenční bit a pokaždé, když je stránka modifikována, je nastaven modifikační bit. V daném časovém intervalu se všechny referenční bity nastaví na 0. Pokud je potřeba odstranit stránku z paměti, dojde k rozdělení všech stránek z paměti na čtyři kategorie: 0 - referenční bit = 0 a modifikační bit = 0 1 - referenční bit = 0 a modifikační bit = 1 2 - referenční bit = 1 a modifikační bit = 0 3 - referenční bit = 1 a modifikační bit = 1 K odstranění je náhodně vybrána stránka z nejnižší kategorie, která obsahuje alespoň jednu stránku. Příklad Mějme vyrovnávací pamět s kapacitou dva, která obsahuje stránky s 1 a s 2. Obě mají nastaveny referenční i modifikační bit na 0. V časech t 1 - t 3 dojde k přístupu a modifikaci stránky s 1 a přístupu ke stránce s 2. V čase t 4, kdy stránka s 1 spadá do kategorie 3 a stránka s 2 do kategorie 2, je vyslán požadavek na načtení stránky s 3 a z paměti je uvolněna stránka s 2, protože spadá do nižší kategorie než stránka s 1. Výhodou toho algoritmu je relativní jednoduchost. Nebylo by příliš složité implementovat jej hardwarově, protože by se jednalo pouze o nastavení dvou bitů a resetování jednoho, když je detekován hodinový signál. V některých situacích by hardwarově řízená vyrovnávací pamět byla výkonnější než pamět řízena softwarově. 3.5 Least Frequently Used (LFU) Dalším algoritmem je Least Frequently Used (dále LFU) - Nejméně používané stránky. Princip tohoto algoritmu spočívá v počítání počtu přístupů k jednotlivým stránkám a při potřebě odstranění stránky z paměti vybrání stránky s nejmenším počtem přístupů. Jednoduchou implementací by bylo vytvoření počítadla pro každou databázovou stránku a při přístupu ke stránce by se počítadlo navýšilo. Tento prostup demonstruje algoritmus 3, kde se na řádku 2 vybírá stránka s nejnižší hodnotou počítadla. Výběr může být proveden jakýmkoliv algoritmem pro výběr minima. V algoritmu 4 se provádí zvýšení počítadla při načtení stránky. Příklad Mějme vyrovnávací pamět o velikosti dvou stránek. V čase t 1 je přistoupeno ke stránce s 1. V čase t 2 je přistoupeno ke stránce s 2. V časech t 3 a t 4 je opět přistoupeno ke stránce s 2. V čase t 5 je přistoupeno ke stránce s 1. V tabulce 1 jsou zapsány počty přístupů

15 Algoritmus 3: LFU - UvolniStranku 1 Funkce UvolniStranku() 2 CisloStrankyKOdsraneni = Pocitadlo.Nejnizsi; 3 return CisloStrankyKOdsraneni; Algoritmus 4: LFU - DokonciAlgoritmus 1 Funkce DokonciAlgoritmus(CisloStranky) /* zvýšíme počítadlo */ 2 Pocitadlo[CisloStranky]++; v čase t 6. V čase t 6 je požádáno o načtení stránky s 3, a protože je vyrovnávací pamět plná, tak dojde v odstranění jedné ze stránek z vyrovnávací paměti. Bude se jednat o stránku s 1, protože má pouze 2 přístupy na rozdíl od stránky s 2, která má 3 přístupy. Problém s takovýmto přístupem je ve stránkách, ke kterým bylo přistoupeno mnohokrát za krátký časový úsek, ale dále už k nim přistupováno nebude. Například se data, uložená na této stránce, přesunula jinam a tím se stránka stala méně důležitou. Další problém je v nově načtených stránkách. Ty budou mít počítadlo příliš nízké, takže může dojít k jejich nahrazení, i když se může jednat o důležité stránky. Částečně vyřešit první problém lze využitím ne-lineárního počítadla. Pokud bychom pro počítání přístupu zvolili logaritmickou funkci se zaokrouhlením na celá čísla, tak by k nahrazení již nepotřebných stránek mohlo dojít rychleji. Druhý problém lze částečně vyřešit nastavením ochranné doby nově načtených stránek. Stránky by po tuto dobu nebylo možné nahradit. 3.6 Least Recently Used (LRU) Algoritmus Least Recently Used (dále LRU) ke každé stránce ukládá informaci, kdy k ní bylo naposledy přistoupeno [4]. Podle této informace, pak volí stránku k nahrazení. Stránka s nejdřívějším posledním přístupem bude vybrána. Příklad Mějme vyrovnávací pamět o velikosti dvou stránek. Předpokládejme, že stránka s 1 je vyžádána systémem v čase t 1, stránka s 2 je vyžádána v čase t 2 a stránka s 1 je opět vyžádána v čase t 3. Poslední přístupy v čase t 4 jsou zapsány v tabulce 2. V čase t 4, kdy bude poslední zaznamenaný přístup ke stránce s 1 v čase t 3 a stránky s 2 v čase t 2, je vy- Stránka s 1 s 2 Počet přístupů 2 3 Tabulka 1: Počet přístupů v čase t 6

16 Algoritmus 5: LRU - UvolniStranku Stránka s 1 s 2 Poslední přístup t 3 t 2 Tabulka 2: Poslední přístupy v čase t 4 1 Funkce UvolniStranku() 2 CisloStrankyKOdsraneni = VyrovnavaciPamet.Prvni; 3 foreach stranka in VyrovnavaciPamet do 4 if PosledniPristupy[CisloStrankyKOdsraneni] > PosledniPristupy[stranka.Cislo] then /* pokud je poslední přístup ke stránce dřívější, tak ji vybereme */ 5 CisloStrankyKOdsraneni = stranka.cislo; 6 return CisloStrankyKOdsraneni; slán požadavek na odstranění stránky z paměti, aby mohla být načtena nová stránka z disku. Podle algoritmu LRU dojde k odstranění stránky s 2. V algoritmu 5 je vidět postup při načítání stránky. Pozornost je nutno věnovat hlavně řádkům 3 až 5. Algoritmus zde iteračně prochází všechny stránky ve vyrovnávací a hledá stránku s minimální hodnotou posledního přístupu. Ukázka slouží pouze k objasnění algoritmu a ne jako způsob implementace. Aby tento algoritmus našel stránky s minimální hodnotou posledního přístupu, musí projít všechny stránky ve vyrovnávací paměti, kterých bude N, kde N je velikost vyrovnávací paměti. Složitost tohoto algoritmu bude tedy O(n). Což je u operace, která se bude nejspíše provádět velmi často, příliš vysoká složitost. V algoritmu 7 je na řádku 2 provedeno nastavení posledního přístupu ke stránce. Tento postup, na rozdíl od algoritmu LFU, zohledňuje časovou složku přístupu ke stránce. Nezáleží na tom, kolikrát bylo ke stránce přistoupeno v předchozí fázi (před ztrátou důležitosti stránky), protože malým množstvím přístupů k jiným stránkám, dochází k zhoršení její pozice ve vyrovnávací paměti. Algoritmus 6: LRU - DokonciAlgoritmus 1 Funkce DokonciAlgoritmus(CisloStranky) /* nastavíme poslední přístup */ 2 PosledniPristupy[CisloStranky] = Ted();

17 3.7 Least Recently Used K (LRU-K) Jedním z hlavních problémů při použití algoritmu LRU v databázových systémech je uchování informací pouze o posledním přístupu ke stránce. Představme si databázi, která obsahuje velkou tabulku tab 1 uloženou na 1000 databázových stránkách. V čase t 1 je vyrovnávací pamět zaplněna převážně často používanými stránkami. Nyní si představme, že v čase t 2 databázový systém provede sekvenční průchod na tabulce tab 1, přičemž hledaný záznam je až na poslední stránce. Z vyrovnávací paměti bude uvolněno 1000 stránek a místo nich bude načteno 1000 stránek tabulky tab 1, přičemž k 999 z nich už nebude z velkou pravděpodobností přistupováno, protože byly načteny pouze pro sekvenční průchod. Tyto stránky setrvají v paměti do doby, než budou všechny ostatní stránky aktualizovány. Tento nedostatek řeší upravená verze algoritmu LRU algoritmus LRU-K. Modifikace spočívá v ukládání K posledních přístupů ke stránce a porovnávaní časů posledních přístupů od K [4]. LRU lze tedy chápat jako speciální verzi LRU-K - LRU-1. 3.7.1 Popis algoritmu Algoritmus pracuje na podobném principu jako algoritmus LRU. V algoritmu 7 je naznačen obecný princip algoritmu LRU-K. Na řádcích 3 až 11 prochází iteračně všechny stránky ve vyrovnávací paměti a hledá minimum. Minimum určuje na základě K-tého posledního přístupu a pokud jsou si rovny, tak pokračuje s K-1 přístupem, atd. Na řádcích 2-3 v algoritmu 8 dochází k posunu existujících přístupů dozadu a k přidání posledního přístupu dochází na řádku 4. Příklad Předpokládejme K = 2 a vyrovnávací pamět s kapacitou dva. V čase t 1 je proveden první přístup ke stránce s 1, v čase t 2 je proveden další přístup k s 1 a v čase t 3 je proveden první přístup k s 2. V tabulce 3 jsou zapsány informace o přístupech ke stránkám uložené algoritmem v čase t 4. Protože stránka s 2 byla vyžádána pouze jednou, je její K-1 přístup roven 0. LRU-2 nejprve porovná Ktý poslední přístup ke stránkám a z porovnání vyplyne, že t 1 > 0 a jako kandidát pro odstranění je vybraná s stránka s 2. Pokud by si byly hodnoty v K rovny, například z důvodu vícevláknového přístupu k vyrovnávací paměti, tak by došlo k porovnání hodnot v K-1. Pro srovnání, LRU porovnává pouze poslední (v tomto případě K-1 poslední) přístupy a t 3 > t 2, takže jako kandidát pro nahrazení by byla vybrána stránka s 1. Kód v ukázce bude značeně neefektivní, protože před každým uvolněním stránky z paměti musí iteračně projít všechny stránky, jejíchž počet bude v tuto chvíli roven kapacitě vyrovnávací paměti. Pokud by byl ukázaný kód použit v reálné implementaci, tak by docházelo ke ztrátě výkonu, protože postup by měl složitost O(n). V reálné implementaci budou muset být použity techniky, které umožní rychlejší přístup k nejhorším stránkám. Nejspíše nějaké stromové struktury. Je důležité, aby se informace o přístupech ke stránce uchovávala i v případě, že bude stránka odstraněna z vyrovnávací paměti. Může vzniknout situace, kdy bude důležitá

18 s 1 s 2 Ktý poslední přístup t 1 0 K-1ní poslední přístup t 2 t 3 Tabulka 3: Přístupy v čase t 4 stránka načtena v paměti po nějakou dobu a pak z ní bude odstraněna například z důvodu sekvenčního čtení. Hned poté bude znovu načtena, ale K-tý poslední přístup bude nastaven na 0, protože informace nebyla uchována a pohlíží se na ní jako na úplně novou stránku. Příklad Přestavme si, že máme vyrovnávací pamět o velikosti dvou stránek a algoritmus LRU-2. V čase t 1 dojde k prvnímu načtení stránky s 1, v čase t 2 dojde k prvnímu načtení stránky s 2, v čase t 3 dojde k opětovnému přístupu ke stránce s 1. A v čase t 4 je načtena stránka s 3. Jelikož je vyrovnávací pamět plná, bude k nahrazení správně vybrána stránka s 2. V čase t 5 dojde k dalšímu přístupu ke stránce s 2 a z vyrovnávací paměti je odstraněna stránka s 3. Pokud v čase t 6 bude načtena stránka s 4 a informace o přístupech nejsou k dispozici po odstranění stránky z vyrovnávací paměti, bude nesprávně nahrazena stránka s 2, přestože její Ktý poslední přístup je větší než Ktý poslední přístup s 1 (t 2 >t 1 ). 3.7.2 Korelační a ochranná doba Jednou z častých operací v databázových systémech je UPDATE. Tato operace se skládá ze dvou fází. V první se data (a tedy celá stránka) načtou do paměti k editaci. Poté dojde k úpravě dat a novému přístupu ke stránce, aby se data mohla uložit. To způsobuje, že se provedou dva přístupy ke stránce, i když se jedná o jednu operaci. Stránka tak získá lepší pozici ve vyrovnávací paměti. Zdvojení přístupu má negativní vliv na průběh algoritmu, operace UPDATE bude mít dvojnásobnou váhu oproti operaci SELECT a způsobí nahrazení potřebnějších stránek namísto stránek, kde se prováděl UPDATE. Další problém spočívá v odstranění stránek, na kterých probíhá UPDATE. Představme si, že stránka s 1 obsahuje data, která se budou upravovat. V čase t 1 je stránka s 1 poprvé načtena do paměti. Ale v čase t 2 je vybrána jako kandidát na odstranění, protože hodnota její K-tého posledního přístupu je 0. V čase t 3 jsou změny dat na stránce hotovy a musejí se zaznamenat, stránka s 1 musí být znovu načtena do paměti. Oba problémy lze vyřešit stanovením doby od posledního přístupu, po kterou se nebudou provádět aktualizace posledních přístupů ke stránce. Druhá fáze operace UP- DATE, tak neprovede aktualizaci posledních přístupů, i když stránku načte. Zároveň po tuto dobu nesmí být stránka odstraněna z vyrovnávací paměti, čím se zajistí, že nedojde k odstranění stránky, která se bude upravovat.

19 Algoritmus 7: LRU-K - UvolniStranku 1 Funkce UvolniStranku() 2 CisloStrankyKOdsraneni = VyrovnavaciPamet.Prvni; 3 foreach stranka in VyrovnavaciPamet do 4 for i in K.. 0 do 5 if PolsedniPristupy[CisloStrankyKOdsraneni][i] > PolsedniPristupy[stranka.Cislo][i] then /* pokud je i-tý poslední přístup ke stránce dřívější, tak ji vybereme */ 6 CisloStrankyKOdsraneni = stranka.cislo; 7 break; 8 if PolsedniPristupy[CisloStrankyKOdsraneni][i] == PolsedniPristupy[stranka.Cislo][i] then /* pokud jsou i-té poslední přístupy rovny, tak pokračujeme i-1 přístupem */ 9 continue; 10 else /* pokud je i-tý poslední přístup ke stránce pozdější, tak ji nevybereme */ 11 break; 12 return CisloStrankyKOdsraneni; Pokud po uplynutí této doby dojde k přístupu ke stránce, tak se aktualizují poslední přístupy a stránka zůstane v paměti. Pokud k přístupu nedojde bude brzy stránka vybrána k odstranění a nahrazena. 3.8 Ukládání stránek Všechny dosud popsané algoritmy se týkaly pouze načítání stránek z disku. Databázové systémy ovšem potřebují ukládat data na disk jako zálohu pro případ výpadku a jako úložiště při nedostatku místa ve vyrovnávací paměti. Ideálním případem by bylo ukládat všechna data na disk ihned, jak jsou zapsány. Tedy v okamžiku, kdy je přistoupeno ke stránce a je provedena její úprava, se stránka uloží na disk. Problém s tímto přístupem je ve výkonu. Operace zápisu je stejně jako operace čtení mnohem pomalejší u disku než u operační paměti. Ukládat stránku po každém přístupu by způsobovalo výkonnostní problémy. Stačí si představit operaci, která provede několik stovek aktualizací na jedné stránce během několika vteřin. Znamenalo by to stovky zápisů na disk. Jinou možností je stránky na disk neukládat ihned, ale jen v případě, že přišel požadavek na odstranění stránky z vyrovnávací paměti a stránka byla od posledního načtení z disku změněna. Tento postup urychlí práci s diskem, protože každá načtená stránka

20 Algoritmus 8: LRU-K - DokonciAlgoritmus 1 Funkce DokonciAlgoritmus(CisloStranky) /* posuneme všechny polední přístupy a do posledního přístupu vložíme aktuální čas */ 2 for i in K.. 0 do 3 PosledniPristupy[CisloStranky][i] = PosledniPristupy[CisloStranky][i-1]; 4 PosledniPristupy[CisloStranky][0] = Ted(); bude uložena maximálně jednou a poté už nebude měněna. Měnit se bude jedině až po dalším načtení k disku. Problém s tímto postupem je ve výpadku systému. Ne všechny stránky musí být uloženy v době výpadku a může dojít ke ztrátě dat. Ovšem většina databázových systémů obsahuje techniky pro zotavení a není tedy nutné, aby toto zvládala vyrovnávací pamět.

21 4 Více-vláknové aplikace V dnešní dob je již většina procesorů i operačních systému připravena pro paralelní zpracování požadavků. Jednou z možností, jak lze více jádrový procesor využít, je přidělení procesorového času více aplikacím na jednou. Takže dvě aplikace se budou zpracovávat najednou. Postup sice umožní rychlejší zpracování různých požadavků, ale nijak nezvýší výkon jedné aplikace. Pokud by bylo možné paralelizovat zpracování požadavků v rámci jedné aplikace, mohlo by dojít k výraznému zvýšení propustnosti dané aplikace a tedy rychlejšímu zpracování všech požadavků. U databázových systému je paralelizace jednou z možných optimalizací pro zvýšení výkonu. Jednotlivé dotazy na databázový systém mohou být zpracovávány současně a výsledek předán uživateli dříve. Paralelizovat aplikace lze pomocí tzv. vláken. Vlákno je posloupnost instrukcí, které budou procesorem zpracovány postupně. Použitím více vláken, lze mít více takovýchto posloupností, které mohou obsahovat i stejné instrukce, ale pracovat s jinými daty. Jednotlivá vlákna mohou být zpracovávána procesorem současně. 4.1 Problémy s více vlákny Může se zdát, že použití více vláken je jednoduché a bezproblémové, pouze rozdělíme požadavky do různých vláken. Tak to ovšem není, při zpracování může dojít k řadě problému, způsobené konfliktem mezi vlákny. Jeden z největších problémů je způsoben prací se sdílenou pamětí a nemožností určit, které vlákno se dostane k dané instrukci dříve. V určitém bodě se můžou v paměti objevit neplatná data. Příklad Mějme dvě vlákna. V paměti je na adrese 0 hodnota 5. Vlákno 1 dostane za úkol vynásobit hodnotu na pozici 0 čtyřmi a vlákno 2 má vynásobit hodnotu dvěma. Vlákno 1 čte hodnotu na pozici 0 v paměti a ukládá si ji do vlastní paměti pro další zpracování. Nyní čte vlákno 2 hodnotu na pozici 0 a ukládá si jí do vlastí paměti. Vlákno dvě potom vynásobí hodnotu dvěma, takže má k dispozici hodnotu 10. Tuto hodnotu ukládá zpět na pozici 0. Vlákno 1 bylo o něco pomalejší než vlákno 2, takže hodnotu násobí 4 až nyní. Výsledek je tedy 20. Tuto hodnotu ukládá na pozici 0, kde je nyní hodnota 10. O tom ale vlákno 1 neví, takže ukládá hodnotu 20 na pozici 0. Nyní, když obě vlákny skončily je na pozici hodnota 20 přestože by tam měla být hodnota 40, která vznikla vynásobením původní hodnoty 5 dvěma a čtyřmi. Hodnota na pozici 0 není platná. Prvním způsobem, jak vytvářet paralelní aplikace je vyhnout se zápisu do sdílené paměti úplně. Vytvořit aplikaci tak, aby nebylo třeba zapisovat do paměti, ke které má přístup více vláken. Ovšem pokaždé není možné se vyhnout sdílené paměti, do které se zapisují data. V takovém případě je nutno zabránit kolizi při zápisu do paměti. Existují dva hlavní přístupy k zabránění kolize [5]:

22 Vzájemné vyloučení (anglicky mutual exclusion, taky mutex) Atomické operace 4.1.1 Vzájemné vyloučení Vzájemné vyloučení zabraňuje přístupu jiného vlákna do části programu, která pracuje se sdílenou pamětí, pokud tam již pracuje jiné vlákno. Provádí serializaci instrukcí, které pracují se sdílenou pamětí Nejčastěji je proveden pomocí zamykání. Existuje zámek, což je nějaký indikátor, který určuje, zda nějaké vlákno pracuje s částí kódu, která musí být serializována. Když se vlákno dostane k zámku, tak zkontroluje, zda není uzamčen. Pokud není uzamčen, tak jej uzamkne a pokračuje dále. Pokud je uzamčen, tak vlákno čeká na odemčení a až potom může pokračovat. Jakmile vlákno opouští část kódu, která musí být serilalizována, tak odemyká zámek. Příklad Mějme dvě vlákna a zámek z 1, který chrání část kódu. Vlákno 1 přistupuje ke chráněné části kódu, a protože zámek z 1 není uzamčen, tak jej zamyká a pokračuje do chráněné části. Vlákno 2 přistupuje k chráněné části, a protože je zámek z 1 uzamčen, tak čeká. Vlákno 1 vykonává chráněný kód. Vlákno dvě stále čeká na odemčení zámku z 1. Vlákno 1 opouští chráněný kód a odemyká zámek z 1. Vlákno dvě zamyká zámek z 1 a pokračuje do chráněného kódu. Důležité je, aby část kódu, která je chráněna zámkem, byla co nejmenší, protože není paralelizována. Kdyby byla velká část kódu chráněna zámky, tak by stálo za zvážení, zda je paralelizace dané úlohy vůbec vhodná. Zároveň je důležité, aby bylo zámků co nejméně, protože logika spojená se zamykáním a odemykáním má také určitou cenu. V případě velkého počtu zámků se může paradoxně stát, že použití více vláken aplikaci zpomalí. Ve většině programovacích jazyků existují třídy, které umožňují zamykání kódu. Technicky jsou provedeny pomocí atomických operací. 4.1.2 Atomické operace Atomická operace je operace, která již není dále dělitelná. Nemůže se proto stát, že dojde ke změně dat během průběhu této operace. Tohle je zajištěno procesorem a operačním systémem. Při použití více vláken se všechny přístupy ke sdíleným proměnným, které jsou ve sdílené paměti, budou řešit pouze pomocí atomických operací. Příklad Mějme dvě vlákna a proměnou p 1 s hodnotou 3. Vlákno 1 zvyšuje hodnotu proměnné p 1 o 1. Zároveň vlákno 2 zvyšuje hodnotu proměnné p 1 o 1. Přestože obě operace proběhly současně, tak proměnná p 1 má hodnotu 5.

Používaní atomických operací bude mít mnohem menší vliv na ztrátu výkonu, než používání vzájemného vyloučení, protože jednotlivá vlákna na sebe nemusejí vůbec čekat. A logika spojená s používáním atomických operací namísto operací klasických má velmi nízký vliv na výkon. Používání atomických operací by tedy mělo být první volbou při paralelizaci aplikace. Problémem je, že ne každou situaci je možné řešit atomickými operacemi. Počet operací je omezen tím, co poskytuje operační systém. Většinou se jedná o klasické aritmetické operace, logické operace a nějaké speciální operace. 23

24 5 Vlastní implementace Pro implementaci vyrovnávací paměti byl zvolen programovací jazyk C++. Pro vývoj bylo použito vývojové prostředí Visual studio 2013. Jako algoritmus pro nahrazování stránek byl zvolen algoritmus LRU-K. Konkrétně jeho varianta LRU-2. Nicméně K je volitelné jako parametr kompilátoru. 5.1 Návrh systému Pozice vyrovnávací paměti v rámci databázového systému RadegastDB je patrná z obrázku 2. S vyrovnávací pamětí komunikují nejvíce datové struktury. Na obrázku 3 je vidět diagram znázorňující nejdůležitější komponenty vyrovnávací paměti. Jako rozhraní pro komunikací s datovými strukturami slouží třída cnodecache a její veřejné metody. Metody Open a Create slouží k otevření stávajícího souboru databáze, či vytvoření nového databázového souboru a zahájení funkce vyrovnávací paměti. Metoda Close slouží k uzavření vyrovnávací paměti. Při jejím vyvolání se všechny modifikované databázové stránky uloží na disk a uvolní se alokovaná pamět systému. Asi nejpoužívanější metody jsou ReadR, která vrátí požadovanou stránku pro čtení, ReadW, která vrátí databázovou stránku pro zápis, a ReadNew, která založí novou prázdnou databázovou stránku a vrátí ji pro zápis. Pro odemčení zamknuté stránky slouží metody UnlockW a UnlockR. Třídy cheap a chashmap jsou pomocné datové struktury použité v rámci implementace. Základní pojmy: databázová stránka - jedná se o jednu stránku paměti, na kterou se ukládají data jednotlivých datových struktur. Celý obsah stránky se ukládá na disk. blok paměti - část hlavní paměti, kam se ukládá databázová stránka, která je načtena do vyrovnávací paměti, a pomocné informace k dané stránce využívané datovými strukturami kandidát - blok paměti, který je nejvhodnější k vyčištění (uložení a odstranění stránky z paměti) podle algoritmu LRU-K 5.2 Části cnodecache Ke každé databázové stránce, která je nebo byla načtena do vyrovnávací paměti, existuje instance cnodeinfo, která je identifikována identifikátorem dané stránky. Identifikátorem stránky je jedinečné kladné celé číslo. Obsahuje veškeré informace potřebné pro algoritmus LRU-K a další informace potřebné pro provoz. Třída cnodeinfo obsahuje i odkaz do pole paměti, kde jsou uložena samotná data databázové stránky. Třída cnodeinfostorage pak slouží jako úložiště instancí cnodeinfo a existuje v jedné instanci pro každou instanci cnodecache.

25 Obrázek 2: Pozice vyrovnávací paměti v rámci RadegastDB Obrázek 3: Struktura systému

26 Aby byly tyto instance jednoduše dohledané, tak se ukládají do hashovací tabulky (třída chashtable). Klíčem této tabulky je identifikátor databázové stránky, ke které instance cnodeinfo přísluší. Tato struktura slouží k rychlému přístupu k cnodeinfo pomocí identifikátoru stránky. Algoritmus LRU-K potřebuje vyhledávat stránky na základě jejich posledních přístupů a postup popsaný v kapitole 3.7 je značně neefektivní, protože využívá sekvenční vyhledávání. Proto jsou ukazatele na instance cnodeinfo zároveň ukládány do struktury typu halda (cheap). V kořeni této struktury se nachází cnodeinfo ke stránce nejvhodnější pro nahrazení. Halda se využívá při výběru kandidáta k odstranění. Postup pro výběr kandidáta je podrobněji popsán v kapitole 5.6.3. Halda byla zvolena proto, že se jedná o strukturu s rychlým vkládáním a konstantní složitostí přístupu k uzlu. Pole bloků paměti databázových stránek, je pole bloků o velikosti databázové stránky s velikostí vyrovnávací paměti. Fronta volných bloků obsahuje indexy na bloky pole, které nejsou obsazeny žádnou stránkou. 5.3 Zamykání stránek Implementace zahrnuje jednoduché zamykání stránek. Umožňuje dvojí typ zámků: sdílený a exkluzivní. Sdílený zámek slouží ke čtení a exkluzivní pro zápis. Jedná se o běžný způsob zamykání stránek, který není třeba podrobně vysvětlovat. Ke každé databázové stránce se vytvoří čítač sdílených zámků a indikátor exkluzivního zámku. Pokud přijde požadavek na ReadR, tak se inkrementuje sdílený čítač, ale pouze v případě, že není nastaven indikátor exkluzivního zámku. Pokud přijde požadavek na ReadW, tak se nastaví indikátor exkluzivního zámku, ale pouze v případě že je čítač sdílených zámků roven nule a není nastaven indikátor exkluzivního zámku. V opačných případech se čeká na na splnění podmínky (např. jiné vlákno smaže indikátor exkluzivního zámku). Zámky jsou součástí třídy cnodeinfo. 5.4 Čistící vlákno Implementace obsahuje metodu, která po zavolání uvolní požadované procento vyrovnávací paměti. V ideálním případě by se tato metoda volala v době nízkého vytížení databáze a byla by tedy volána databázovým systémem. Nicméně pro zjednodušení je v implementaci zakomponováno čistící vlákno, které se v určitém intervalu provede zavolání metody Shrink, která provede uvolnění paměti. Oba parametry, procento, které má být uvolněno, a interval, v jakém se má provádět uvolnění, jsou parametry metod Open a Create. Funkce Shrink, která provádí čištění vyrovnávací paměti, provede nejprve výpočet počtu kadidátů, které musí z paměti uvolnit. Výpočet provede na základě procenta, které má být uvolněno, celkové velikosti vyrovnávací paměti a počtu volných bloků takto: Počet kandidátů k uvolnění = PROCENTO_K_UVOLENI * Velikost paměti - Velikost fronty volných bloků

27 Pak provede výběr vypočteného počtu kandidátů pomocí postupu pro výběr kandidáta popsaného v kapitole 5.6.3. Kandidáta ovšem nenahrazuje, ale pouze uloží na disk, pokud byl modifikován a vloží volný pamět ový index do fronty volných bloků. 5.5 Změna velikosti vyrovnávací paměti Implementace umožňuje měnit velikost vyrovnávací paměti za běhu. Tato funkcionalita je potřebná zejména v případě, že dojde k zvýšení přístupu k databázovému systému a tedy i jeho zatížení a většímu počtu přístupu k různým databázovým stránkám. A vznikne potřeba zvýšit počet databázových stránek uchovávaných v operační paměti. Po pominutí zvýšeného přístupu k databázi, může být počet stránek v paměti opět snížen, aby se uvolnila operační pamět pro jiné aplikace. K tomuto účelu slouží metoda Resize. Při jejím zavolání dojde ke změně velikosti pole bloků paměti, do kterého se ukládají stránky. Algoritmus 9 zachycuje postup při změně velikosti vyrovnávací paměti. Existují tři možnosti změny velikosti. Bud bude nová velikost větší než současná a dojde tedy ke zvětšení (řádky 4-8), nebo bude menší a dojde ke zmenšení vyrovnávací paměti (řádky 9-25). Pokud je nová požadovaná velikost stejná jako současná, tak je řešení triviální (řádky 2-3). Pokud bude požadovaná velikost vyrovnávací paměti větší než současná, tak program provede realokaci paměti, kde se ukládají data (řádek 5) a přesun stránek ve vyrovnávací paměti na nové umístění. Pak provede výpočet indexů nově přidaných bloků paměti a tyto indexy vloží do fronty volných bloků v paměti (řádky 6-7). Nesložitější možnost je změna velikosti s požadovánou velikostí nižší než je současná velikost. Problémem bude případ, kdy existují načtené stránky v části paměti, která má být odstraněna. Pokud například blok paměti, kde je stránka uložena, má index 8 000 a nová velikost vyrovnávací paměti je 4 000 bloků, tak stránka v bloku na pozici 8000 musí být přesunuta na volný blok paměti s indexem menším než 4 000. Navíc počet volných bloků v části, která se zachová nemusí být dostatečný pro přesun stránek z části, která bude smazaná. Algoritmus tedy při zmenšování vyrovnávací paměti nejdříve projde část, která bude odstraněna, a spočte počet stránek, které se budou přesouvat (řádky 10-13). Budou to ty stránky, které jsou ve vyrovnávací paměti a nejsou označeny jako odstraněné. Pak odstraní z fronty volných bloků ty bloky, které už nevlezou do nové vyrovnávací paměti (řádky 14-16). Dále uvolňuje bloky paměti a přidává uvolněné bloky do fronty dokud není počet prvků ve frontě dostatečný k přesunu všech stránek z bloků v části paměti, která bude odstraněna (řádky 17-20). Bloky uvolňuje stejným způsobem, který se používá pro nalezení kandidáta na uvolnění při zaplněné paměti, a který je popsán v kapitole 5.6.3. Pak provede přesun stránek z bloků, které se budou odstraňovat na bloky z fronty volných bloků (řádky 21-23). Nakonec provede realokaci paměti (řádek 24). Funkce Resize nemůže být prováděna paralelně s funkcí Read nebo ReadNew, protože by mohlo dojít k přístupu do neplatné paměti. Pro je funkce synchronizována s ostatními funkcemi pomocí mutexu. Zároveň nesmí být při provedení funkce Resize žádná stránka zpracovávána, což znamená, že nebude uzamčena sdíleným ani exkluzivním zámkem. Funkce tedy čeká na odemčení všech stránek. Proto je třeba zajistit, aby

28 nebyla volána z vlákna, které v okamžiku volání funkce Resize pracovala s nějakou stránkou. Mohlo by dojít k zacyklení. 5.6 Načítání stránky Hlavní operací, kterou bude vyrovnávací pamět provádět je načtení stránky, kterou datová struktura požaduje. Existují 3 možnosti, kterými může datová struktura požádat o načtení stránek: Existující stránka pro čtení - tato možnost načte požadovanou stránku a přidělí jí sdílený zámek. Umožňuje více vláknům číst stejnou databázovou stránku. V tomto případě nesmí datová struktura provádět žádné modifikace na stránce, protože by mohlo dojít ke ztrátě těchto změn. Existující stránka pro zápis - tato možnost načte požadovanou stránku a přidělí jí exkluzivní zámek. Neumožňuje přístup více vláknům k této stránce. Pokud nějaké jiné vlákno požádá o tuto stránku, tak bude muset počkat, dokud ji předchozí vlákno neuvolní. Zároveň se nastaví identifikátor špinavé stránky, takže stránka bude uložena na disk. K zápisu na disk dojde i v případě, že datová struktura neprovede žádnou změnu na stránce, takže pokud to nemá v plánu, měl by požádat o stránku ke čtení. Nová stránka - tato možnost vytvoří novou databázovou stránku, přidělí jí exkluzivní zámek a označí jako špinavou. Jedná se tedy o možnost načtení stránky pro zápis. Načítat novou stránku pro čtení nemá smysl, jelikož neobsahuje data, která by mohl databázový systém číst. 5.6.1 Postup při načítání existující stránky Pro načítání se používají metody ReadR k načtení stránky pro čtení a ReadW k načtení stránky pro zápis, které pak vnitřně využívají metody Read, jelikož většina logiky načítání bude stejná. Postup metody Read na naznačen v algoritmu 10. Při načítání stránky v metodě Read se nejprve ověří, zda stránka již není obsažena v paměti. Pokud cnodeinfo pro danou stránku není obsaženo v hashovací tabulce úložiště stránek, nebo má cnodeinfo nastaven indikátor smazání, tak se daná stránka v paměti nenalézá. Pokud je nalezena (řádek 3), tak se získá příslušné cnodeinfo. Pokud nalezena není, tak se získá volný blok paměti (řádek 5). Načte se daná stránka z disku (řádek 6) a příslušné cnodeinfo se vloží do hashovací tabulky, pokud je třeba (řádky 7-11). A cnodeinfo se vloží do haldy(řádek 12). K získání volného bloku paměti je použita funkce ZiskejVolnyBlokPameti popsána v kapitole 5.6.3. Nakonec dojde k nastavení zámku (podle požadovaného typy čtení, řádky 13-20), nastavení posledních přístupů v cnodeinfo (řádky 21-25) a přepočtu haldy (řádek 26).