Eerste Toets Concurrency 20 december 2018, 11.00 13.00, Educ-β. Motiveer je antwoorden kort! Stel geen vragen over deze toets; als je een vraag niet duidelijk vindt, schrijf dan op hoe je de vraag interpreteert en beantwoord de vraag zoals je hem begrijpt. Cijfer: Vraag 3 is 2pt, vraag 5 is 4pt en de andere vragen elk 3pt. Te halen 15pt; T1 is totaal plus 1, gedeeld door 1,4. 1. Terminatie van threads: Twee threads alterneren elk een bit, waarbij de ene zal stoppen bij gelijkheid en de andere juist bij ongelijkheid; a en b zijn initieel true: Thread 0: while (a == b) Thread 1: while (b!= a) a =!a; b =!b; (a) Heeft dit programma een oneindige executie? (b) Heeft dit programma een oneindige faire executie? (c) Bewijs dat het programma obstruction-free is voor thread 0: als, vanaf enig moment, thread 1 niet meer actief is, dan termineert thread 0. Oplossing: (a) Ja. De bits zijn in het begin gelijk; laat T0 zijn test doen en zijn body uitvoeren, dan zijn ze ongelijk. Daarna kan T1 zijn test plus body doen, en zijn de bits weer gelijk. Dit kan zich willekeurig vaak, zelfs oneindig vaak, herhalen. (b) Ja, want het scenario uit (a) is fair. Immers, elke thread komt oneindig vaak aan de beurt. (c) Als thread 1 een tijdje non-actief is, verandert b niet meer, terwijl thread 0 a zal alterneren. Op z n laatst in de tweede test zal thread 0 gelijkheid zien en termineren. (Mocht thread 1 hierna weer wakker worden, dan is thread 0 inactief en ook thread 1 zal termineren. Beoordeling/Toelichting: Per deelvraag een punt. Codes: A = Alleen 1 thread laten werken bij (a) is niet goed, die zou zichzelf termineren. B = Om de Beurt is niet hetzelfde als fair. E = Elke thread Een keer aan de beurt is nog niet genoeg voor fairness. F = Je moet zeggen waarom je voorbeeld fair is. L = De Loop conditiecheck plus body is niet atomair. (Het scenario in (a) pakt wel steeds een check plus body, maar je redenering mag er niet van uit gaan dat zoiets gegarandeerd is.) T = Thread 1 niet meer actief impliceert niet dat hij getermineerd is (en dus b==a). De premisse bij Obstruction Free is alleen, dat de thread lang genoeg geen activiteiten uitvoert. W = De While-conditie op false laat een thread niet Wachten maar termineren.
2. MultiReader register: Om een MultiReader register te bouwen met SingleReader registers, kun je gebruik maken van kopiëren, wat de eigenschappen Safe en Regular behoudt. (a) Wanneer is een register Regular? (b) Geef code voor Write(x) en Read() voor een MultiReader Safe register. Wat is de complexiteit van de Write(x) en Read() als er n Readers zijn? (c) Laat met een voorbeeld zien, dat kopiëren niet de eigenschap Atomic behoudt. Oplossing: (a) Wanneer een Read gegarandeerd de waarde teruggeeft van een ermee overlappende Write, of de laatste Write die was afgelopen voor de Read begon. (b) Het n-reader register bestaat uit n SR-registers: s SR-register[n] Write(x): for(int i=0; i<n; i++) Read() voor Reader i: s[i].write(x); return s[i].read(); De Read bestaat uit 1 read en heeft dus constante complexiteit O(1). De Write bestaat uit n write s dus heeft lineaire complexiteit O(n). (c) Een Inversie wordt mogelijk: laat de Writer eerst s[0] en dan s[1] muteren. Tussen deze twee write s kan Reader0 een complete Read uitvoeren en de nieuwe waarde zien, strikt waarna Reader1 komt en de oude waarde ziet. (Dit is alleen een inversie wanneer de Read van Reader0 is afgelopen voordat de Read van Reader1 begint.) Beoordeling/Toelichting: Totaal 3pt, per deelvraag een punt. Beoordelingscodes: B = Bij overlap tussen de twee reads is er geen sprake van inversie. C = Complexiteit vergeten te vermelden. G = Je beschrijft wel wat een inversie is, maar niet hoe dat kan Gebeuren, 1/2pt. K = Kopiëren is een techniekje om multireader te beeiken, het staat niet voor een of andere actie die hier gebeurt. M = Een Read kan ook met Meerdere (of geen) Writes overlappen, 1/2pt. S = Silent Write gebruik je om een regular bit te maken, maar is niet de definitie ervan. T = Een regular register heeft alleen een non-atomair scenario met Twee Reads. U = Wat je beschrijft is de Unaire representatie, niet kopiëren. V = Voorlaatste opleveren mag alleen bij overlap! W = Writes kunnen niet overlappen in een Single-Writer situatie. Z = Zelfs geen beschrijving van wat een inversie is, 0pt.
3. Ticket en 3-Consensus: Anneke heeft voor haar Softwareproject een 3-Consensus object nodig, waarmee consensus wordt bereikt tussen 3 threads. Uit haar vorige project heeft Anneke nog een atomair Ticket object, dit is een object met 1 methode namelijk rinc() die aan de aanroepende threads achtereenvolgens oplopende integers returnt. Geef een implementatie van 3-Consensus met Ticket, of bewijs dat dit niet kan. Oplossing: Dit is onmogelijk, omdat de Ticket maar consensus-getal 2 heeft. Om dit compleet te bewijzen, moet je redeneren over een bivalente state C, die een 0-valente en 1-valente opvolger heeft, zeg C 0 en C 1. Een consensus-protocol, als het bestaat, heeft zo n state. We weten uit het college dat de stappen die tot 0- en 1-valentie leiden, geen registerstappen kunnen zijn of stappen op verschillende objecten. De stappen van bv. thread0 en thread1 die C 0- resp. 1-valent maken zijn dus rinc stappen. Helaas is na een rinc-stap niet te zien, welke thread die uitvoerde. Dus zijn C 0 en C 1 2-gelijk en kunnen geen verschillende valentie hebben. Beoordeling/Toelichting: Max 2pt. Beoordelingscodes: A = De combinatie t[i] = rinc(); is niet Atomair. B = Beredeneert dat Bepaalde oplossing niet kan, 1/2, 1 of 1 1/2 afhankelijk van algemeenheid. C = 1 als je alleen iets over het Consensus-getal zegt. Voor 2 moet je ook echt beredeneren waarom Ticket CN=2 heeft. Als je denkt dat Ticket CN 1 heeft, 1/2. K = Zegt Kan alleen met CaS, 1/2. N = Zegt kan Niet, maar zonder toelichting, 0pt. T = Bewijst CN van Ticket door te zeggen dat die met TaS kan, maar niet hoe, 1 1/2pt. W = Zegt dat t Wel kan, 0pt.
4. Parallelle Conjunctie: (a) Laat zien hoe de CRCW PRAM de conjunctie van n condities c i, dus c 0 c 1 c 2... c n 1, kan bepalen in lineair (dus O(n)) werk en constante (dus O(1)) span. (b) Kan je algoritme worden uitgevoerd op een CREW-PRAM en wat is dan de duur van de executie? (c) Wat is een goede manier om de conjunctie te bepalen op een CREW-PRAM? Oplossing: (a) Dit is het duale van de OR (die op hoorcollege is voorgedaan): (1) R = true; (2) par.for(i, 1, n) if (!c[i]) R = false; Na afloop is R true wanneer alle c i true zijn, en false wanneer minstens 1 c i false is, dus de conjunctie. De Concurrent Write die de vraag veronderstelt, zorgt dat ook meerdere writes in constante tijd worden verwerkt. (b) Dit gaat op een CREW heel slecht. Als k het aantal condities is dat false is, worden er k writes op R gedaan en dat kost Θ(k) tijd, dus in het slechtste geval lineair. (c) Gebruik een boomschema of een van de andere recursieve oplossingen die we voor Sommeren hebben gezien. Dat kost lineair veel werk en logaritmische span. Beoordeling/Toelichting: Per deelvraag een punt. Je kunt (a) zien als een kennisvraag, (b) als een toepassingsvraag (betekenis EW) en (c) als doordenkvraag. Beoordelingscodes: A = Als Alle threads de c i schrijven naar R, krijg je niet de conjunctie, maar de waarde van de laatst schrijvende thread. B = Boomschema bij (a) geen pt, onnodig traag. C = Onduidelijk hoe de deelresultaten gecombineerd worden. Er bestaat geen Concurrent Return op de CRCW PRAM! K Alleen Kan niet (met motivatie) bij (b) geeft 1/2, want het kan wel alleen het duurt langer. L = Concurrent Read/Write slaat op operaties op dezelfde Locatie. OR = Er werd gevraagd om AND maar jij geeft OR, 1/2pt. R = Een Recursieve oplossing kost logaritmische span. Elk ander schema dat volgens een boomplan paarsgewijze competities houdt ook. S = De R lezen voor t Schrijven (Silent Write) werkt niet, je zou R moeten locken. 0pt. U = Een Update zoals R = R && c[i]; is inherent sequentieel en kan niet parallel, zelfs niet op een CRCW PRAM. V = De c i laten combineren met de Volgende c i+1 is vrij zinloos (lost niet t probleem op). Z = Stoppen Zodra je False ziet is een sequentieel proces, 0pt.
5. Parallelle MergeSort: Om n elementen te sorteren, zal MergeSort recursief de eerste en laatste helft sorteren, en dan de gesorteerde deelrijen samenvoegen, dwz. mergen. Sequentieel mergen van n elementen kost O(n) tijd. (a) Analyseer de span van een parallelle MergeSort, waarin alleen de twee recursieve aanroepen parallel worden gedaan (met Invoke) en het mergen sequentieel. (b) Is het algoritme uit (a) efficient en is het optimaal? Leg uit. (c) Je kunt n elementen mergen met n/ lg n cores in O(lg n) tijd. Wat betekent dit voor Work en Span van de merge? (d) Als je de merge procedure uit c gebruikt in MergeSort, wordt het algoritme dan efficient en optimaal? Oplossing: (a) Noem de span voor n elementen, S(n). Omdat de recursieve aanroepen parallel gaan, tellen we die als eentje, maar het mergen is dan nog sequentieel dus lineair. Dit geeft de vergelijking S(n) = S(n/2) + O(n) met oplossing (MT: a = 1, b = 2, f(n) = n 1 ) S(n) = O(n). (b) De work is gelijk aan de sequentiele tijd, dus O(n lg n), wat optimaal is voor sorteren, er is dus constante overhead. Helaas is de span niet polylogaritmisch, waarmee het niet optimaal is (namelijk: constante overhead en polylog span) en zelfs niet efficient (namelijk: polylog overhead en ploylog span). (c) Als de taak gedaan wordt door n/ lg n cores in lg n tijd, is de verzette hoeveelheid werk zeker niet meer dan O(n), conclusie: Work is (hoogstens) lineair. Het is na lg n tijd af, waaruit volgt dat de Span (hoogstens) logaritmisch is. Beide zijn optimaal (het is dus niet strikt minder dan lineair cq. logaritmisch) maar daarover hoef je niets te zeggen. (d) We kunnen de lineaire Work en logaritmische Span invoeren in de Work en Span vergelijkingen voor MergeSort. Die heeft dan Work W (n) = 2 W (n/2) + O(n) met oplossing W (n) = O(n lg n), en Span S(n) = S(n/2) + O(lg n) met oplossing S(n) = O(lg 2 n). De Work is gelijk aan de sequentiele complexiteit, dus geen overhead, en de Span is polylog, het is dus wel efficient en zelfs optimaal. Beoordeling/Toelichting: Een punt per deelvraag, totaal 4pt. Codes: A = Analyseren betekent het opstellen van de recurrente betrekking plus het oplossen ervan (met de master Theorem). D = Uitkomst is (Diepte van recursie keer) Dwangterm is niet een acceptabele manier om een RB op te lossen, zelfs niet als die uitkomst hetzelfde is als de juiste oplossing. E = Extra factor lg n vergeten bij de Span van MergeSort. F = Gebruik f(n) (of f(lg n)) niet als synoniem voor O(n) (of O(lg n)). L = Verkeerde Overhead berekend omdat je denkt dat sorteren sequentieel Lineair (of Logaritmisch) is. S = Bij (c) en (d) werd Merge en MergSort vaak door elkaar gehaald. Bij (c) werd gevraagd naar Merge, maar als je MergeSort daar juist analyseerde was t goed. Bij (c) Merge analyseren en de uitkomst gebruiken bij (d) voor MergeSort isniet goed. V = Wel Vreemd als je Work vindt die lager is dan sequentiële tijd! Moet opvallen! Z = Een recurrente betrekking heeft de Zelfde functienaam in de LHS en RHS staan, als in S(n) = S(n/2) + O(n). Niet goed is T (n) = S(n/2) + O(n) of S(n) = (n/2) + O(n).