Hotfix release available: 2025-05-14b "Librarian".
upgrade now! [56.2] (what's this?)
Hotfix release available: 2025-05-14a "Librarian".
upgrade now! [56.1] (what's this?)
New release available: 2025-05-14 "Librarian".
upgrade now! [56] (what's this?)
Hotfix release available: 2024-02-06b "Kaos".
upgrade now! [55.2] (what's this?)
Hotfix release available: 2024-02-06a "Kaos".
upgrade now! [55.1] (what's this?)
New release available: 2024-02-06 "Kaos".
upgrade now! [55] (what's this?)
Hotfix release available: 2023-04-04b "Jack Jackrum".
upgrade now! [54.2] (what's this?)
users:martin.kocicka:pdp:6b
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
users:martin.kocicka:pdp:6b [2017/06/13 09:48] – vytvořeno martin.kocicka | users:martin.kocicka:pdp:6b [2017/06/13 10:16] (current) – martin.kocicka | ||
---|---|---|---|
Line 20: | Line 20: | ||
:!://Viz skripta CZ [2006] str. 87 nebo EN [2009] str. 70// | :!://Viz skripta CZ [2006] str. 87 nebo EN [2009] str. 70// | ||
- | {{: | + | {{: |
< | < | ||
Line 54: | Line 54: | ||
To poslední mapování hrany, ten modrý oblouček co začíná nejvíc vpravo nepřechází přes tu hranu, kterou pozorujeme ( svislá růžová čára ), takže ta se do ecng nepočítá, | To poslední mapování hrany, ten modrý oblouček co začíná nejvíc vpravo nepřechází přes tu hranu, kterou pozorujeme ( svislá růžová čára ), takže ta se do ecng nepočítá, | ||
- | ===== Algebraické vnoření CBTn do Qn+1 ===== | ||
- | |||
- | - Dokažte, že **úplný binární strom** o výšce //n//, < | ||
- | - Pak popište algoritmus pro vnoření < | ||
- | |||
- | ★ //Bylo ve zkoušce: [[.: | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | {{: | ||
- | |||
- | === První část === | ||
- | viz [[par_řešené_příklady_2b# | ||
- | |||
- | === Druhá část === | ||
- | |||
- | :!://viz. 7. proseminář 2008, je to tam fakt dobře vysvětlené// | ||
- | |||
- | :!:// viz česká skripta 2006 strana 80 // | ||
- | |||
- | Zakladní myšlenka algoritmu je zdvojení kořenu CBT< | ||
- | |||
- | {{: | ||
- | |||
- | Indukční základ (a) ukazuje vnoření < | ||
- | < | ||
- | | ||
- | | ||
- | | ||
- | </ | ||
- | Konkrétně, | ||
- | |||
- | {{: | ||
- | |||
- | | přesun | ||
- | ^ < | ||
- | ^ < | ||
- | ^ < | ||
- | |||
- | Ve výsledné transformaci lze použít pouze permutaci pořadí a negaci (automorfismus), | ||
- | |||
- | :?: //Co mi není jasné je, zda to stačí takto, či zda je potřeba provést explicitně pomocí algoritmu i přechod z Q2 do Q3. V PDFku to není, a na scanech je ten mezikrok sice zmíněn, ale proveden metodou kouknu a vidím.// | ||
- | |||
- | Ten krok z Q2 do Q3 se dělá úplně stejně jako zmíněný Q3 do Q4. Akurát že uzly se indexují dvěma bity. Mapování se provádí obdobně 00->10, 10->11 .. atp. Opět jde vždy o to, nalézt 4 významné uzly (v pripadě Q2 jde o všechny jeho uzly) u obou kopií - dvou Q2jek. Tyto významné uzly jsou následně propojeny nalezenou mapovací funkcí a dále jsou také umazány dve hrany z původních Q2jek (jedu stale dle obrazku). | ||
- | |||
- | pre 4D ->5D. V 4D krychli nájdeme 4 významné uzly, zistíme ich adresy (budú to 4bity). Nová tabuľka bude popisovať presuny z 1->2, 2->3, 3->4. | ||
====== Algoritmy ====== | ====== Algoritmy ====== | ||
- | |||
- | ===== Offline permutační směrování na nepřímé Benešově síti ===== | ||
- | |||
- | Máme nepřímou Benešovu síť. Popište, jak se offline vytvářejí cesty pro permutace, a znázorněte, | ||
- | |||
- | ★ //Bylo ve zkoušce: [[.: | ||
- | ==== Řešení ==== | ||
- | |||
- | :!://Viz skripta CZ [2006] str. 163 nebo EN [2009] str. 142// | ||
- | |||
- | Cesta se tvoří rekurzivně. Benešova síť < | ||
- | |||
- | Edit (5/16) k definici nepřímé BN. Přijde mi, že je to zde popsané trochu jinak než v EN skriptech, zde je překlad: | ||
- | |||
- | Nechť < | ||
- | |||
- | - Vyberu libovolné < | ||
- | - Najdu cestu (permutaci) < | ||
- | - Najdu cestu < | ||
- | - Pokud < | ||
- | - Permutace v < | ||
- | |||
- | Postup jednoduše: | ||
- | - Zvolím si jeden bod, kterým začnu. Ideálně třeba 0. | ||
- | - Zvolím si směr, kterým půjdu (horní < | ||
- | - Pokud např. 0 půjde do spodní < | ||
- | - Podívat se do tabulky a např. pro 0->6 udělat na druhé straně to, že 6 musí jít také do spodní < | ||
- | - Tím pádem půjde 7 (je v páru s 6) do horní < | ||
- | - Postupně takto doplním všechny dvojice (potom zkontrolovat, | ||
- | - A ten samý postup opakovat 2x pro menší vzniké < | ||
- | |||
- | |||
- | {{: | ||
- | |||
- | {{: | ||
- | |||
- | {{: | ||
- | |||
- | Pozn by topas: Na slajdech 9/30 je sice první krok výpočtu symetrický, | ||
- | |||
- | Pozn by darkdiablo: imho je na tom přikladu blbě nakreslená benešova síť, viz přednáška 9 slide 29. | ||
- | |||
- | Pozn. by honzab: dle mého je ta síť taky špatně, vyšlo mi to takhle:\\ | ||
- | Pozn. by Hoogoo: honzab sit se zda, ze ma dobre algoritmus, ale sit je u 5 na prave strane spatne zakreslena. | ||
- | |||
- | {{: | ||
- | |||
- | Pozn. by Karry: mě takhle: | ||
- | |||
- | {{: | ||
- | |||
- | Pozn. by Fry: Všechny obrázky kromě honzab jsou špatně. Nepřímá i přímá síť má dané spoje mezi přepínači viz slajdy 9/29. Jediné co se u nepřímé podle návodu mění je jak se uvnitř přepne (jak říkal Tvrdík, dostanete vytvořené spoje z továrny a vy si volíte přepnutí, aby to odpovídalo požadovaným cestám). A variant jak to uvnitř přepnout je vícero, aby to v důsledku vyšlo podle zadání, stačí se držet návodu (přepnutí nemusí být symetrické jen musíte dodržet popsaná pravidla). U přímé je jediný rozdíl, že jakoby nemáte přepínače (máte přímo připojené vstupy, takže boxů je 2x víc než u nepřímé, protože jedno jsou přepínače a jedno jen vstupy), tak jen vyberete jednu možnou cestu z těch dvou daných (např. si ji vytáhněte propiskou, ale struktura je daná od začátku).\\ | ||
- | |||
- | Pozn. IMHO jsou všechny obrázky správně, jde to nakreslit dvěma způsoby. Viz obrázek ze skript a z přednášek: | ||
- | |||
- | {{: | ||
- | {{: | ||
- | |||
- | Tento obrázok som kreslil s kamošom, čo BN dal na skúške, tak snáď je dobre: | ||
- | |||
- | {{: | ||
- | |||
- | Pozn. 14-01-2016 Vyslo mi to stejne jako posledni barevny obrazek. | ||
- | |||
- | < | ||
- | |||
- | :?: V čem jsou špatně? Všechny obrázky tady se liší maximálně v tom, jestli vodorovné a šikmé hrany vedou vždy ze stejné pozice přepínače (šikmá ze spodní jako ve skriptech) a nebo jestli šikmá vede vždy z té bližší pozice (jako v přednáškách). Vzhledem k tomu, že existují obě varianty BN a my v tomhle algoritmu neřešíme, | ||
- | |||
- | |||
- | mm mas pravdu, prislo mi to, ze je dulezite kde jsou umistene jednotlive hrany. | ||
- | |||
- | ===== Offline permutační směrování na přímé Benešově síti ===== | ||
- | |||
- | Máme přímou Benešovu síť. Popište, jak se offline vytvářejí cesty pro permutace, a znázorněte, | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | :!://Viz skripta CZ [2006] str. 163 nebo EN [2009] str. 142// | ||
- | |||
- | Analogické k nepřímé síti až na to, že spřažené uzly (liší se v nejvyšším bitu) jsou tvořeny tak, aby se nepotkaly v jednom následujícím uzlu. Pro názornost s předchozím příkladem je zvolená stejná požadovaná permutace. | ||
- | |||
- | Postup: | ||
- | - zvolíme si libovolný uzel a libovolnou cestu. Např na obrázku zvolena 0 (zelená barva). K ní je spřažená 4, ta tedy musí jít nahoru. | ||
- | - mrkneme se na síť z druhé strany - požadované cílové uzly musí jít do stejné části podsítě jako uzly z prvního kroku | ||
- | - v druhém kroku jsme spojili zas některé uzly, tedy spřažené cesty jsou jasně dány, propojíme, mrkneme ke kterým uzlům patří a kam chtějí atd.\\ | ||
- | |||
- | {{: | ||
- | |||
- | Pozn. by Fry: propiskou je vyznačeno rozhodnutí, | ||
- | |||
- | Pozn. sprazene uzly jsou v i-tem kroku ty, ktere maji rozdilny i-ty bit zleva | ||
- | |||
- | Pozn. Já to v tom obrázku asi nějak nevidím, ale kde přesně má být ta zelená barva a ty čáry propiskou, o kterých se tu mluví? | ||
- | |||
- | Pozn. k Pozn. Spřažené hrany jsou např. (0, 000) a (0, 100) a když jdu v (0, 000) dolů, tak musím v (0, 100) nahoru. | ||
- | |||
- | ===== Algoritmus pro pořadí na zřetězeném seznamu ===== | ||
- | |||
- | Uveďte časově optimální algoritmus pro určení pořadí (rank) ve zřetězeném seznamu n prvků na CREW (EREW) PRAM s p procesory. Zhodnoťte škálovatelnost. | ||
- | |||
- | ★ //Bylo ve zkoušce: [[.: | ||
- | ==== Řešení ==== | ||
- | |||
- | :!://Viz skripta CZ [2006] str. 105-106; EN [2006] str. 103; předn. 7, sl. 28 [FIT 2014/15]// | ||
- | |||
- | === Algoritmus === | ||
- | |||
- | Optimální algoritmus pro tuto úlohu se jmenuje **přeskakování ukazatelů** (pointer jumping). Pro počet procesorů rovný velikosti pole (p = n) má následující podobu: | ||
- | |||
- | < | ||
- | Vstup: pole Succ[1, | ||
- | Výstup: modifikované pole Succ[1, | ||
- | |||
- | for i=1..n do_in_parallel { | ||
- | if (Succ[i] == i) then Rank[i] = 0 else Rank[i] = 1 | ||
- | repeat ⌈log n⌉ times { | ||
- | Rank[i] += Rank[Succ[i]] | ||
- | Succ[i] = Succ[Succ[i]] | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | To samé zapsané v jiné syntaxi: | ||
- | <code java> | ||
- | // arrays are 1-based | ||
- | // succs: ID prvku => ID jeho následníka | ||
- | // ranks: ID prvku => pořadové číslo v seznamu od konce */ | ||
- | listRanking(int[] succs) { | ||
- | int[] ranks = new int[ succs.length ]; | ||
- | | ||
- | for (int i = 1; i < | ||
- | // pokud následník prvku je on sám (poslední prvek) -> rank = 0 | ||
- | if (succs[i] == i) ranks[i] = 0; else ranks[i] = 1; // <RLW> = 3 | ||
- | |||
- | repeat (⌈log(n)⌉) { // < | ||
- | ranks[i] += ranks[ succs[i] ]; | ||
- | succs[i] = succs[ succs[i] ]; // pointer jump | ||
- | } | ||
- | } | ||
- | return ranks; | ||
- | } | ||
- | </ | ||
- | |||
- | === Složitost === | ||
- | |||
- | Pro **p = n**: | ||
- | * < | ||
- | * < | ||
- | Pro **p < n** (každý procesor simuluje činnost n/p procesorů): | ||
- | * < | ||
- | * -pozn. je tam log(p)? ten cyklus dělá každý procesor sám a je dlouhý log(n) | ||
- | * < | ||
- | |||
- | Na EREW PRAM by byl výpočet zpomalen v každém kroku o < | ||
- | |||
- | Algoritmus je sice časově optimální, | ||
- | |||
- | < | ||
- | |||
- | Škálovatelnost je kvůli nelokalitě dat špatná a rozdělení na více/ | ||
- | |||
- | - není ani časově optimální ne? | ||
- | Podle skript "Any algorithm with T(n,p) matching lower bound SL(n)/p is optimal" | ||
- | Toho ale algoritmus nedosahuje, < | ||
- | Nebo se pletu? | ||
- | |||
- | - Pozn.: souhlasím, také si myslím, že není ani časově optimální | ||
- | |||
- | CZ skripta str. 106: | ||
- | Pole Succ (následovníci) v najhoršom prípade nemusí vykazovať žádnou lokalitu (nedá se rozdelit rovnomerne medzi CPU). Muže se stát, že počas lokálneho výpočtu n/p prvkov budú všetci ich succ v paměti iného CPU a teda lokálny výpočet bude theta (n/p) ukazatelů. Ich paralelné provádení bude trvat znovu n/p*log(p) kroků a z toho nejako plyne, že CENA bude < | ||
- | |||
- | Predstavte si to tak, ze puvodni pole rozsekate na mensi o velikosti p (=> bude n/p dilku), kazdy procesor tedy musi zpracovat n/p cisel => bude to trvat nejmene cas n/p * paralelni cast. Ale to je jen pripad, ze by byly vsichni nasledovnici hezky za sebou.. Pokud budou nasledovnici v ruznych blocich, bude to strasne rozhazene, takze tech iteraci bude mnohem vice. Takze vezmeme ten nejlepsi pripad a vsechny ostatni moznosti budou vzdy horsi, tzn. | ||
- | < | ||
- | |||
- | :?: Kde se pro < | ||
- | |||
- | Taky si myslim, ze by to melo byt log(n). (viz. prednaska 7 slide 31) (kucerjo) | ||
- | |||
- | Ja si myslim, že pokud nastane ideální případ, že prvky spojáku sou v tom poli hezky za sebou a tedy může každej procesor svoji část kompletně vyřešit, potom je to < | ||
- | **Ale v tomhle sem nikdy nebyl moc dobrej, tak tomu nevěřte :-D. Může to někdo potvrdit? | ||
- | ===== Velikost podstromů (PRAM) ===== | ||
- | |||
- | Velikost podstromů, je zadáno RANK, není nutné předpočítat. Známe AL, EL, EA. | ||
- | * Bylo [[.: | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | :!://Viz skripta CZ [2006] str. 108; EN skripta 107 - 6.7.2.2 // | ||
- | |||
- | Pozn.: | ||
- | * AL - adjacency list - seznam uzlů - AL[x] je ukazatel do seznamu hran EL | ||
- | * EL - edge list - seznam hran, který se skládá z podseznamů hran vycházejících z jednotlivých uzlů | ||
- | * EA - edge array - pole hran, jak jdou za sebou v eulerovské cestě | ||
- | |||
- | :!: **2. varianta zadání - datové struktury (by zatretom): | ||
- | |||
- | V termínu 9. 2. 2015 bylo v zadání konkrétně napsáno, že máme EL (seznam hran) a zkonstruovanou cestu v poli EK, kde EK[i] je i-tá hrana eulerovské cesty. Nic víc. Při opravě docela tepal na tom, jak pracuju s datovejma strukturama - napsal jsem pseudokód v podstatě jako tady a hned mi vytknul, co to je Rank(xy) a podobně. | ||
- | |||
- | Ze zadání jsem pochopil, že v EK jsou hrany uloženy jako ukazatelé do EL akorát v pořadí tý cesty. Takže IMHO by se to mělo řešit takto (pro takto vybudované struktury): | ||
- | * Pro rodiče potřebuju znát pořadí, takže procházím do_in_parallel přes EK. | ||
- | * Protože pak potřebuju znát rank antiparalelního dvojčete a z EL se zpět na pořadí v EK nedostanu (znám pořadí xy, protože xy = EK[i], přes ukazatel se dostanu do EL a pak na dvojče yx, ale ukazatel zpět do EK nemám), musím si buď obohatit EL o rank nebo vytvořit vlastní datovou strukturu (to při prvním do_in_parallel zvládnu plně paralelně). | ||
- | * Pak už můžu postupovat podle kódu tady - budu mít obohacené EL (ve skriptech značeno jako EL') | ||
- | |||
- | Tato myšlenka vyjádřena pseudokódem: | ||
- | <code c> | ||
- | // Vstup: pole EK | ||
- | // Výstup: modifikovaný seznam EL` | ||
- | for i = 1 ... 2n - 2 in EK do_in_parallel{ | ||
- | EK[i].rank = i; // v poli EK[i] jsou ukazatelé na hrany v EL (EL tedy obohatím o rank) | ||
- | } | ||
- | |||
- | // Vstup: EL` | ||
- | // Výstup: Parent | ||
- | for all xy in EL` do_in_parallel{ | ||
- | if (xy.rank < xy.sibling.rank) Parent[y] = x; // xy.sibling je antiparalelní dvojče (yx) | ||
- | } | ||
- | Parent[root] = null; | ||
- | |||
- | |||
- | // Vstup: EL`, Parent | ||
- | // Výstup: Subtree | ||
- | for all uzly i in EL` do_in_parallel{ | ||
- | Subtree[i] = (Rank[ij] - Rank[ji] + 1)/2 ; //kde j=Parent[i]; | ||
- | } | ||
- | Subtree[root] = n; | ||
- | </ | ||
- | |||
- | EDIT: Předpokládám, | ||
- | === Algoritmus === | ||
- | == Pole rodičů == | ||
- | Na výpočet pole rodičů použijeme algoritmus(označíme hrany jako zpětné a dopředné): | ||
- | <code c> | ||
- | //Dir[xy] je příznak dané hrany | ||
- | //Rank[xy] je hodnota pořadí hrany | ||
- | for all xy in EL do_in_parallel{ | ||
- | | ||
- | Dir[xy] = F; // | ||
- | Dir[yx] = R; // | ||
- | Parent[y] = x; | ||
- | } | ||
- | } | ||
- | Parent[root] = null | ||
- | </ | ||
- | |||
- | To samé zapsané v pseudokódu, | ||
- | |||
- | <code python> | ||
- | # edges: pole hran a anti-paralelních hran (Tvrdík značí AA) | ||
- | # [ID počátečního + ID koncového uzlu => hrana] | ||
- | # parents: pole rodičů [ID uzlu => ID jeho rodičovského uzlu] | ||
- | def findAllParents(edges) { | ||
- | parents = array( nodes.length ); | ||
- | | ||
- | for edge in edges do_in_parallel { # 4m = 4*(2n-2) | ||
- | if (edge.rank < edge.sibling.rank) { # < | ||
- | parents[ edge.endNode ] = edge.startNode; | ||
- | } | ||
- | } | ||
- | return parents | ||
- | } | ||
- | </ | ||
- | |||
- | Algoritmus dostane na vstupu pole hran a jejich anti-paralelních hran (AA), které už jsou ohodnoceny algoritmem pro výpočet pořadí na Eulerovské cestě (známe „rank“). Ty paralelně projde a zastaví se jen u těch, které jdou směrem **od kořenu** (tj. mají nižší „rank“). Počáteční uzel této hrany prohlásí za rodiče koncového uzlu, resp. zapíše do pole rodičů. | ||
- | |||
- | Podle slajdů by měl ještě ukládat příznaky Dir (UP | DOWN) podle toho, kterým směrem hrana vede. Ty v těchto algoritmech ale nijak nevyužijeme, | ||
- | |||
- | Pozn. existuje ještě jeden algoritmus, který využívá právě těch UP|DOWN šipek, pokud to někoho zajímá, tak třeba v EN skriptech na straně 107 úplně dole. | ||
- | |||
- | == Velikost podstromů == | ||
- | Pak provedeme výpočet velikosti podstromů pomocí algoritmu: | ||
- | |||
- | <code c> | ||
- | //Rank[ij] je vzdálenost na eulerovské kružnici od uzlu i k jeho rodiči. | ||
- | for all uzly i != root do_in_parallel{ | ||
- | | ||
- | } | ||
- | Subtree[root] = n; | ||
- | </ | ||
- | |||
- | To samé zapsané v pseudokódu, | ||
- | <code python> | ||
- | # nodes: pole uzlů | ||
- | # edges: pole hran a antiparalelních hran (Tvrdík značí AA) | ||
- | # parents: pole rodičů | ||
- | # subtreeSizes: | ||
- | def countSubtreeSizes(nodes, | ||
- | subtreeSizes = array( nodes.length ); | ||
- | | ||
- | for node in nodes do_in_parallel { # < | ||
- | if (node.isRoot) continue; | ||
- | | ||
- | parentNode = parents[ node ]; | ||
- | edge = edges[ node +"" | ||
- | subtreeSizes[ node ] = (edge.rank - edge.sibling.rank +1)/2; | ||
- | } | ||
- | subtreeSizes[ ROOT ] = nodes.length; | ||
- | return subtreeSizes; | ||
- | } | ||
- | </ | ||
- | |||
- | Tento algoritmus využívá toho, že počet uzlů v podstromu je roven počtu všech hran v podstromu **dělený dvěma** (máme tu antiparalelní dvojčata!) Na vstupu dostane pole hran (AA) jako předchozí, | ||
- | |||
- | Zde přikládám ještě pro úplnost druhou variantu algoritmu (viz EN skripta s. 107 úplně dole), která pracuje s počítáním DOWN hran ve stromu. | ||
- | |||
- | <code python> | ||
- | def EREW_PRAM_AllSubtreeSizesII(EA[]) | ||
- | { | ||
- | # [1, ..., n] | ||
- | SubtreeSizes = array(EA.Length) | ||
- | |||
- | for edge in EA do_in_parallel { | ||
- | if edge.Direction == DOWN: | ||
- | ea.Weight = 1 | ||
- | else | ||
- | ea.Weight = 0 | ||
- | } | ||
- | |||
- | # postfixový součet! | ||
- | PSS(EA, attribute=Weight) | ||
- | |||
- | for edge in EA do_in_parallel { | ||
- | if edge.Direction == DOWN: | ||
- | SubtreeSizes[edge.EndNode] = edge.Weight - edge.Sibling.Weight | ||
- | } | ||
- | |||
- | SubtreeSizes[ROOT] = EA.Length # Počet všech uzlů grafu | ||
- | |||
- | return SubtreeSizes; | ||
- | } | ||
- | </ | ||
- | |||
- | A takto je vizualizace algoritmu výše: | ||
- | |||
- | {{: | ||
- | |||
- | === Složitost === | ||
- | |||
- | Počet procesorů nutný k provedení algoritmu v O(1) krocích je < | ||
- | |||
- | < | ||
- | |||
- | Jedná se tedy o plně paralelní algoritmus. | ||
- | |||
- | |||
- | **JDU:** Nepotvrzená domněnka\\ | ||
- | Algoritmus ze skript už má na vstupu pole rodičů. Sníží se tím potřebný počet procesorů, protože pak už nepotřebuju procesorů jako hran, ale jen jako procesorů.\\ | ||
- | V případě, že nám nedali pole rodičů k dispozici, nebudeme výpočet velikosti podstromu přece zbytečně rozdělovat na výpočet rodičů a samotného výpočtu podstromů, když velikosti podstromů můžeme drobnou modifikací počítat právě už při (místo) zjišťování rodičů (místo ukládání rodiče, spočítám už velikost). | ||
- | |||
===== OAB na M(z1, ... zn), SF, všeport, spodní a horní meze na kroky a komunikaci, napsat algoritmus, zhodnotit optimalitu ===== | ===== OAB na M(z1, ... zn), SF, všeport, spodní a horní meze na kroky a komunikaci, napsat algoritmus, zhodnotit optimalitu ===== | ||
Line 483: | Line 89: | ||
hanouto: Přidal jsem navíc obrázek s nejhorším případem v 3D mřížce, k optimalitě jen napsal, že optimální je bez nějakého dalšího odůvodnění a plný počet bodů. | hanouto: Přidal jsem navíc obrázek s nejhorším případem v 3D mřížce, k optimalitě jen napsal, že optimální je bez nějakého dalšího odůvodnění a plný počet bodů. | ||
- | ===== AAB na 1-portové mřížce s kombinováním paketů, SF, taab, r ===== | ||
- | |||
- | ==== Řešení ==== | ||
- | (jestli je to full duplex nebo ne bývá v zadání. tohle je full duplex. ) | ||
- | |||
- | :!://Viz přednáška 11 FIT slajd 10// | ||
- | |||
- | Algoritmus pro AAB na k-rozměrné 1-portové mřížce s kombinováním paketů je založen na AAB na 1 rozměrné 1-portové mřížce. Provádí se technikou sudo-lichých výměn. | ||
- | * V lichém kroku si každý lichý a následující sudý vymění zprávy. Posílají pouze nové zprávy, to jest ty, které se dozvěděly v předchozím kroku (neplatí pro první dva kroky, viz dále). | ||
- | * V sudém kroku udělá to samé každý sudý a následující lichý. | ||
- | * Na **M(z)** je počet kroků **k = z**, pokud je **//z//** liché, **k = z-1** v opačném případě. | ||
- | |||
- | Na začátku má každý uzel svou jednu zprávu, kterou chce poslat všem ostatním. V prvním kroku si tedy každá licho-sudá dvojice uzlů vymění vzájemně jednu zprávu, čímž už bude mít každý zprávy dvě (kromě posledního v případě lichého počtu uzlů). Ve druhém kroku si každá sudo-lichá dvojice vymění vše co mají, což jest dvě zprávy. V každém dalším kroku už se vyměňují pouze ty zprávy, které uzel nově obdržel v předchozím kroku, což jsou pokaždé právě dvě zprávy. Velikost zprávy je tedy v podstatě konstantní a délka trasy je vždy 1. | ||
- | |||
- | Obrázek za tisíc slov: | ||
- | |||
- | {{: | ||
- | |||
- | **Je-li //z// liché:** < | ||
- | |||
- | **jinak:** < | ||
- | |||
- | To (2z - 2) vykoukám z obrázku. V prvním kroku pošle jednička jeden paket velikosti < | ||
- | |||
- | Na více rozměrné mřížce se postupuje po dimenzích. Například ve 2D mřížce se nejprve provede AAB ve všech řádcích (tj. dimenze **// | ||
- | |||
- | < | ||
- | |||
- | Na začátku bude každý uzel začínat s jednou zprávou. Po dokončení AAB v první dimenzi už bude mít každý uzel tolik zpráv, kolik je velikost této dimenze. V dalším AAB ve druhé dimenzi už tedy budou uzly začínat se < | ||
- | |||
- | < | ||
- | |||
- | FIXME v tom vzorečku chybí ta zpoždění Ts a Tm. Těch Ts bude asi stejně jako r(AAB), ta Tm je třeba ověřit, já jsem do toho vzorečku ještě nepronikl... | ||
- | |||
- | Řekl bych, že: | ||
- | |||
- | < | ||
===== PPS na 1-portové 1-D mřížce ===== | ===== PPS na 1-portové 1-D mřížce ===== | ||
Line 575: | Line 144: | ||
{{http:// | {{http:// | ||
- | ===== Popsat smerovani na 1D toroidu odolne proti deadlocku ===== | ||
- | |||
- | Popsat směrování na 1D toroidu odolné proti deadlocku + jaké řešení + důkaz. | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | Popis je jasný, prostě člověk musí umět teorii | ||
- | |||
- | :!://Viz skripta CZ [2006] str. 146, skripta EN [2009] str. 90, prednaska 6, strana 38.// | ||
- | |||
- | Důkaz se udělá tak, že se nakreslí graf kanál. závislostí a ukáže se, že neobsahuje cykly. | ||
- | |||
- | :!: Dodatek by voho (nejsem si ale jistý): Dělá se to přes virtuální kanály. V toroidu o dimenzi //N// má každý uzel //2N// sousedů (portů). Každý port může být plně duplexní. Kdybychom byli v mřížce, tak uděláme dimenzionálně uspořádané směrování, | ||
- | |||
- | **Pro 1D toroid K(z) a směrování mezi uzly u, v** | ||
- | |||
- | Jestliže < | ||
- | |||
- | {{: | ||
- | |||
- | edit Radek: nejlépe je to vidět na obrázku ze skript, pokud je uzel tedy uzel < | ||
- | |||
- | pozn.: každý fyzický kanál lze rozdělit na < | ||
- | |||
- | {{: | ||
- | |||
- | |||
===== Paralelní sčítačka ===== | ===== Paralelní sčítačka ===== | ||
Line 692: | Line 234: | ||
Edit 2: Chybí a na straně 99 v ENG skriptech je v textu ten součet popsán. Přidal jsem výše pseudokód, který obsahuje i finální součet Z=X+Y+C. | Edit 2: Chybí a na straně 99 v ENG skriptech je v textu ten součet popsán. Přidal jsem výše pseudokód, který obsahuje i finální součet Z=X+Y+C. | ||
- | ===== EREW PRAM algoritmus pro pořadí uzlů v průchodu inorder ===== | ||
- | ★ //Bylo ve zkoušce: [[par_zkouska_2012-05-18|2012-05-18]]// | ||
- | Popište EREW PRAM algoritmus pro výpočet pořadí uzlů při průchodu inorder (levý podstrom, kořen, pravý podstrom) všech **n** uzlů Eulerova binárního stromu **S**. Výsledkem bude pole IN[1..n]. Eulerův strom **S** má **m = 2n-2** hran a je reprezentován polem uzlů, které mají odkazy na cyklický seznam svých hran. Předpokládejte, | ||
- | ==== Řešení ==== | ||
- | Podobná myšlenka jako PreOrder Přednáška 7 slide 42 | ||
- | |||
- | {{: | ||
- | |||
- | < | ||
- | alg. EREW_PRAM_InOrder(In: | ||
- | for xy in EA do parallel: | ||
- | if xy.direction <> xy.next.direction | ||
- | weight[xy.next] = 1 | ||
- | else | ||
- | weight[xy.next] = 0 | ||
- | | ||
- | call pps on EA | ||
- | | ||
- | for xy in EA list do parallel: | ||
- | if xy.direction <> xy.next.direction then | ||
- | inOrder[y] = weight[xy] | ||
- | </ | ||
- | |||
- | malo by to fungovat pre binarne stromy, v tejto podobe to cisluje od ' | ||
- | este by sa tam asi malo doplnit, ze pre koren plati: root = pocet uzlov | ||
- | |||
- | Pozn. Pozor, není myšlena //next// hrana dle definice reprezentace grafu pro Eulerovské stromy jako je tomu v přednášce 7/34, ale je tím myšlena následující hrana v eulerovské cestě. | ||
- | |||
- | Časová složitost tohoto algoritmu je velice podobná jako [[škola: | ||
- | |||
- | :!: Pokud algoritmus správně chápu, tak není korektní, protože přestane fungovat ve chvíli, kdy nějaký uzel nemá levý podstrom (extrémní případ by byl třeba spojový seznam). | ||
- | |||
- | :!: EA je eulerovský strom, podívej se na přednášku 7 slide 41, tam je krásně nakreslený jak vypadá. Tvoří eulerovskou kružnici, takže tam vždycky bude next. | ||
- | |||
- | EDIT: Trošku problém může být, že neznáme next. V EA máme uloženou jen hranu a její směr (Down, Up). | ||
- | |||
- | JDU: Domnívám se, že ten pseudokód nefunguje. Už když ten strom bude vypadat jako nudle doleva a na konci třešeň tak to nečísluje dobře (ty uzly v té nudli to kvůli tomu IF ani nijak neočísluje, | ||
- | |||
- | EDIT: Předpokládam, | ||
- | |||
- | Pero: Myšlenka algoritmu mi připadá správná, ale nefungovala by, pokud by poslední patro binárního stromu nebylo plné. Ale snad to jen někdo tady zapomněl dopsat do zadání, že je úplný.\\ | ||
- | Jen ten algoritmus není dotažený do konce, má někdo nápad, jak nakonec získám to pole IN? | ||
- | |||
- | Edit VD: Myslím, že algoritmus funguje správně, ale tedy jen na binární stromy. Jak je uvedeno výše, že ještě potřebujeme root = pocet uzlov, tak to podle mě není pravda (alespoň pokud si alg. odkrokujete na binárním stromu, kořen dostane správné číslo). | ||
- | |||
- | < | ||
- | def EREW_PRAM_InOrder([] EA) { | ||
- | |||
- | for edge in EA do_in_parallel { | ||
- | # Tato hrana má jinou orientaci než další hrana | ||
- | # v eulerovské cestě | ||
- | if edge.Direction != edge.Next.Direction: | ||
- | # Pozor: ne této hraně ale další | ||
- | EA[indexOf(edget.Next)].Weight = 1 | ||
- | else: | ||
- | EA[indexOf(edget.Next)].Weight = 0 | ||
- | } | ||
- | |||
- | pps(EA, on_attribute=Weight) | ||
- | InOrder = array(EA.Length) | ||
- | |||
- | for edge in EA do_in_parallel { | ||
- | # Tato hrana má jinou orientaci než další hrana | ||
- | # v eulerovské cestě | ||
- | if edge.Direction != edge.Next.Direction: | ||
- | # edge = x -> y (hrana vede z vrcholu x do y) | ||
- | InOrder[edge.Y] = EA[indexOf(edge)].Weight | ||
- | } | ||
- | |||
- | return InOrder; | ||
- | } | ||
- | </ | ||
- | |||
- | ===== EREW PRAM na hloubku uzlů ve stromu ===== | ||
- | |||
- | ★ //Bylo ve zkoušce: [[.: | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | Slajd 7/34 FEL | ||
- | |||
- | Analogicky jako EREW PRAM (třeba číslování preorder), jen hrany dolů ohodnotím 1 a hrany nahoru -1. Důležité je podle mě taky to, jaký byl vstup. Tím byl graf, každý uzel znal odkazy do pole na své hrany, hrany znaly odkazy na své protějšky a byla zkonstruována eulerovská kružnice, která byla k dispozici ve formě pole jako zobrazení pořadí hrany v kružnici → idetifikátor hrany. | ||
- | |||
- | {{: | ||
- | |||
- | Zde stejný algoritmus jen to trochu připomíná kód: | ||
- | |||
- | <code python> | ||
- | def EREW_PRAM_AllLevels(EA): | ||
- | for edge in EA do_in_parallel: | ||
- | if edge.Direction == DOWN: | ||
- | ea.Weight = 1 | ||
- | else: | ||
- | ea.Weight = -1 | ||
- | |||
- | pps(EA, on_attribute=Weight) | ||
- | Level = array(EA.Length) | ||
- | |||
- | for edge in EA do_in_parallel: | ||
- | if edge.Direction == DOWN: | ||
- | # edge = x -> y | ||
- | Level[edge.Y] = EA[indexOf(edge)].Weight | ||
- | |||
- | Level[indexOf(ROOT)] = 0 | ||
- | |||
- | return Level | ||
- | |||
- | </ | ||
====== Teorie a důkazy ====== | ====== Teorie a důkazy ====== | ||
- | ===== Dokažte, že e-cube směrování v Qn při zhuštění je bezkolizní ===== | ||
- | |||
- | ★ //Bylo ve zkoušce: [[.: | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | //viz skripta {{: | ||
- | |||
- | Důkaz je induktivní, | ||
- | Jelikož je to sousední dvojice, tak i ve výsledku budou sousední v tomto pořadí (z definice zhuštění). | ||
- | |||
- | Tedy mohou nastat dva případy : | ||
- | |||
- | - " | ||
- | - " | ||
- | |||
- | :?: Jak se může v druhém bodu vnořit do jiné podkrychle, když permutoval na nejnižším bitu (a ne na nejvyšším)? | ||
- | |||
- | Pozn: Neni tady nahodou ta druha cast spatne? Ja bych rekl, ze ten nejnizsi bit je ten nejvic v pravo. | ||
- | |||
- | |||
- | Pozn: Zhusteni zachovava poradi, takze kdyz jeden paket zacina na uzlu s poslednim bitem = 0 a druhy vedle nej, tedy s poslednim bitem = 1, budou i ve vysledku muset mit v cili posledni bit roven: jeden 0 a druhy 1 nebo opacne) Proto mame 2 moznosti viz vyse. | ||
- | |||
- | Zaroven se tu pouziva e-cube smerovani, ktere postupne porovnava bity zdrojoveho a ciloveho uzlu - pokud se nelisi (prvni pripad, protoze posledni bit v cili ccc0 a zdroji bbb0 je stejny), posle ty 2 pakety pod sebou rovne => nedojde ke kolizi. | ||
- | V druhem pripade se zdrojovy a cilovy uzel lisi v poslednim bite => bude se lisit i u zdroje a cile toho druheho paketu. Opet e-cube porovna i-ty bit zdroje a cile a pokud se lisi, posle pakety krizem => opet nebude kolize - nenabouraji do sebe | ||
- | |||
- | Ještě přidám moji verzi (bliznjan): V i-tém kroku (kroky i bity indexuji od nuly, bity indexuji zprava od nejnižšího) řeším vzájemně pouze ty dvojice paketů, jejichž souřadnice se liší právě v i-tém bitu zprava (jinak by v Qn nebyly v sousedních uzlech). Kolize by mohla nastat, kdybych takovouto dvojici paketů chtěl přesunout do stejného uzlu, tedy na stejné souřadnice. Vzhledem k e-cube směrování už mám bity vpravo (nižší) vyřešené a mohou se v následujících krocích měnit už jen vyšší bity, ale ty se naopak zatím neměnily. U dvou paketů, co zrovna řeším, tudíž platí, že jejich vyšší bity byly od začátku rovny, takže na začátku (i teď) byly od sebe vzdálené o méně než < | ||
- | ===== Dokažte, že neúplná online permutace zhuštění na indBFn je bezkolizní ===== | ||
- | Popište, jak si procesory na zadané indBFn zjistí pořadí, když lokálně mají jen flag 0/1 (zda patří do množiny) a následně proveďte neúplnou online permutaci zhuštění procesorů s flagem 1. Dokažte, že online směrování na indBF je pro ni bezkolizní | ||
- | |||
- | ★ //Bylo ve zkoušce: [[.: | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | zjištění cílového umístění, | ||
- | |||
- | {{ : | ||
- | |||
- | V podstatě stejné jako [[škola: | ||
- | |||
- | Důkaz je ve slidech, slide 31 přednáška 9 (pro oBFn, ale to je v skoro to samé). | ||
- | |||
- | Minimální směrování v indBFn funguje tak, že se porovnají adresy cíle a zdroje (postupně od LSB k MSB, v každé úrovni jeden). Když se bit adresy zdroje a cíle liší, tak se jde směrovačem křížem, když se neliší, tak se jde rovně. | ||
- | |||
- | Kolize může nastat v 1. úrovni motýlka pouze pro sousední uzly (tedy např. zdrojové uzly bbbb0 a bbbb1). Ty se permutují buď na uzly se stejnou paritou (xxxx0 a xxxx1) nebo s opačnou paritou (xxxx1 a xxxy0). Žádný jiný případ nemůže nastat. | ||
- | Když je parita stejná, tak oba uzly chtějí v cestě pokračovat rovně - není kolize a když je různá, tak chtějí oba pokračovat křížem - není kolize. | ||
- | |||
- | Po prvním stupni indBFn budou pakety směrovány do disjunktních podmotýlků indBFn-1 a důkaz tam induktivně probíhá stejně. | ||
- | ===== Důkaz bezkoliznosti operace přeložení na Qn při použití e-cube ===== | ||
- | |||
- | Dokažte, že v Qn je operace přeložení //i->i xor w// je při směrování e-cube bezkolizní (//w// je n-bitová posloupnost) | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | E-cube směrování se řídí bity řetězce //w// (protože < | ||
- | |||
- | Ke kolizi může nastat v libovolném kroku //k// mezi uzly spojenými hranou dimenze //k//. | ||
- | |||
- | Existují 2 možnosti: | ||
- | * a) //k//-tý bit řetězce //w// je 0 => k pohybu v //k//-té dimenzi nedojde => kolize nenastává | ||
- | * b) //k//-tý bit řetězce //w// je 1 => u obou uzlů dojde k pohybu v dimenzi //k// => vymění se pozice => kolize nenastává | ||
- | |||
- | //Pozn. by Klaara (ad pochybnosti o XORech): Řešení je OK. Jde o to si jakoby " | ||
- | |||
- | --- | ||
- | |||
- | Edit: dovysvětlení by Rulfik \\ | ||
- | jelikož permutace na < | ||
- | |||
- | Potom cílová adresa permutovaného paketu vyslaného z uzlu < | ||
- | |||
- | Edit: aby to bylo jasné, jak jsme se dostali k tomuto vzorci: < | ||
- | |||
- | xor je definován následovně | ||
- | |||
- | ^ < | ||
- | |0|0|0| | ||
- | |0|1|1| | ||
- | |1|0|1| | ||
- | |1|1|0| | ||
- | |||
- | Je nutné si uvědomit, že se směruje e-cube (tedy po jednotlivých dimenzích od LSB k MSB) tedy celkem v n krocích. | ||
- | Pro každý k-tý krok mohou nastat následující 2 případy: | ||
- | |||
- | ^ < | ||
- | ^0|**0**^0| | ||
- | ^1|**0**^1| | ||
- | |||
- | Je li w=0, pak k-tý bit adresy paketu zůstává nezměněn, ke směrování nedochází = žádná kolize | ||
- | |||
- | ^ < | ||
- | ^0|**1**^1| | ||
- | ^1|**1**^0| | ||
- | |||
- | Je-li w=1, pak k-tý bit se zneguje = čili u dvou sousedních uzlů dojde ke křížové výměně paketů = žádná kolize. | ||
- | |||
- | Čili je pravda, že směrování se řídí bity řetězce k jak již bylo uvedeno. | ||
- | |||
- | ===== Minimální směrování pro nepřímý oBFn ===== | ||
- | |||
- | Dokažte, že minimální směřování pro nepřímý oBF< | ||
- | |||
- | ★ //Bylo ve zkoušce: [[.: | ||
- | |||
- | ==== Řešení ==== | ||
- | |||
- | [[https:// | ||
- | |||
- | Cyklický posun jsou 2 operace zhuštění na stejné síti. Důkaz je tedy skoro stejný jako u důkazu že zhuštění je bezkonfliktní: | ||
- | - záleží na paritě slova o které se posouváme. Pokud je parita lichá, v prvním sloupci se vždy nastaví přepínače křížem = není kolize. Pokud je parita sudá, nejnižší bit se vůbec nemění a čili se nastaví přepínače rovně = není kolize | ||
- | - jelikož výstupy ze stupně 0 jdou na vstupy disjunktních podmotýlků, | ||
- | |||
- | |||
- | {{https:// | ||
- | (a) Cyklický posun o < | ||
===== Konstrukce všech uzlově disjunktních cest v 3D mřížce s nejkratšími délkami ===== | ===== Konstrukce všech uzlově disjunktních cest v 3D mřížce s nejkratšími délkami ===== | ||
Line 987: | Line 306: | ||
Nestačí. Nemáš najít pouze nejkratší cesty, ale všechny disjunktní cesty tak, aby byly co nejkratší. Disjunktních cest může být max 2*dimenze (to ti požere všechny sousední uzly k počátečnímu uzlu a žádné disjunktní cesty už neuděláš) a ty se je snažíš najít tak, aby byly co nejkratší -> najdeš dimeze-krát úplně nejkratších pomocí přímýho směrování + ty úhybný. (hroncmir) | Nestačí. Nemáš najít pouze nejkratší cesty, ale všechny disjunktní cesty tak, aby byly co nejkratší. Disjunktních cest může být max 2*dimenze (to ti požere všechny sousední uzly k počátečnímu uzlu a žádné disjunktní cesty už neuděláš) a ty se je snažíš najít tak, aby byly co nejkratší -> najdeš dimeze-krát úplně nejkratších pomocí přímýho směrování + ty úhybný. (hroncmir) | ||
- | |||
- | ===== SF,oBFn monotonni permutace ===== | ||
- | //Řešení obdobného příkladu: [[škola: | ||
- | |||
- | |||
- | Dokázat, že každou monotónní permutaci lze na SF oBFn realizovat bezkolizně, | ||
- | ==== Řešení ==== | ||
- | :!://Viz skripta [2006] str. 161-162// && [2015] 9. přednáška / slide 33 | ||
- | === Důkaz bezkoliznosti === | ||
- | |||
- | Monotónní permutace se skládá ze zhušťovací, | ||
- | |||
- | Důkaz je induktivní. Uvažujme, že žádné dva pakety se nemohou srazit na stejném uzlu v 1. úrovni (číslujeme od nuly). Ke kolizi by mohlo dojít jen mezi pakety, které by tvořily sudo–lichou dvojici po sobě jdoucích paketů. Tyto pakety by ovšem po zhuštění skončily také na dvou po sobě jdoucích výstupech. Mohou nastat dvě situace: | ||
- | - Výstupní uzly budou **sudo–lichá dvojice** (nejnižší bit se neliší). → Pakety šly v 1. úrovni **rovně** (dle pravidel min. směrování). → Nemohlo dojít ke kolizi. | ||
- | - Výstupní uzly budou **licho–sudá dvojice** (nejnižší bit se liší). → Pakety šly v 1. úrovni **křížem**. → Nemohlo dojít ke kolizi. | ||
- | Po tomto kroku se pakety dostanou na vstupy dvou navzájem disjunktních podmotýlků oBF< | ||
- | |||
- | |||
- | === Časová složitost === | ||
- | |||
- | Každá z permutací má složitost O(n). PPS má složitost O(2n) (FIXED). Celkem tedy O(5n), skrytá konstanta je 5. | ||
- | PPS n vstupních hodnot lze řešit na libovolné n-uzlové síti v čase T = O(diam(G)) viz Prednaska 7, slide 11. | ||
- | diam(oBFn) = 2n viz Prednaska 4, slide 37. | ||
- | |||
- | DOTAZ :?:: v tom zminenem tvrzeni se preci pise, ze to PPS lze resit v O(log n), kde n je pocet vstupnich hodnot, u nas tedy v O(log 2^n) = n. Podminku toho, ze tvrzeni to plati mame splnenou (diam(G) = 2*n = O(log2^n) = O(n). Budu rad za objasneni, diky. (navic tam se navic predpoklada, | ||
- | === Trocha teorie === | ||
- | |||
- | * Monotónní permutace je jakákoli neúplná permutace, která nemění pořadí paketů. Jinak řečeno, jedná se o směrování z libovolné podmnožiny vstupů do stejně velké podmnožiny výstupů, které mohou být různě posunuté, ale musí zachovávat stejné pořadí paketů. Každou monotónní permutaci lze vytvořit složením z permutace zhušťovací a roztažné. | ||
- | * Zhušťovací permutace je směrování paketů z libovolné podmnožiny **//x//** vstupů do //prvních, nebo posledních **x**// výstupů (tj. odshora, nebo odspoda), přičemž se opět zachovává relativní pořadí paketů. | ||
- | * Roztažná permutace (též zředění) je zrcadlovým otočením zhušťovací permutace. Je pro ni nutné zrcadlově otočit i celého motýlka, tj. posílat pakety zprava doleva. | ||
- | * Identita je směrování paketů z libovolné podmnožiny (nebo všech) vstupů do protějších výstupů. Jednoduše řečeno, pouze přenese pakety z jedné strany na druhou ve stejné řádce. | ||
- | |||
- | Realizace monotónní permutace na obyčejném motýlkovi má celkem **čtyři fáze**. Nejprve musíme spočítat relativní pořadí paketů (tj. aktivních vstupů) pomocí **paralelního prefixového součtu** (PPS). To je potřeba k výpočtu výstupních adres pro druhou fázi, **zhušťovací permutaci**. Ve třetí fázi provedeme **roztažnou permutaci**. Nejprve jsme pakety poslali zleva doprava, poté zpátky doleva, takže nakonec musíme provést **identitu**, | ||
- | |||
- | {{tag> |
users/martin.kocicka/pdp/6b.1497347318.txt.gz · Last modified: 2017/06/13 09:48 by martin.kocicka