Debugging. Testování. I když vypadá kód bez chyby, stejně ho nechte testovat víc než dostatečně dlouho za různých podmínek.

Podobné dokumenty
Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Teoretické minimum z PJV

Vlákna a přístup ke sdílené paměti. B4B36PDV Paralelní a distribuované výpočty

Procesy a vlákna - synchronizace

Paralelní architektury se sdílenou pamětí typu NUMA. NUMA architektury

K8055D.DLL v Technická příručka. Úvod. Obecné. Konvence volání. Nastavení adresy karty

C++ 0x aka C++11. Základním kamenem je třída std::thread

IPA - Lab.1 Úvod do programování v ASM

Více o konstruktorech a destruktorech

Procesy a vlákna (Processes and Threads)

Programování v Javě I. Leden 2008

Vlákno odlehčený proces kód vlákna, zásobník privátní ostatní sdíleno s dalšími vlákny téhož procesu

TG Motion verze 4 Modul Virtuální PLC návod k obsluze

8 Třídy, objekty, metody, předávání argumentů metod

ZÁKLADY PROGRAMOVÁNÍ. Mgr. Vladislav BEDNÁŘ , 5.1 a 5.2 8/14

Úvod do programovacích jazyků (Java)

Ústav technické matematiky FS ( Ústav technické matematiky FS ) / 35

Ukázka zkouškové písemka OSY

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

11. Přehled prog. jazyků

Architektura COM. Historie Component Object Model (COM) Komunikace s komponentami Rozhraní komponent COM komponenty v.net.

1. Programování proti rozhraní

Objektové programování

Programování v Javě I. Únor 2009

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

ALGORITMIZACE A PROGRAMOVÁNÍ

Paralelní programování

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

TG Motion verze 4 Modul Virtuální PLC návod k obsluze

Příklad aplikace Klient/Server s Boss/Worker modelem (informativní)

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Zápis programu v jazyce C#

Assembler - 5.část. poslední změna této stránky: Zpět

Úvod do programování

Úvod do OpenMP. Jiří Fürst

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

ZOS 9. cvičení, ukázky kódu. Pavel Bžoch

PES lib (C + PASCAL) KNIHOVNY KOMUNIKAÈNÍCH FUNKCÍ 03/ PESlib KOMUNIKAČNÍ KNIHOVNY C, PASCAL 03/ stran 1

Správa paměti. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta, 2016

1 Nejkratší cesta grafem

Struktura programu v době běhu

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

ČÁST 1. Základy 32bitového programování ve Windows

Programování v jazyce C a C++

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Abstraktní datové typy: zásobník

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Cvičení 9 - Monitory. monitor m; var proměnné... procedure p; begin... end; begin inicializace; end;

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Konstruktory a destruktory

IUJCE 07/08 Přednáška č. 6

Operační systémy Tomáš Hudec. 6 Komunikace procesů (IPC) Obsah: 6.1 Klasické problémy souběhu Obědvající filosofové

PB161 Základy OOP. Tomáš Brukner

Matematika v programovacích

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Pavel Procházka. 3. prosince 2014

Programování bez vláken. OpenMP

Řada programovacích jazyků nabízí prostředky pro řešení meziprocesové komunikace jako je synchronizace a řízení přístupu do kritické sekce.

Aplikace Embedded systémů v Mechatronice. Michal Bastl A2/713a

Reprezentace dat v informačních systémech. Jaroslav Šmarda

Principy objektově orientovaného programování

Programovací jazyky. imperativní (procedurální) neimperativní (neprocedurální) assembler (jazyk symbolických instrukcí)

PB161 Programování v jazyce C++ Přednáška 9

Další aspekty architektur CISC a RISC Aktuálnost obsahu registru

Dědění, polymorfismus

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Funkční objekty v C++.

CZ.1.07/1.5.00/

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Algoritmizace a programování

Popis funkcí a parametrů programu. Reliance External communicator. Verze 1.5.0

Paralelní výpočetní jádro matematického modelu elektrostatického zvlákňování

PB071 Programování v jazyce C Jaro 2013

Úvod do GPGPU J. Sloup, I. Šimeček

Programování v C++, 2. cvičení

Vláknové programování část V

Google Web Toolkit. Martin Šurkovský, SUR března Katedra informatiky

Opakování programování

Unity a Objekty (NMIN102) RNDr. Michal Žemlička, Ph.D.

dovolují dělení velkých úloh na menší = dekompozice

15. Projekt Kalkulačka

IUJCE 07/08 Přednáška č. 1

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

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

Paralelní a distribuované výpočty (B4B36PDV)

MPASM a IDE pro vývoj aplikací MCU (Microchip)

IUJCE Přednáška č. 11. další prvky globální proměnné, řízení viditelnosti proměnných, funkcí

Mělká a hluboká kopie

Paralelní programování

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

Novinky ve Visual Studio Tomáš Kroupa

setup() { I = 0; } loop() { I = I + 1; }

PREPROCESOR POKRAČOVÁNÍ

Dalším příkladem může být například výstup dat na různá zařízení, souborů, grafických rozhraní, sítě atd.

Řídicí struktury. alg3 1

Transkript:

Debugging Čistě sériový kód se dá odladit snadno, protože posloupnost vykonávání instrukcí je pokaždé stejná U paralelních výpočtů to neplatí Odladit netriviální, navíc je-li optimalizovaný, paralelní výpočet je jedna z nejtěžších věcí Testování I když vypadá kód bez chyby, stejně ho nechte testovat víc než dostatečně dlouho za různých podmínek Sériový kód Stále je třeba odladit sériový kód, resp. kód vlákna, zda např. provádí správně např. I/O operace Jde o kontrolu té části výpočtu, kdy nedochází k interakci s ostatními vlákny, ani se nepřistupuje ke sdíleným proměnným Lze s ním odladit pouze omezenou množinu všech možných chyb paralelního programu Většinou jde o chyby, které je vidět přímo ze zdrojového kódu Kontrolní výpisy Výsledek paralelního programu s chybnou synchronizací závisí i na tom, jak rychle poběží jeho vlákna o Krokování v debuggeru IDE způsobuje velké prodlevy Strana 1 (celkem 11)

Randseed Může tak docházet k dodatečné synchronizaci, jejímž následkem se chyba neprojeví o Kontrolní výpis sice neposkytne tolik informací jako použití debuggeru, ale zase je rychlost vykonávání vláken bližší jejich běžné rychlosti Kontrolní výpis také způsobuje dodatečnou synchronizaci, která může zabránit chybě, aby se projevila o Fce volající jádro způsobují dodatečnou synchronizaci Např. v kontrolním výpisu GetThreadID Rychlost programu, tj. i možné potlačení chyby, ovlivní o Debug verze vs. release verze Release verze by minimálně díky optimalizaci měla běžet rychleji V debug verzi může být něco od překladače, co způsobí dodatečnou synchronizaci o Použitý hardware Pentium Pro vs. fce Delay Borland Pascalu CRT unit počítal, kolikrát zvládne procesor vykonat smyčku za jeden tik hodin -55ms Pentium Pro od 200MHz výš jich zvládlo více 65536 Tj. 16-bitové dělení přeteklo, a následně se to projevilo jako chyba dělení nulou o Zátěž systému Strana 2 (celkem 11)

V systému může běžet několik aplikací, uzamykatelné zdroje nemusí být vždy stejně dostupné, využití systémových zdrojů se mění viz zátěžové testy simulující nedostatek systémových zdrojů Je možné do debug verze programu přidat náhodné zpoždění sleep(rand) o A na začátku inicializovat proměnnou randseed, tak aby se případná chyba dala zopakovat Pokud jí ovšem způsobují náhodné prodlevy, opakované ve stejném pořadí Lamportovy hodiny Vymyšlené pro distribuované systémy o Pro sdílenou paměť budeme vlákno považovat za proces distribuované aplikace Časové značky, které umožňují částečné uspořádání událostí o Ale neumožňují implikovat závislost Časová značka je monotónně inkrementující se counter o Jeden na proces/vlákno o integer Vlastnosti o Proces/vlákno inkrementuje counter před každou událostí o Kdykoliv proces pošle zprávu, vlákno provede interakci, přiřadí se k tomu časová značka counter o Proces přijímající zprávu, druhý účastník interakce, nastaví svůj vlastní counter na maximum z přijatého Strana 3 (celkem 11)

counteru a svého counteru, než došlo k přijetí cizího counteru Synchronizuje svoje hodiny s vysílajícím procesem, iniciátorem interakce Nechť a a b jsou události C(x) je čas události x Pak platí o Pokud a způsobilo b, pak C(a) < C(b) Vektorové hodiny Vektorové hodiny umožňují detekci porušení příčinnosti mezi událostmi v distribuovaném systému Lamport umí detekci pro dva procesy http://upload.wikimedia.org/wikipedia/commons/5/55/vector_clock.svg Máme vektor Lamportových hodin o Hodin všech procesů/vláken o Proces si drží nejmenší potřebnou kopii vektoru o Všechny procesy/vlákna vždy inkrementují o stejné, konstantní množství 1 Strana 4 (celkem 11)

Postup o Vynulovat všechny hodiny o Proces/vlákno inkrementuje svoje hodiny při vnitřní události Např. když se chystá odeslat zprávu, ve které bude odesílaný vektor s jeho hodinami již inkrementovanými o Kdykoliv proces přijme zprávu, vlákno se dostane do interakce, inkrementuje svoje logické hodiny a updatuje zbývající, známé hodiny ostatních procesů/vláken na maxima z toho, co zná, a z toho, co přijal Nechť je VC(x) časový vektor události x Pak pro události a a b platí, že VC(a) < VC(b) tehdy, když: o for i:=0 to vectorsize-1: VC(a)[i]<=VC(b)[i] o a pro alespoň jedno i platí, že VC(a)[i]<VC(b)[i] Pak opět platí o Pokud a způsobilo b, pak VC(a) < VC(b) Další možnosti Maticové hodiny o chronologická a příčinná souvislost událostí o zobecnění vektorových hodin Vektor verzí verzování replik dat Co se začalo odvíjet od Lamportových hodin, je spíše vhodné pro studium doktoranda - ale je dobré to znát i tak Strana 5 (celkem 11)

Příklad využití Lamportových hodin u vláken Rozhraní jsou nadefinována analogicky ke konceptu IAdviseSink z Windows COM type PEventMedium = ^TEventMedium; TEventMedium = record Clock:integer; //Lamportovy hodin Sender:TSenderID; Code:integer; //kód zprávy WParam, //parametry LParam:integer; end; IEventAdviseSink = interface(iunknown) ['{FBCA3BDD-9E2A-4AA7-961E-742336109CD0}'] procedure OnEvent(const event:peventmedium); stdcall; end; IEventAdviseHolder =interface(iunknown) ['{33675443-A096-40B2 -B076-1DCD5475DAEF}'] function Advise( const Sink:IEventAdviseSink; out Connection:integer ):HRESULT; stdcall; function Unadvise(const Connection:integer):HRESULT; stdcall; function SendOnEvent(const Code, WParam, LParam:integer ):HRESULT; stdcall; end; Strana 6 (celkem 11)

Pozor na to, že vše není chyba synchronizace vláken Pokud se zdá, že algoritmus je napsaný správně, ale přesto to nefunguje, nemusí být chyba v synchronizaci vláken, ale v inicializaci proměnných a dat Překladače se obvykle chovají různě, když produkují debug verzi a release verzi výsledného kódu Debug verze obvykle inicializuje proměnné a přidělenou paměť na nuly o Snadná detekce nil pointerů o Snadnější detekce dělení nulou o Při přičítání se jakoby nic neděje čísla se nemění o Při násobení se jakoby nic nepočítá výsledkem je 0 Release verze nemusí nic inicializovat o Proč do proměnné přiřazovat nulu, když se vzápětí bezpodmínečně přepíše něčím jiným? Může se stát, že přidělená paměť už obsahuje něco, s čím program zdánlivě běží správně o Např. lokální proměnné podprogramů v oblasti již dříve použitého zásobníku o Vlastní paměť ový manažer s recyklací použitých paměť ových bloků, ale bez jejich inicializace o Ale na jiném počítači, nebo spuštění programu mimo IDE, už v takovém případě může mít za následek jiné chování programu Ze stejného důvodu je třeba kontrolovat návratové hodnoty synchronizačních funkcí! Strana 7 (celkem 11)

Cizí knihovny Pokud se kód chová divně bez zjevné příčiny, může být chyba i v knihovně, kterou používáte o Např. projekt zkompilovaný s maximální optimalizací, díky které se projevila v něm obsažená chyba Pak se totiž může stát, že se s jedním překladačem chyba objeví, a s druhým ne Nicméně, úměrně k počtu lidí, kteří danou knihovnu používají, je mnohem víc pravděpodobnější, že je chyba ve vašem kódu o Např. danou knihovnu špatně používáte #include <concrt.h> class CRWLock { private: Concurrency::reader_writer_lock mclock; public: void AcquireRead(){mcLock.lock_read();} void AcquireWrite(){mcLock.lock(); } void Release() {mclock. unlock();} }; o Concurrency Runtime by MS & Intel o Lepší chování než SRW Lock WinAPI Jenže potřebujete mít plánovač a asociovat s ním vlákna Jinak memory leaks a možné vyjímky Jenomže concrt může vytvořit implicitní plánovač, a kód tak může zdánlivě běžet OK za určitých podmínek Strana 8 (celkem 11)

Specifické triky Např. pro MS VC a WinDbg lze pro diagnostické účely pojmenovat vlákna přes výjimku o Specifická záležitost, původně nedokumentovaná Posléze dokumentovaná k MS VS 2003 #if defined(_msc_ver) && defined(_debug) typedef struct tagthreadname_info { DWORD dwtype; //must be 0x1000 LPCSTR szname; //pointer to name DWORD dwthreadid; //thread ID DWORD dwflags; //must be zero } THREADNAME_INFO; void SetThreadName( DWORD dwthreadid, LPCSTR szthreadname) { THREADNAME_INFO info; { info.dwtype = 0x1000; info.szname = szthreadname; info.dwthreadid = dwthreadid; info.dwflags = 0; } try { RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(dword), (DWORD*)&info ); } except EXCEPTION_CONTINUE_EXECUTION){} } #endif Strana 9 (celkem 11)

o V kombinaci MS VC 2010 (.dll) a Delphi 2005 (.exe) Memory leaks Neočekávaná vyjímka, která se někdy tvářila jako chyba výpočtu, jindy jako chyba synchronizace v dalších případech jako chyba pointerové aritmetiky a většinu času to běželo, jako kdyby tam žádná chyba nebyla Podle debuggeru Delphi byla vyjímka na straně VC Podle debuggeru VC byla vyjímka na straně Delphi A pak to odlaďte, když se k tomu nikdo nezná Hrozí takové nebezpečí u Javy a JVM? o V prvé řadě jde o zodpovědnost programátora, že vůbec něco takového použije Musí vědět, co dělá v uvedeném příkladu má možnost výběru, jestli to použije, nebo ne o Kdyby se JVM spoléhal pouze na bytecode, tak by program běžel neúnosně pomalu, a proto se JVM snaží nahradit známé knihovní funkce implementacemi napsanými v assembleru, nebo jiném, pointerovém jazyku Tj. splněn první krok Druhým krokem je spustit kód, který nevytvořil tým JVM, ani žádný nástroj JVM Strana 10 (celkem 11)

o JNA Java Native Access Přístup k DLL a Shared Objects bez JNI //BOOL WINAPI EnumWindows( // in WNDENUMPROC lpenumfunc, // in LPARAM lparam); public interface User32 extends StdCallLibrary { interface WNDENUMPROC extends StdCallCallback { boolean callback(pointer hwnd, Pointer arg); } boolean EnumWindows(WNDENUMPROC lpenumfunc, Pointer arg); } User32 user32 = User32.INSTANCE; user32.enumwindows(new WNDENUMPROC() { int count; public boolean callback(pointer hwnd, Pointer userdata) { System.out.println( "Found window " + hwnd + ", total " + ++count); return true; } }, null); https://jna.dev.java.net/ o Navzdory původní myšlence, jen reference na objekty a monitory (synchronized), dnes už i v Javě máte možnost vytvořit chyby specifických triků o Je to o to záludnější, že Java na to nebyla navržená Strana 11 (celkem 11)