Programování inženýrských aplikací

Rozměr: px
Začít zobrazení ze stránky:

Download "Programování inženýrských aplikací"

Transkript

1 Výchova studentů pro aplikace řešené na výkonných počítačích České vysoké učení technické v Praze Fakulta strojní Programování inženýrských aplikací Jiří Fürst TENTO PROJEKT JE SPOLUFINANCOVÁN EVROPSKÝM SOCIÁLNÍM FONDEM A STÁTNÍM ROZPOČTEM ČESKÉ REPUBLIKY A ROZPOČTEM HLAVNÍHO MĚSTA PRAHY

2 Obsah 1 Jemný úvod do C Objektově orientované programování Knihovna Boost Vícerozměrná pole v C++ v knihovně Boost Nástroje pro analýzu kódu Valgrind Valgrind - cvičení Profiler Optimalizace programu pro jeden procesor Princip fungování cache Přímo mapovaná cache N-cestně asociativní cache Plně asociativní cache Cache na konkrétních typech procesorů Optimalizace pro lepší využití cache Umístění dat v paměti Paralelní programování počítače se sdílenou pamětí Procesy, vlákna a jejich využití OpenMP standard OpenMP direktivy Direktiva for/do Dodatek Charakteristika počítačů použitých pro měření Program pro měření času Poznámka na úvod Tento text slouží především jako poznámky pro výuku předmětu Programování inženýrských aplikací na FS ČVUT. Jedná se pouze o částečné informace, které si čtenář musí samostatně doplnit a ověřit v literatuře. Některé kapitoly jsou zatím spíše osnovou přednášky a na rozšíření se průběžně pracuje. Soubor pia.pdf obsahuje aktuální verzi tohoto dokumentu v PDF formátu. Na adrese jsou též průběžně aktualizované verze ukázkových programů a dalších doplňujících materiálů. 1

3 Kapitola 1 Jemný úvod do C++ V této sekci se pokusíme o ukázku některých prvků programovacího jazyka C++. V žádném případě se nebude jednat o úplný výklad všech zákoutí tohoto jazyka. Pokusíme se spíše čtenáře seznámit s těmi vlastnostmi C++, které jsou dobře využitelné pro tvorbu vědecko-technických programů. Budeme sse snažit hlavně o srozumitelnost a přehlednost programu, dosažení co nejvyššího rychlosti běhu, případnou možnost kontroly přeloženého kódu. Do nedávné doby 1 byl hlavním programovacím jazykem pro vědecko-technické aplikace jazyk Fortran. V současné době se většina studentů učí programovat v jazycích C/C++. Ty jsou univerzálnější než Fortran, na druhou stranu je však programovaní v těchto jazycích poněkud složitější. Proto se budeme zabývat jakousi podmnožinou jazyka C++ pracovně nazvanou C++tran, která bude obsahovat pouze ty konstrukce, které jsou vhodné pro numerické výpočty. Při čtení následujícího textu budeme předpokládat u čtenáře základní znalosti jazyka C. 1.1 Objektově orientované programování Hlavním rozdílem mezi C++ a jazukem C nebo Fortran je velmi dobrá podpora tzv. objektově orientovaného programování. Tomuto způsobu programování je věnována celá řada dobře dostupné literatury. My seproto nebudeme věnovat popisu OOP a ukážeme si pouze některé aplikace OOP, které jsou vhodné pro programovaní jednoduchých úloh z inženýrské praxe. První jednoduchou ukázkou je třída implementující obyčejné jednorozměrné pole. Při práci s poli v jazyce C víme, že je třeba buď znát rozměry pole před sestavením programu (tzv. statické pole), nebo můžeme použít tzv. dynamické pole alokované až v době běhu programu. Bohužel, zpusob zápisu dynamické alokace v C je poněkud složitý a proto se pokusíme nahradit dynamicky alokované pole jednoduchou třídou, kterou budeme dále rozšiřovat. Výpis 1.1 ukazuje velmi jednoduchou třídu, která obsahuje dvě položky: velikost pole a ukazatel na dynamicky alokovaná data. Výhodou této třídy oproti běžné dynamické alokaci je to, že takto alokované pole není třeba explicitně dealokovat. Jakmile totiž zanikne proměnná obsahující pole, volá se destruktor třídy a ten po sobě automaticky uklidí paměť. 1 Dle mého soukromého názoru je jím stále. 2

4 1 #include <iostream > c l a s s Array { 5 6 p u b l i c : 7 8 int s i z e ; 9 double data ; Array ( int n ) { 12 s i z e = n ; 13 data = new double [ n ] ; 14 } ~ Array ( ) { 17 d e l e t e [ ] data ; 18 } } ; // using namespace std ; int main ( int argc, char argv ) { Array x = Array ( 1 0 ) ; for ( int i =0; i <10; i++) 30 x. data [ i ] = i ; return 0 ; 34 } Výpis 1.1: program class/array.cpp 3

5 Na druhou stranu, přístup do pole se děje poněkud složitě přes x.data[i]. To není nejvhodnější, protože pokud bychom chtěli nahradit klasické pole pomocí námi navržené třídy v již hotovém programu, museli bychom provádět mnoho změn v kódu a to by mohlo vést k zanesení nových chyb. Bylo by proto vhodné naučit pole pracovat s obvyklým přístupem pomocí hranatých závorek. To je prezentováno v příkladě 1.2, kde v definici třídy přibývá operátor [], který vrací referenci na požadovaný prvek. Další změnou je to, že v této tříde jsou položky deklarované jako privátní a nelze k nim tedy přistupovat přímo. Zápis pomocí x.data[i] tedy již není možný. Důležitější je však to, že uživatel nemá žádnou možnost změnit položku size. Jednou z nejčastějších chyb při práci s poli je překročení rozsahu pole. Například práce s prvkem 100 u pole o velikosti 50. Rozšíříme tedy definici operátoru [] o kontrolu, zda požadovaný prvek je platný. TO lze implementovat jednoduše pomocí rozhodovacího příkazu. To by ale znamenalo, že výsledný kód bude vždy testovat platnost prvku, což může velmi zdržovat běho programu. Ve výpisu 1.3 je proto ukázáno použití makra assert. Přeložíme-li tento program pomocí g++ array-v2a.cpp, bude se při každém přístupu k prvku pole testovat podmínka uvedená uvnitř makra. Jestliže nebude splněna, progrm ohlásí při behu chybu s výpisem, pomocí kterého budeme schopni chybu lokalizovat. Pro výslednou verzi programu, která již neobsahuje chyby, můžeme použít překlad s parameterm -DNDEBUG, překladač automaticky vynechá všechny kontroly v makru assert. Dalším omezení polí v C/C++ je to, že jsou indexována výhradně od nuly. Výpis 1.4 ukazuje rozšíření třídy Array o možnost deklarovat pole s libovolnými mezemi. Poslední ukázkou implementace pole je příklad 1.5, ketrý ukazuje, jak jednoduše použít navrženou třídu Array nejen pro prvky typu float, ale pro definici pole libovolného typu. 1.2 Knihovna Boost Knihovna Boost je volně dostupná na adrese Jedná se o velmi rozsáhlou knihovnu usnadňující programování některých obecných úloh v jazyce C++. Její úplný popis se vymyká rozsahu tohoto kurzu a my se proto omezíme na podmnožinu, týkající se implementace polí Vícerozměrná pole v C++ v knihovně Boost Podpora vícerozměrných polí je v jazyce C++ velmi omezená. Je sice možné deklarovat vícerozměrné pole například jako double a[100][100], tato deklarace je však statická. Pokud je zapotřebí použít dynamická pole, řeší se to obyčejně tak, že se na vícerozměrné pole pohlíží jako na pole polí, např. pro dvourozměrná pole (matici) bychom použili pole ukazatelů na rádky matice. Tento postup vypadá na první pohled velmi atraktivně: je možné použít jednoduchý zápis pro přístup k prvku jako a[i][j] a je možné postup rozšířit i na vícerozměrná pole. Na druhou stranu má tento postup určité nevýhody: složitější alokace a dealokace pole, např. pro matici se alokace provádí jako double** a;... a = (double**)malloc(n*sizeof(double*)); for (i=0; i<n; i++) a[i] = (double*)malloc(m*sizeof(double)); a dealokace jako 4

6 1 #include <iostream > 2 #include <c a s s e r t > 3 4 c l a s s Array { 5 6 int s i z e ; 7 double data ; 8 9 p u b l i c : Array ( int n ) { 12 s i z e = n ; 13 data = new double [ n ] ; 14 } double & o p e r a t o r [ ] ( int i ) { 17 return data [ i ] ; 18 } ~ Array ( ) { 22 d e l e t e [ ] data ; 23 } int g e t S i z e ( ) { 26 return s i z e ; 27 } } ; using namespace std ; int main ( int argc, char argv ) { Array x = Array ( 1 0 ) ; for ( int i =0; i <x. g e t S i z e ( ) ; i ++) 39 x [ i ] = i ; double s =0; 42 for ( int i =0; i <x. g e t S i z e ( ) ; i ++) 43 s += x [ i ] ; cout << " s = " << s << endl ; return 0 ; 48 } Výpis 1.2: program class/array-v2.cpp 5

7 1 #include <iostream > 2 #include <c a s s e r t > 3 4 c l a s s Array { 5 6 int s i z e ; 7 double data ; 8 9 p u b l i c : Array ( int n ) { 12 s i z e = n ; 13 data = new double [ n ] ; 14 } double & o p e r a t o r [ ] ( int i ) { 17 return data [ i ] ; 18 } ~ Array ( ) { 22 d e l e t e [ ] data ; 23 } int g e t S i z e ( ) { 26 return s i z e ; 27 } } ; using namespace std ; int main ( int argc, char argv ) { Array x = Array ( 1 0 ) ; for ( int i =0; i <x. g e t S i z e ( ) ; i ++) 39 x [ i ] = i ; double s =0; 42 for ( int i =0; i <x. g e t S i z e ( ) ; i ++) 43 s += x [ i ] ; cout << " s = " << s << endl ; return 0 ; 48 } Výpis 1.3: program class/array-v2-a.cpp 6

8 Výpis 1.4: program class/array-v3.cpp 1 #include <iostream > 2 #include <c a s s e r t > 3 4 c l a s s Range { 5 6 p u b l i c : 7 8 int lower, upper ; 9 10 Range ( ) { } ; Range ( int up ) { 13 lower = 0 ; 14 upper = up ; 15 } Range ( int lo, int up ) { 18 lower = l o ; 19 upper = up ; 20 } } ; c l a s s Array { Range range ; 28 double data ; p u b l i c : Array ( Range r ) { 33 range = r ; 34 data = new double [ range. upper range. lower ] ; 35 } Array ( int n ) { 38 range = Range ( n ) ; 39 data = new double [ range. upper range. lower ] ; 40 } double& o p e r a t o r [ ] ( int i ) { 44 a s s e r t ( range. lower<= i & i < range. upper ) ; 45 return data [ i range. lower ] ; 46 } int lbound ( ) { return range. lower ; } int ubound ( ) { return range. upper ; } ~ Array ( ) { 53 d e l e t e [ ] data ; 54 } } ; using namespace std ; int main ( int argc, char argv ) { Array x = Array ( 1 0 ) ; for ( int i =0; i <10; i++) 66 x [ i ] = i ; double s ; 69 s = 0 ; 70 for ( int i =0; i <10; i++) 71 s += x [ i ] ; cout << " s = " << s << endl ; Array y = Array ( Range ( 2,12) ) ; for ( int i=y. lbound ( ) ; i <y. ubound ( ) ; i ++) 80 y [ i ] = i ; s = 0 ; 83 for ( int i=y. lbound ( ) ; i <y. ubound ( ) ; i ++) 84 s += y [ i ] ; cout << " s = " << s << endl ; return 0 ; 90 }

9 1 #include <iostream > 2 #include <c a s s e r t > 3 4 template<typename T> 5 c l a s s Array { 6 7 int s i z e ; 8 T data ; 9 10 p u b l i c : Array ( int n ) { 13 s i z e = n ; 14 data = new T[ n ] ; 15 } T & o p e r a t o r [ ] ( int i ) { 18 a s s e r t ( 0<= i & i < s i z e ) ; 19 return data [ i ] ; 20 } ~ Array ( ) { 24 d e l e t e [ ] data ; 25 } } ; using namespace std ; int main ( int argc, char argv ) { //Array x = Array ( 1 0 ) ; 35 Array<float > x ( 1 0 ) ; for ( int i =0; i <10; i++) 38 x [ i ] = i ; double s =0; 41 for ( int i =0; i <10; i++) 42 s += x [ i ] ; cout << " s = " << s << endl ; return 0 ; 47 } Výpis 1.5: program class/array-v4.cpp 8

10 Výpis 1.6: program boost/array2d.cpp 1 #include <iostream > 2 #include " boost / multi_array. hpp " 3 4 typedef boost : : multi_array<double,2> array2d ; 5 6 int main ( int argc, char argv ) { 7 int n, m; 8 double s ; 9 10 s t d : : cout << " Zadej rozmery p o l e ( n,m)\ n " ; 11 s t d : : c i n >> n >> m; array2d A( boost : : e x t e n t s [ n ] [m] ) ; for ( int i =0; i<n ; ++i ) 16 for ( int j =0; j<m; ++j ) 17 A[ i ] [ j ] = 1. 0 ; s = 0 ; 20 for ( int i =0; i<n ; ++i ) 21 for ( int j =0; j<m; ++j ) 22 s += A[ i ] [ j ] ; s t d : : cout << " Soucet n x m j e " << s << " \n " ; 25 return 0 ; 26 } for (i=0; i<n; i++) free(a[i]); free(a); pole jsou indexována vždy od nuly, není možné jednoduchým způsobem z pole vybrat určitou část (podmatici). Tyto problémy řeší šablona multi_array<t,rank>, která definuje pole o rank rozměrech jehož prvky jsou typu T. Následující příklad ukazuje deklaraci matice o rozměrech n krát m prvků typu double: #include "boost/multi_array.hpp"... boost::multi_array<double,2> a(boost::extents[n][m]); K prvkům této matice lze přistupovat 2 jednoduše pomocí indexů, tj. a[i][j]. Příklad 1.6 ukazuje jednoduché použití knihovny boost pro práci s maticemi. Na zčátku kódu je pomocí příkazu typedef definován nový datový typ array2d, který odpovídá matici s prvky typu double. Pole definované pomocí šablony multi_array obsahuje mimo hodnot prvků také informace o tvaru pole (mj. o počtu dimenzí, o velikostech v jednotlivých dimenzích). Toho lze využít například při předávání pole do funkce. Příklad 1.7 ukazuje použití metody shape(), která pro zadané pole vrací odkaz na pole obsahující rozměry pole v jednotlivých dimenzích. Velikou výhodou je možnost definovat pole, jejichž indexu nepůjdou od nuly, ale od libovolného čísla. Příklad 1.8 ukazuje, jak lze vytvořit pole, jehož indexy začínají -1. Všimněte si též funkce pro součet prvků. Zde je nejprve z pole získána hosdnota nejmenšího indexu pomocí index_bases(). 2 Existují i další typy přístupů k prvkům matice, například přes iterátory. 9

11 Výpis 1.7: program boost/array2d-s1.cpp 1 #include <iostream > 2 #include " boost / multi_array. hpp " 3 #include <c a s s e r t > typedef boost : : multi_array<double,2> array2d ; 7 8 double sum( array2d M) { 9 double s ; s = 0 ; 12 for ( int i =0; i <M. shape ( ) [ 0 ] ; ++i ) 13 for ( int j =0; j<m. shape ( ) [ 1 ] ; ++j ) 14 s += M[ i ] [ j ] ; return s ; 17 } ; int main ( int argc, char argv ) { 20 int n, m; 21 double s ; s t d : : cout << " Program pro demonstraci 2D p o l e z knihovny b o ost \n " ; 24 s t d : : cout << " Zadej rozmery p o l e ( n,m)\ n " ; 25 s t d : : c i n >> n >> m; 26 s t d : : cout << " zadano n=" << n << " m=" << m << " \n " ; array2d A( boost : : e x t e n t s [ n ] [m] ) ; for ( int i =0; i<n ; ++i ) 31 for ( int j =0; j<m; ++j ) 32 A[ i ] [ j ] = 1. 0 ; s = sum (A) ; s t d : : cout << " Soucet n x m j e " << s << " \n " ; 37 return 0 ; 38 } 10

12 Výpis 1.8: program boost/array2d-m1.cpp 1 #include <iostream > 2 #include " boost / multi_array. hpp " 3 #include <c a s s e r t > typedef boost : : multi_array<double,2> array2d ; 7 typedef array2d : : extent_range range ; 8 9 double sum( array2d M) { 10 double s ; int i 1 = M. index_bases ( ) [ 0 ] ; 13 int i 2 = i 1 + M. shape ( ) [ 0 ] ; int j 1 = M. index_bases ( ) [ 1 ] ; 16 int j 2 = j 1 + M. shape ( ) [ 1 ] ; for ( int i=i 1 ; i <i 2 ; ++i ) 19 for ( int j=j 1 ; j<j 2 ; ++j ) 20 s += M[ i ] [ j ] ; return s ; 23 } ; int main ( int argc, char argv ) { 26 int n, m; 27 double s ; s t d : : cout << " Program pro demonstraci 2D p o l e z knihovny b o ost \n " ; 30 s t d : : cout << " Zadej rozmery p o l e ( n,m)\ n " ; 31 s t d : : c i n >> n >> m; 32 s t d : : cout << " zadano n=" << n << " m=" << m << " \n " ; array2d A( boost : : e x t e n t s [ range ( 1,n + 1 ) ] [ range ( 1,m+ 1 ) ] ) ; for ( int i = 1; i<n+1; ++i ) 37 for ( int j = 1; j<m+1; ++j ) 38 A[ i ] [ j ] = 1. 0 ; s = sum (A) ; s t d : : cout << " Soucet ( n+2) x (m+2) j e " << s << " \n " ; 43 return 0 ; 44 } 11

13 Kapitola 2 Nástroje pro analýzu kódu 2.1 Valgrind Program valgrind umožňuje nalézt v přeloženém programu místa, která jsou pravděpodobně chybami. Obsahuje následující nástroje: memcheck - nástroj pro odhalování chybných přístupů do paměti (např. index prvku v poli je mimo rozsah pole), použití neinicializovaných proměnných a chybné alokace a dealokace, cachegrind - nástroj pro měření využití cache, callgrind - nástroj pro měření výkonu programu, massif - nástroj pro měření paměťových nároků programu Valgrind - cvičení Pomocí programu valgrind se pokuste nalézt a odstranit chyby z následujících programů. valgrind/example_01.cpp valgrind/example_02.cpp valgrind/example_03.cpp valgrind/example_04.cpp valgrind/example_05.cpp valgrind/example_06.cpp valgrind/example_07.cpp 2.2 Profiler Profiler je program umožňující změřit výkon programu. Velmi jednoduché je použití standardního profileru gprof. Na následujícím příklade si jej ukážeme na příkladě kódu pro řešení obtékání profilu. Jedná se program obsahující celou řadu funkcí a přetížených operátorů. My se pokusíme 12

14 zjistit, kolikrát se která funkce ve skutečnosti volala a kolik času se v ní strávilo. To nám pomůže určit, kterou část kódu bychom měli optimalizovat. Nejprve program přeložíme s parametrem -pg, tedy g++ -O -pg ProgramLW-orig.cpp Poté jej spustime. Během vykonávání programu se v aktuálním adresáři vytváří soubor gmon.out, do kterého si program zapisuje informace o svém běhu. Tyto informace lze přečíst pomocí programu gprof, tedy gprof./a.out Na obrazovce se objeví dlouhý výpis začínající udaji o jednotlivých funkcích. V našem případě je zde něco jako Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name tpromenna::operator*(double) NumerickeSchema() tpromenna::operator+(tpromenna) tpromenna::operator-(tpromenna) frame_dummy global constructors keyed to _ZN9tPromennap NodeCentering() SpoctiGeometrii() VypisVysledekNC() static_initialization_and_destruction_0(i Zadani() PocPodm() NactiSit() Z tohoto výpisu vidíme, že prakticky třetina času se strávila během volání operátoru násobení a tento operátor byl volán mnohokrát. Stejně tak se mnoho časy strávilo ve funkci NumerickeSchems() a v operátoru pro sčítání. Naproti tomu funkce jako SpoctiGeomerii() nespotřebuje prakticky žádný čas. To znamená, že při optimalizaci kůdu bychom se měli soustředit hlavně na operátory a na funkci NumerickeSchema(). 13

15 Kapitola 3 Optimalizace programu pro jeden procesor Současné procesory jsou většinou velice výkonné a při práci s rozsáhlými daty, se kterými se u vědecko-technických aplikací často setkáváme, nebývá celkový výkon počítače určován ani tak frekvencí procesoru, jako spíše rychlostí přístupu do paměti. Výroba pamětí, které by pracovaly s rychlostí odpovídající procesoru, je velmi drahá a náročná a proto se v počítačích využívají pomalejší paměti s velkou kapacitou a procesory se vybavují rychlejšími vyrovnávacími pamětmi (tzv. cache) o menší kapacitě. 3.1 Princip fungování cache Jak již bylo naznačeno, cache bývá sice mnohem rychlejší, má však mnohem menší kapacitu, než hlavní pamět. To znamená, že se do cache nemohou vejít všechna potřebná data a řídicí obvody cache musí umět "hospodařit" s místem. To vše musí zvládat velmi rychle a proto algoritmus pro správu cache musí být velmi jednoduchý. Probereme si nyní tři v současné době nejužívanější typy cache pamětí Přímo mapovaná cache Nejjednodušším typem je tzv.přímo mapovaná cache. Její princip si nejlépe vysvětlíme na jednoduchém příkladě. Předpokládejme, že náš fiktivní 32-bitový procesor má 16kB cache. Ta bývá organizovaná to tzv. řádků. Řekněme, že délka řádku je 64B, to znamená, že cache má 256 řádků. Ke každému řádku je navíc přidruženo dodatečných 18 bitů paměti (tzv. tag) pro řízení cache. Předpokládejme, že procesor chce číst dataz určité adresy, provede řadič následující operace: 1. rozdělí adresu na tři části. V pořadí od nejméně významného bitu to jsou (a) 6 bitů tvořících adresu bytu v řádku o délce 64B, (b) 8 bitů tvořících číslo řádku, (c) zbylých nejvýznamnějších 18 bitů pro tag. 2. Řadič se podívá do vypočteného řádku a pokud uložený tag v tomto řádku souhlasí s tagem adresy požadovaných dat, přečte procesor data z odpovídající pozice tohoto řádku. 14

16 3. Pokud tag nesouhlasí, řádek z cache je uložen do paměti (pokud je to zapotřebí) a na jeho místo je z paměti natažen celý řádkek obsahující požadovaná data. To znamená, že komunikace mezi procesorem a pamětí probíhá po celých řádcích (tj. 64B) a to i v případě, že potřebujeme z paměti jediný bit. Tento nejjednodušší typ cache trpí jednou nevýhodou. Představme si, že pracujeme s matsicí čísel typu double o rozměrech 2048x2048 a tato čísla budou uložena v souvislém úseku paměti. Předpokládejme, že chceme sečíst v této matici první dva sloupce 1 a výsledek uložit do třetího: 1 for ( i =0; i <2048; i ++) 2 a [ i ] [ 2 ] = a [ i ] [ 0 ] + a [ i ] [ 1 ] ; Počítač nejdříve načte do cache číslo a[0][0]. Pak se snaží načíst a[0][1]. To je přesně 16kB od a[0][0] a mělo by tedy být uloženo v cache do stejného řádku. Je tedy třeba načíst nový řádek (tj. 64B). Výsledek se bude ukládat do a[0][2], které patří opět do stejného řádku a je tedy potřeba opět načíst do stejného řádku cache data z jiného úseku paměti. Ve druhém kroku cyklu se situace přesně opakuje s tím rozdílem, že než se do cache nahraje řádek obsahující a[1][0], je třeba stávající řádek zapsat do paměti (bylo v něm změněno 8B). Ve výsledku to znamená, že jsme nejen vůbec nevyužili rychlost cache, ale k načtení 2 n a uložení n čísel o 8B se z pomalé paměti načítalo 3 n a ukládalo n řádků o délce 64B! N-cestně asociativní cache V mnoha moderních procesorech se proto používá tzv. vícecestná nebo vícecestně asociativní cache. Tu si můžeme představit zhruba jako několik vedle sebe postavených přímo mapovaných pamětí. Např. L1D cache procesoru T2350 (Intel Core Duo) má kapacitu 32kB a je 8-mi cestně asociativní. To znamená, že je složena z osmi bank po 64 řádcích o délce 64B. Ke každému z těchto 512 řádků je přidána paměť o délce 20b pro tagy. V případě, že chce procesor procesor číst nějaká data, rozdělí adresu na dolních 6 bitů pro určení pozice uvnitř řádku, dalších 6 bitů pro číslo řádku a zbylých 20 bitů bere jako tag. Řadič potom porovná vypočtený tag s uloženými tagy v daném řádku pro každou banku a pokud v některé dojde ke shodě, přečte data z řádku této banky. Pokud není požadovaný řádek v žadné bance, řadič uvolní řádek v některé bance a nahraje požadovaný řádek do tohoto místa. Tím se do jisté míry odstraní resp. oddálí dříve zmiňovaný problém. Nicméně stejný problém by mohl nastat v případě, že bychom chtěli sečíst prvních 9 sloupců matice o rozměrech prvků Plně asociativní cache Nejdokonalejším, avšak výrobně nejnáročnějším) typem je tzv. plně asociativní cache, kterou si můžeme představit jako N-cestně asociativní typ, kde N je tak velké, že v každé bance je pouze jeden řádek. Např. pro 32kB cache s řádkem dlouhým 64B by to odpovídalo 512-cestně asociativní verzi Cache na konkrétních typech procesorů Toto bych rád doplnil tabulkou shrnující parametry cache na některých procesorech. 1 Ve Fortranu by to byly řádky. 15

17 3.2 Optimalizace pro lepší využití cache Umístění dat v paměti Rychlost přístupu dat do paměti je mimo jiné ovlivněna rozložením dat v paměti. Uvažujme následující příklad: máme pole struktur z nichž každá obsahuje tři čisla typu double. Naším úkolem je vypočíst nové pole o stejné velikosti jehož hodnoty budou dány součtem deseti prvků původního pole na zadaných pozicích. Tento algoritmus se nazývá gathering a v různých variantách se objevuje např. při násobení řídkých matic s vektory nebo v metodě konečných prvků či objemů. Podívejme se nyní na to, jakým způsobem je možné tento jednoduchý algoritmus optimalizovat pro lepší využití cache. Připomeňme, že při přístupu k paměti se do cache přenáší celá řádka (tzn. 64B). To znamená, že pokud je načítaná struktura uložená v paměti uvnitř jednoho řádku, bude pro načtení jedné struktury o délce 24B zapotřebí načíst z paměti 64B. Pokud ale bude uložena přes hranici řádků, bude potřeba načíst 128B! To znamená, že je vhodné ukládat data tak, aby neprocházela přez hranici řádků. Tho lze dosáhnout jednoduše ve dvou krocích: Modifikujeme data tak, aby délka struktury odpovídala délce řádku, tzn. aby byla buď dělitelem nebo násobkem délky řádku. V našem případě do struktury doplníme nepoužívanou položku char pad[8] čímž změníme délku struktury na 32B. Alokujeme pamět tak, aby začátek alokované paměti odpovídal hranici řádků. Toho dosáhneme např. pomocí funkce posix_memalign. Výpis 3.1 obsahuje implementaci tohoto programu. Tabulka 3.1 ukazuje vliv délky datové struktury a adresy začátku pole na rychlost programu pro různé typy procesorů. je z ní vidět, že uložení dat v paměti může ovlivnit výkon programu. Na druhou stranu je ale u tohoto příkladu vidět závislost na daném procesoru. 16

18 Výpis 3.1: program cache/padding.cpp 1 #include <iostream > 2 #include <s t d l i b. h> 3 #include " timer. hpp " 4 5 struct Item { 6 double x ; 7 double y ; 8 double z ; 9 10 char pad [32 3 s i z e o f ( double ) ] ; 11 } ; int main ( int argc, char argv ) { 16 const int N = ; 17 const int NZ = 1 0 ; 18 const int NITER = 5 ; Item a, b ; 21 int idx, k ; 22 double x, y, z ; //a = ( Item ) malloc (N s i z e o f ( Item ) ) ; 25 //b = ( Item ) malloc (N s i z e o f ( Item ) ) ; posix_memalign ( ( void )&a, 64, N s i z e o f ( Item ) ) ; 28 posix_memalign ( ( void )&b, 64, N s i z e o f ( Item ) ) ; idx = ( int ) malloc (NZ N s i z e o f ( int ) ) ; for ( int i =0; i <N NZ; i ++) 33 idx [ i ] = ( int ) (N ( ( f l o a t ) rand ( ) ) /RAND_MAX) ; for ( int i =0; i <N; i ++) { 36 b [ i ]. x = 1 ; b [ i ]. y = 2 ; b [ i ]. z = 3 ; 37 } ; Timer stopky ( " mereni " ) ; 41 stopky. s t a r t ( ) ; for ( int i t e r =0; i t e r <NITER ; i t e r ++) 44 for ( int i =0; i <N; i ++) { 45 x = 0 ; y = 0 ; z = 0 ; 46 for ( int j=nz i ; j<nz i+nz; j++) { 47 k = idx [ j ] ; 48 x += b [ k ]. x ; 49 y += b [ k ]. y ; 50 z += b [ k ]. z ; 51 } ; 52 a [ i ]. x = x ; 53 a [ i ]. y = y ; 54 a [ i ]. z = z ; 55 } ; stopky. s t o p ( ) ; std : : cout << "MFLOPS = " << (3 N NZ NITER)/ stopky. getwalltime ( ) 1. e 6; 60 s t d : : cout << " \n " ; 61 s t d : : cout << " s i z e o f ( Item)= " << s i z e o f ( Item ) << " \n " ; 62 s t d : : cout << "&a [ 0 ] = " << a << " \n " ; 63 s t d : : cout << "&b [ 0 ] = " << b << " \n " ; 64 return 0 ; 65 } 17

19 CPU sizeof(item) alokace MFLOPS Pentium-M 24 malloc GHz 32 malloc 37 - g++ -O3 24 posix_memalign posix_memalign 37 Pentium-M 24 malloc GHz 32 malloc 46 - icc -O3 -xb 24 posix_memalign posix_memalign 47 Core 2 Duo 24 malloc 90 - E malloc GHz 24 posix_memalign 91 - g++ -O3 32 posix_memalign 108 Altix 24 malloc 43 - Itanium2 32 malloc GHz 24 posix_memalign 43 - icc -O3 32 posix_memalign 43 Altix 24 malloc 18 - Itanium2 32 malloc GHz 24 posix_memalign 18 - g++ -O3 32 posix_memalign 18 Tabulka 3.1: Výkon programu cache/padding.cpp na ruzných typech procesorů. CPU LDA MFLOPS Pentium-M g++ -O Pentium-M icc -O3 -xb Core 2 Duo g++ -O Altix icc -O Altix icc91 -O Tabulka 3.2: Výkon programu cache/trashing.cpp na ruzných typech procesorů. 18

20 Kapitola 4 Paralelní programování počítače se sdílenou pamětí Nejprve se soustředíme na programování počítačů se sdílenou pamětí. U tohoto typu paralelního počítače mají všechny procesory neomezený přístup do společné paměti. Velmi často je takový počítač složen z jedné společné paměti ke které je přes společnou sběrnici připojeno buď několik procesorů nebo jeden vícejádrový procesor. S rostoucím počtem procesorů resp. jader zde však dochází velmi rychle dochází k zahlcení sběrnice a proto je tento jednoduchý model vhodný pouze pro malý počet procesorů. Složitějším typem počítače se sdílenou pamětí je tzv. NUMA systém (Non-Uniform Memory Access neboli nestejný přístup k paměti), kdy je počítač složen z uzlů obsahujících jeden či více procesorů a lokální paměť. Uzly jsou navzájem propojeny pomocí řídicích obvodů a sítě tak, že procesory mají neomezený přístup do pamětí všech uzlů (sdílená paměť), rychlost přístupu však závisí na tom, do jaké části paměti procesor přistupuje. Nejrychlejší přístup je samozřejmě do paměti na stejném uzlu, rychlost přístupu do paměti jiných uzlů závisí na topologii propojení a na rychlosti linek, bývá však několikanásobně menší. Tento typ počítače (např. SGI Altix) existuje v konfiguracích obsahujících tisíce procesorů. V následujících kapitolách se seznámíme s přímým využitím procesů a vláken pro nízkoúrovňové paralelní programování a dále se budeme podrobněji věnovat standardu OpenMP, který umožňuje paralelní programování na vyšší úrovni. 4.1 Procesy, vlákna a jejich využití Hlavním cílem paralelního programování je zkrácení času potřebného na zpracování nějaké úlohy. Toho lze dosáhnout tak, že ke zpracování této úlohy využijeme více procesorů. Můžeme tedy spustit několik procesů nebo jeden proces rozdělit na několik vláken tzv. threads. Objasněme si jeden podstatný rozdíl mezi procesem a vláknem. Každý proces má svou vlastní přidělenou paměť která je chráněna před přístupem od ostatních procesů. To znamená, že procesy mezi sebou nemohou komunikovat přímo a musí k tomu využívat služeb operačního systému. Navíc se zde do jisté míry ztrácí výhoda počítače se sdílenou pamětí. Naprotitomu vlákna vzniknou rozštěpením jednoho procesu a sdílejí tedy spolu paměť. Komunikovat spolu tedy mohou přímo pomocí této sdílené paměti. Odsud vyplývá, že pro paralelní programování na počítačích se sdílenou pamětí je výhodnější používat vlákna. Přímé použití vláken lze například pomocí knihovny pthreads, která obsahuje základní funkce 19

21 1 #include <s t d i o. h> 2 3 int main ( ) { 4 5 #pragma omp p a r a l l e l 6 { 7 p r i n t f ( " Ahoj\n " ) ; 8 } 9 10 return 0 ; 11 } Výpis 4.1: program openmp/parallel.c pro vytváření a rušení vláken a pro synchronizaci mezi vlákny. 4.2 OpenMP standard OpenMP je nadstavbou jazyků Fortran/C/C++, která umožňuje paralelizaci programu bez nutnosti práce s nizkoúrovňovými knihovnami typu pthreads. Standard OpenMP (viz je rozdělen na tři části: 1. OpenMP direktivy - v podstatě se jedná o pokyny pro překladač, jak má paralelizovat určité části programu, 2. funkce OpenMP knihovny - zde je soustředěno několik funkcí, které umožňují např. zjistit počet běžících vláken, číslo aktuálního vlákna atd. 3. systémové proměnné - pomocí nich lze nastavit různé parametry pro běh programu. K tomu, aby bylo možné využít OpenMP standard, je nutné používat překladač, ktreý OpenMP podporuje a pomocí vhodného přepínače tuto podporu zapnout. V současné době se jedná mimo jiné o překladače firmy Intel nebo překladače GNU verze 4.2 a výš OpenMP direktivy OpenMP direktivy se skládají z úvodní části (v jazyce C/C++ je to #pragma omp, ve Fortranu!$omp nebo C$omp), která říká překladači, že bude následovat tělo OpenMP direktivy, a z vlastního těla direktivy. Direktiva parallel Direktiva parallel způsobí rozdělení programu na několik vláken. Tato vlákna provádějí v C/C++ následující příkaz (nebo posloupnost příkazů uzavřených do složených závorek), v jazyce Fortran provádějí následující příkazy až k direktivě end parallel. Jednoduchý příklad této direktivy je uveden ve výpisu 4.1 pro C/C++ a 4.2 pro Fortran. Program přeložíme např. pomocí překladače Intel následovně icc -O -openmp parallel.c a na obrazovce uvidíme výpis parallel.c(5): (col. 1) remark: OpenMP DEFINED REGION WAS PARALLELIZED. 20

22 1 program P a r a l l e l 2 3!$omp p a r a l l e l 4 print, " Ahoj " 5!$omp end p a r a l l e l 6 7 end program P a r a l l e l Výpis 4.2: program openmp/parallel.f90 Ten nás informuje o tom, že příkaz začínající na řádku 5 byl paralelizován. Podobně se překládá i program ve Fortranu a to příkazem resp. ifort -O -openmp parallel.f90 Pro případ GNU překladačů od verze 4.2 je překlad pomocí gcc -O -fopenmp parallel.c gfortran -O -fopenmp parallel.f90 Podívejme se nyní na to, jakým způsobem se vykonává tento program. Po spuštění příkazem./a.out se rozběhne jedno hlavní vlákno zpracovávající náš program. Jakmile toto vlákno dorazí na direktivu parallel, dojde k jeho rozdělení na několik vláken, které vykonávají příkaz pro tisk na obrazovku. Všechna vlákna však vykonávají totéž. To znamená, že na obrazovce bychom měli uvidět tolik kopií 1 výpisu, kolik se spustilo vláken. Jakmile vlákna dojdou na konec paralelního bloku (řádka 8 ve verzi pro C nebo direktiva end parallel ve Fortranu), dojde k zániku všech vláken s výjimkou hlavního, které dále pokračuje v vykonávání zbytku programu. Hlavní vlákno přitom na konci paralelního bloku čeká, než zaniknou ostatní vlákna. V nejjednodušším případě se spouští tolik vláken, kolik má počítač procesorů resp. jader. Počet vláken je však samozřejmě možné ovlivnit a to buď pomocí vhodných direktiv, volání knihovních funkcí, nebo pomocí nastavení systémových proměnných. Tomu se budeme ale věnovat později. K direktivě parallel lze přidat několik klauzulí, které upřesňují chování této direktivy. Jedná se o if(scalar-expression) private(list) firstprivate(list) default(shared none) shared(list) copyin(list) reduction(operator: list) num_threads(integer-expression) Klauzule if způsobí to, že překladač vytvoří dvě varianty bloku příkazů, jednu paralelní a jednu sériovou. Na základě podmínky uvedené v závorce za if se vykonává buď paralelní verze (je-li podmínka splněna), nebo sériová verze. Předpokládejme například, že pracujeme s polem o velikosti n prvků. Pro malé hodnoty n je režie spojená se vznikem a zánikem vláken často vyšší, než zisk a proto se paralelizace nevyplácí. Naproti tomu pro velká n (řekněme větší než 100) může být paralelizace vhodná. V tom případě lze použít direktivu 1 Může se stát, že výpisy budou na obrazovce různě "pomíchané". 21

23 1 #include <s t d i o. h> 2 #include <math. h> 3 4 int main ( ) { 5 int j ; 6 7 #pragma omp parallel private ( j ) 8 { 9 j = 0 ; 10 j = j + 1 ; 11 p r i n t f ( "%i \n ", j ) ; 12 } return 0 ; 15 } Výpis 4.3: program openmp/private.c #pragma omp parallel if(n>100) Klauzule private se seznamem proměnných říká překladači, že má v paralelním bloku vytvořit pro každé vlákno soukromou kopii těchto proměnných. Představme si příklad 4.3. Kdybychom nepoužili klauzuli private, byla proměnná j ve sdílené paměti, tj. společná pro obě vlákna a například pro dvě vlákna by mohl program probíhat zhruba takto: Vlákno 0 Vlákno 1 j := 0 načti j přičti 1 ulož j j := 0 tiskni j načti j přičti 1 ulož j tiskni j To znamená, že vlákno 0 by mohlo vytisknout číslo 0! Všechno by záleželo pouze na načasování běhu jednotlivých vláken a výsledek by byl prakticky nepredikovatelný. Naproti tomu klauzule private(j) vytvoří pro každé vlákno novou kopii proměnné j (řekněme j_0 a j_1) a uvnitř paralelního bloku pracuje s těmito kopiemi. Tedy Vlákno 0 Vlákno 1 vytvoř j_0 j_0 := 0 načti j_0 vytvoř j_1 přičti 1 ulož j_0 j_1 := 0 tiskni j_0 načti j_1 přičti 1 zruš j_0 ulož j_1 tiskni j_1 zruš j_1 22

24 V tomto případě obě vlákna vytisknou výsledek 1. Je však třeba si uvědomit následující skutečnosti: privátní proměnná nemá na začátku paralelního bloku definovanou hodnotu, na konci bloku privátní proměnná zaniká a její hodnota je ztracena. Klauzule shared je opakem klauzule private. Způsobí to, že proměnné zapsané v závorce za klauzulí budou uložené ve sdílené paměti. Poznamenejme, že v C/C++ jsou všechny proměnné deklarované před vstupem do paralelního bloku standardně uvažovány jako shared (pokud se na ně nevztahují jiná pravidla). Proměnné deklarované uvnitř paralelního bloku (buď lokální proměnné uvnitř volaných funkcí nebo proměnné deklarované uvnitř bloku v C++) jsou naprotitomu typu private. Ve Fortranu platí pouze to, že lokální proměnné ve volaných procedurách a funkcích jsou (pokud není uvedeno jinak) private. Klauzule default říká, jak mají být uvažovány proměnné, které nebyly explicitně uvedeny v private nebo shared. V C/C++ jsou přípustné dvě varianty a to default(private) a default(none). Význam první z nich je zřejmý. Druhá varianta způsobí v případě, že nějaká proměnná není explicitně uvedena v shared nebo private, chybu při překladu. Ve Fortranu je k dispozici navíc varianta default(shared). Klauzule firstprivate je určitým rozšířením klauzule private. Vlákna si vytvoří privátní proměnné, do nich však na začátku běhu vlákna překopíruje hodnoty z globálních proměnných odpovídajících jmen. Následující část programu 1 int j, k ; 2 j = 1 ; 3 #pragma omp parallel firstp rivate ( j ) private (k) 4 { 5 k = j } by bylo možné pro dvě vlákna schematicky zapsat jako j = 1; Vlákno 0 Vlákno 1 Vytvoř j_0 Vytvoř j_1 j_0 = j j_1 = j k = j_0 + 1 k = j_ Klauzule reduction vytvoří privátní proměnné, na začátku paralelního bloku je vhodně inicializuje a na konci bloku provede předepsanou redukci mezi sdílenou proměnnou odpovídajícího jména a privatnámi proměnnými. V C/C++ může redukcí být +,,, &,, &&,. Ve Fortranu je to +,,,.and.,.or.,.eqv.,.neqv., max, min, iand, ior, ieor. 1 int j, k ; 2 j = 1 ; 3 #pragma omp parallel reduction(+: j ) 4 { 5 j = 1 ; } 23

25 1 #include <s t d i o. h> 2 3 int main ( ) { 4 5 #pragma omp p a r a l l e l num_threads(10) 6 { 7 p r i n t f ( " Ahoj\n " ) ; 8 } 9 10 return 0 ; 11 } Výpis 4.4: program openmp/parallel-nt.c by bylo možné pro dvě vlákna schematicky zapsat jako j = 1; Vlákno 0 Vlákno 1 Vytvoř j_0 Vytvoř j_1 j_0 = 1 j_1 = j = j + j_0 j = j + j_1 Klauzule num threads umožňuje určit, na kolik vláken se má program rozštěpit, viz příklad 4.4, kde paralelní blok vykonává vždy 10 vláken. Klauzule copyin proměnných. je obdobou klauzule firstprivate, avšak týká se externích proměnných Direktiva for/do Jak již bylo řečeno, direktiva parallel způsobí rozštěpení programu na jednotlivá vlákna. Tato však vykonávají stejný úsek programu. K tomu, abychom vykonávanou práci mezi jednotlivá vlákna rozdělili, však slouží jiné direktivy. Jednou z významných direktiv je direktiva rozdělující iterace v cyklu for (ve Fortranu do). Ta způsobí, že každé vlákno bude provádět pouze určitou část cyklu. Jednoduchá ukázka paralelního cyklu je ve výpisu 4.5. Nejprve dojde k rozštěpení na několik vláken a poté každé vlákno zpracuje určitou část cyklu. Pro dvě vlákna by vlákno 0 mohlo zpracovat iterace pro i = 0 až 4 a vlákno 1 iterace pro i = 5 až 9. Direktiva for resp. do může být opět doplněna následujícími klauzulemi: private(list) firstprivate(list) lastprivate(list) reduction(operator: list) ordered schedule(kind[, chunk_size]) nowait Některé klauzule mají shodný význam jako pro direktivu parallel. Přibývá zde však 24

26 1 #include <s t d i o. h> 2 3 int main ( ) { 4 5 int i ; 6 int x [ 1 0 ] ; 7 8 #pragma omp p a r a l l e l 9 { 10 #pragma omp for 11 for ( i =0; i <10; i ++) 12 x [ i ] = 2 i ; 13 } return 0 ; 16 } Výpis 4.5: program openmp/for.c Klauzule ordered zajistí, že část cyklu označená direktivou ordered (viz později), se bude provádět ve stejném pořadí, jako u sériové verzie programu. Klauzule schedule určuje, jakým způsobem se budou rozdělovat iterace mezi jednotlivá vlákna. K dispozici jsou následující varianty: schedule(static) - iterace jsou rozděleny na zhruba stejně dlouhé úseky jejichž počet je dán počtem vláken. Tyto jsou pak postupně přiřazeny jednotlivým vláknům. Máme-li např. 12 iterací a tři vlákna, pak vlákno 0 bude zpracovávat iterace 0, 1, 2, 3, vlákno 1 iterace 4, 5, 6, 7 a vlákno 2 iterace 8, 9, 10, 11. Je možné použít též variantu se zadanou délkou úseku, např. schedule(static,3). Pak se iterace rozdělí na skupinku po zadané délce a ty se přidělí vláknům. Tedy pro 12 iterací a 3 vlákna by vlákno 0 zpracovávalo iterace 0, 1, 2, 9, 10, 11, vlákno 1 iterace 3, 4, 5, vlákno 2 iterace 6, 7, 8. schedule(dynamic) iterace jsou vláknům přidělovány v pořadí, v jakém je vlákna požadují. V případě, že je zadaána velikost úseku, tedy např. schedule(dynamic,2), jsou iterace opět přiřazovány po úsecích 9jinak se uvažuje délka úseku 1). Jakmile je vláknu přiřazen nějaký usek iterací, vlákno zahájí jeho zpracovaní. Po dokončení si vyžádá od scheduleru další úsek. schedule(guided) iterace jsou opět přiřazovány na základě požadavků jednotlivých vláken (tedy podobně jako u dynamic), délka přiřazovaného úseku však není konstantní a počítá se jako počet nepřiřazených iterací děleno počtem vláken. To znamená, že délka úseku exponencielně klesá. V případě, že je uvedena délka useku, tj. např. schedule(guided,5), budou přiřazovány úseky tak, aby jejich délky (s výjimkou posledního) nebyly menší než zadaná délka. runtime aktualní schedule je určena až při běhu programu pomocí systémových proměnných. Poznamenejme, že standard neříká, jakým způsobem se řeší případ, kdy počet iterací není dělitelný počtem vláken. Tyto situace jsou závislé na implementaci překladače. Klauzule nowait vlákna na sebe po ukončení cyklu standardně čekají. Pokud však uvedeme klauzuli nowait, vlákna opustí paralelní cyklus c okamžiku, kdy dokončí poslední přidělený úsek iterací. 25

27 Další direktivy OpenMP obsahuje samozřejmě ještě další direktivy, nicméně výše uvedené direktivy jsou pro jednoduché paralelní programování zaměřené na práci s poli ve většině případů nejvhodnější. 26

28 Kapitola 5 Dodatek 5.1 Charakteristika počítačů použitých pro měření 5.2 Program pro měření času 27

29 Výpis 5.1: program cache/timer.hpp 1 #i f n d e f TIMER_H 2 #define TIMER_H 3 4 #include <s t r i n g > 5 #include <sys / time. h> 6 #include <s y s / r e s o u r c e. h> c l a s s Timer { 10 p r i v a t e : 11 s t d : : s t r i n g name ; 12 double walltime ; 13 double usertime ; 14 long numberofruns ; 15 bool isrunning ; 16 double lastwalltime ; 17 double lastusertime ; double systemusertime ( ) { 20 struct rusage rusage ; 21 g e t r u s a g e (RUSAGE_SELF, &r u s a g e ) ; 22 return ( double ) ( rusage. ru_utime. tv_sec ) + 23 ( double ) ( r u s a g e. ru_utime. tv_usec ) 1. 0 e 06; 24 } double systemwalltime ( ) { 27 struct timeval timeval ; 28 gettimeofday (& timeval, 0 ) ; 29 return ( double ) ( t i m e v a l. tv_sec ) + ( double ) ( t i m e v a l. tv_usec ) 1. 0 e 06; 30 } p u b l i c : Timer ( ) : numberofruns ( 0 ), walltime ( 0 ), usertime ( 0 ), 36 isrunning ( f a l s e ), name ( " unnamed " ) { } ; Timer ( s t d : : s t r i n g name ) : numberofruns ( 0 ), walltime ( 0 ), usertime ( 0 ), 39 isrunning ( f a l s e ), name ( name ) { } ; ~ Timer ( ) { 42 std : : cout << "TIMER " << name << " : " 43 " u s e r time : " << usertime << " s " << 44 " w a l l time : " << walltime << " s " << 45 " #c a l l s : " << numberofruns << s t d : : e n d l ; 46 } void s t a r t ( ) { 49 isrunning = true ; 50 lastwalltime = systemwalltime ( ) ; 51 lastusertime = systemusertime ( ) ; 52 } void s t o p ( ) { 55 i f ( isrunning ) { 56 isrunning = f a l s e ; 57 usertime += systemusertime ( ) lastusertime ; 58 walltime += systemwalltime ( ) lastwalltime ; 59 numberofruns++; 60 } 61 } double getwalltime ( ) { 64 i f ( isrunning ) 65 return systemwalltime ( ) lastwalltime ; 66 e l s e 67 return walltime ; 68 } } ; #endif 28

30 CPU Pentium-M Core 2 Duo Itanium2 Frekvence [MHz] Velikost [kb] a délka řádky cache [B] L1 32/64 32/64 16/64 L2 2048/ /64 256/64 L3 6144/128 Latence [ns] L L L3 13 RAM Propustnost čtení/zápis [GB/s] L1 22.9/22.9 L2 12.1/4.8 L3 RAM 2.4/ / /1.7 Tabulka 5.1: Charakteristiky počítačů použitých pro měření 29

Úvod do OpenMP. Jiří Fürst

Úvod do OpenMP. Jiří Fürst Úvod do OpenMP Jiří Fürst Osnova: Úvod do paralelního programování Počítače se sdílenou pamětí Základy OpenMP Sdílené a soukromé proměnné Paralelizace cyklů Příklady Úvod do paralelního programování Počítač

Více

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

Programování v C++ 1, 1. cvičení Programování v C++ 1, 1. cvičení opakování látky ze základů programování 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled 1 2 Shrnutí procvičených

Více

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

Paralení programování pro vícejádrové stroje s použitím OpenMP. B4B36PDV Paralelní a distribuované výpočty Paralení programování pro vícejádrové stroje s použitím OpenMP B4B36PDV Paralelní a distribuované výpočty Minulé cvičení: Vlákna a jejich synchronizace v C++ 11... 1 Minulé cvičení: Vlákna a jejich synchronizace

Více

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

Paralelní architektury se sdílenou pamětí typu NUMA. NUMA architektury Paralelní architektury se sdílenou pamětí typu NUMA NUMA architektury Multiprocesorové systémy s distribuovanou pamětí I. úzkým hrdlem multiprocesorů se sdílenou pamětí je datová komunikace s rostoucím

Více

Mělká a hluboká kopie

Mělká a hluboká kopie Karel Müller, Josef Vogel (ČVUT FIT) Mělká a hluboká kopie BI-PA2, 2011, Přednáška 5 1/28 Mělká a hluboká kopie Ing. Josef Vogel, CSc Katedra softwarového inženýrství Katedra teoretické informatiky, Fakulta

Více

Více o konstruktorech a destruktorech

Více o konstruktorech a destruktorech Více o konstruktorech a destruktorech Více o konstruktorech a o přiřazení... inicializovat objekt lze i pomocí jiného objektu lze provést přiřazení mezi objekty v původním C nebylo možné provést přiřazení

Více

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody Dynamická alokace paměti Jazyky C a C++ poskytují programu možnost vyžádat si část volné operační paměti pro

Více

Vector datový kontejner v C++.

Vector datový kontejner v C++. Vector datový kontejner v C++. Jedná se o datový kontejner z knihovny STL jazyka C++. Vektor je šablona jednorozměrného pole. Na rozdíl od "klasického" pole má vector, mnoho užitečných vlastností a služeb.

Více

Algoritmizace a programování

Algoritmizace a programování Algoritmizace a programování Strukturované proměnné Struktura, union Jazyk C České vysoké učení technické Fakulta elektrotechnická A8B14ADP Jazyk C - Strukturované proměnné Ver.1.10 J. Zděnek 20151 Struktura

Více

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole Příkaz switch Příkaz switch provede příslušnou skupinu příkazů na základě hodnoty proměnné (celočíselné

Více

Funkční objekty v C++.

Funkční objekty v C++. Funkční objekty v C++. Funkční objekt je instance třídy, která má jako svou veřejnou metodu operátor (), tedy operátor pro volání funkce. V dnešním článku si ukážeme jak zobecnit funkci, jak používat funkční

Více

VÝUKOVÝ MATERIÁL. Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632 Číslo projektu

VÝUKOVÝ MATERIÁL. Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632 Číslo projektu VÝUKOVÝ MATERIÁL Identifikační údaje školy Vyšší odborná škola a Střední škola, Varnsdorf, příspěvková organizace Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632

Více

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje f1(&pole[4]); funkci f1 předáváme hodnotu 4. prvku adresu 4. prvku adresu 5. prvku hodnotu 5. prvku symbolická konstanta pro konec souboru je eof EOF FEOF feof Správné vytvoření a otevření textového souboru

Více

Pointery II. Jan Hnilica Počítačové modelování 17

Pointery II. Jan Hnilica Počítačové modelování 17 Pointery II 1 Pointery a pole Dosavadní způsob práce s poli zahrnoval: definici pole jakožto kolekce proměnných (prvků) jednoho typu, umístěných v paměti za sebou int pole[10]; práci s jednotlivými prvky

Více

Vícevláknové programování na CPU: POSIX vlákna a OpenMP I. Šimeček

Vícevláknové programování na CPU: POSIX vlákna a OpenMP I. Šimeček Vícevláknové programování na CPU: POSIX vlákna a OpenMP I. Šimeček xsimecek@fit.cvut.cz Katedra počítačových systémů FIT České vysoké učení technické v Praze Ivan Šimeček, 2011 MI-PRC, LS2010/11, Predn.2

Více

2 Datové typy v jazyce C

2 Datové typy v jazyce C 1 Procedurální programování a strukturované programování Charakteristické pro procedurální programování je organizace programu, který řeší daný problém, do bloků (procedur, funkcí, subrutin). Původně jednolitý,

Více

OPS Paralelní systémy, seznam pojmů, klasifikace

OPS Paralelní systémy, seznam pojmů, klasifikace Moorův zákon (polovina 60. let) : Výpočetní výkon a počet tranzistorů na jeden CPU chip integrovaného obvodu mikroprocesoru se každý jeden až dva roky zdvojnásobí; cena se zmenší na polovinu. Paralelismus

Více

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

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 Jednoduché stránkování Operační systémy Přednáška 8: Správa paměti II Hlavní paměť rozdělená na malé úseky stejné velikosti (např. 4kB) nazývané rámce (frames). Program rozdělen na malé úseky stejné velikosti

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Osmé počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 20.11.2017,

Více

Systém adresace paměti

Systém adresace paměti Systém adresace paměti Základní pojmy Adresa fyzická - adresa, která je přenesena na adresní sběrnici a fyzicky adresuje hlavní paměť logická - adresa, kterou má k dispozici proces k adresaci přiděleného

Více

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

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016 ZPRO cvičení 2 Martin Flusser Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague October 17, 2016 Outline I 1 Outline 2 Proměnné 3 Proměnné - cvičení 4 Funkce 5 Funkce

Více

Jazyk C++, některá rozšíření oproti C

Jazyk C++, některá rozšíření oproti C Karel Müller, Josef Vogel (ČVUT FIT) Jazyk C++, některá rozšíření oproti C BI-PA2, 2011, Přednáška 1 1/22 Jazyk C++, některá rozšíření oproti C Ing. Josef Vogel, CSc Katedra softwarového inženýrství Katedra

Více

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15 Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15 KAPITOLA 1 Úvod do programo vání v jazyce C++ 17 Základní pojmy 17 Proměnné a konstanty 18 Typy příkazů 18 IDE integrované vývojové

Více

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

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu: Čtvrtek 8 prosince Pascal - opakování základů Struktura programu: 1 hlavička obsahuje název programu, použité programové jednotky (knihovny), definice konstant, deklarace proměnných, všechny použité procedury

Více

Programování v jazyce C a C++

Programování v jazyce C a C++ Programování v jazyce C a C++ Richter 1 Petyovský 2 1. března 2015 1 Ing. Richter Miloslav, Ph.D., UAMT FEKT VUT Brno 2 Ing. Petyovský Petr, UAMT FEKT VUT Brno C++ Stručná charakteristika Nesdíĺı normu

Více

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

IUJCE 07/08 Přednáška č. 6 Správa paměti Motivace a úvod v C (skoro vždy) ručně statické proměnné o datový typ, počet znám v době překladu o zabírají paměť po celou dobu běhu programu problém velikosti definovaných proměnných jak

Více

Struktura programu v době běhu

Struktura programu v době běhu Struktura programu v době běhu Miroslav Beneš Dušan Kolář Struktura programu v době běhu Vztah mezi zdrojovým programem a činností přeloženého programu reprezentace dat správa paměti aktivace podprogramů

Více

Optimalizace. Optimalizace. Profilování. Gprof. Gcov. Oprofile. Callgrind. Intel Vtune. AMD CodeAnalyst

Optimalizace. Optimalizace. Profilování. Gprof. Gcov. Oprofile. Callgrind. Intel Vtune. AMD CodeAnalyst Optimalizace Optimalizace Profilování Gprof Gcov Oprofile Callgrind Intel Vtune AMD CodeAnalyst Cvičení Hlavní využití počítačů Vývoj paralelního algoritmu je nutné chápat jako optimalizaci. 1. nejprve

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Jedenácté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Gabriela Nečasová, inecasova@fit.vutbr.cz

Více

přetížení operátorů (o)

přetížení operátorů (o) přetížení operátorů (o) - pro vlastní typy je možné přetížit i operátory (tj. definovat vlastní) - pro definici slouží klíčové slovo operator následované typem/znakem operátoru - deklarace pomocí funkčního

Více

Operační systémy. Cvičení 4: Programování v C pod Unixem

Operační systémy. Cvičení 4: Programování v C pod Unixem Operační systémy Cvičení 4: Programování v C pod Unixem 1 Obsah cvičení Řídící struktury Funkce Dynamická alokace paměti Ladění programu Kde najít další informace Poznámka: uvedené příklady jsou dostupné

Více

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech 7 Formátovaný výstup, třídy, objekty, pole, chyby v programech Studijní cíl Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost formátovanému výstupu,

Více

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu } 5. Operátor čárka, - slouží k jistému určení pořadí vykonání dvou příkazů - oddělím-li čárkou dva příkazy, je jisté, že ten první bude vykonán dříve než příkaz druhý. Např.: i = 5; j = 8; - po překladu

Více

Operační systémy. Cvičení 3: Programování v C pod Unixem

Operační systémy. Cvičení 3: Programování v C pod Unixem Operační systémy Cvičení 3: Programování v C pod Unixem 1 Obsah cvičení Editace zdrojového kódu Překlad zdrojového kódu Základní datové typy, struktura, ukazatel, pole Načtení vstupních dat Poznámka: uvedené

Více

24-2-2 PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: 23.7.2013 KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

24-2-2 PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: 23.7.2013 KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1 24-2-2 PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE AUTOR DOKUMENTU: MGR. MARTINA SUKOVÁ DATUM VYTVOŘENÍ: 23.7.2013 KLÍČOVÁ AKTIVITA: 02 UČIVO: STUDIJNÍ OBOR: PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) INFORMAČNÍ TECHNOLOGIE

Více

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

Programování v C++, 2. cvičení Programování v C++, 2. cvičení 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled 1 Operátory new a delete 2 3 Operátory new a delete minule

Více

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

Paralelní a distribuované výpočty (B4B36PDV) Paralelní a distribuované výpočty (B4B36PDV) Branislav Bošanský, Michal Jakob bosansky@fel.cvut.cz Artificial Intelligence Center Department of Computer Science Faculty of Electrical Engineering Czech

Více

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

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 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 Příprava studijního programu Informatika je podporována projektem financovaným z Evropského

Více

Martin Lísal. Úvod do MPI

Martin Lísal. Úvod do MPI Martin Lísal září 2003 PARALELNÍ POČÍTÁNÍ Úvod do MPI 1 1 Co je to paralelní počítání? Paralelní počítání je počítání na paralelních počítačích či jinak řečeno využití více než jednoho procesoru při výpočtu

Více

Koncepce (větších) programů. Základy programování 2 Tomáš Kühr

Koncepce (větších) programů. Základy programování 2 Tomáš Kühr Koncepce (větších) programů Základy programování 2 Tomáš Kühr Parametry a návratová hodnota main Již víme, že main je funkce A také tušíme, že je trochu jiná než ostatní funkce v programu Funkce main je

Více

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace Předmět: Vývoj aplikací Téma: Pole Vyučující: Ing. Milan Káža Třída: EK3 Hodina: 14 Číslo: V/5 Programování v jazyce

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Deváté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 27.11.2017,

Více

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

ZPRO v C Ing. Vít Hanousek. verze 0.3 verze 0.3 Hello World Nejjednoduší program ukazující vypsání textu. #include using namespace std; int main(void) { cout

Více

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

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu VÝUKOVÝ MATERIÁL Identifikační údaje školy Vyšší odborná škola a Střední škola, Varnsdorf, příspěvková organizace Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632

Více

map, multimap - Asociativní pole v C++.

map, multimap - Asociativní pole v C++. map, multimap - Asociativní pole v C++. Jedná se o asociativní pole. V asociativním poli jsou uloženy hodnoty ve tvaru (klíč,hodnota), kde klíč je vlastně "index" prvku. Klíčem může být libovolný objekt,

Více

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; } Pole Kdybychom v jazyce C++chtěli načíst větší počet čísel nebo znaků a všechny bylo by nutné všechny tyto hodnoty nadále uchovávat v paměti počítače, tak by bylo potřeba v paměti počítače alokovat stejný

Více

Šablony, kontejnery a iterátory

Šablony, kontejnery a iterátory 7. října 2010, Brno Připravil: David Procházka Šablony, kontejnery a iterátory Programovací jazyk C++ Šablony Strana 2 / 21 Šablona funkce/metody Šablona je obecný popis (třídy, funkce) bez toho, že by

Více

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write(\nPrumerna teplota je {0}, tprumer); Pole (array) Motivace Častá úloha práce s větším množstvím dat stejného typu o Př.: průměrná teplota za týden a odchylka od průměru v jednotlivých dnech Console.Write("Zadej T pro.den: "); double t = Double.Parse(Console.ReadLine());

Více

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++ Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++ Globální konstantní proměnné Konstantní proměnné specifikujeme s klíčovým slovem const, tyto konstantní proměné

Více

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

Programování v C++ 3, 3. cvičení Programování v C++ 3, 3. cvičení úvod do objektově orientovaného programování 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled Dokončení spojového

Více

Paralelní architektury se sdílenou pamětí

Paralelní architektury se sdílenou pamětí Paralelní architektury se sdílenou pamětí Multiprocesory Multiprocesory se sdílenou pamětí SMP architektury Přístup do paměti OpenMP Multiprocesorové architektury I. Multiprocesor se skládá z několika

Více

Př. další použití pointerů

Př. další použití pointerů Př. další použití pointerů char *p_ch; int *p_i; p_ch = (char *) p_i; // konverze int * na char * 8 int i = 5; int *p_i; p_i = &i; POZOR!!!! scanf("%d", p_i); printf("%d", *p_i); Obecný pointer na cokoliv:

Více

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

Programování v C++ 2, 4. cvičení Programování v C++ 2, 4. cvičení statické atributy a metody, konstruktory 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled Přístupová práva

Více

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

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií 1 Fakulta elektrotechniky a informatiky Katedra softwarových technologií 12. října 2009 Organizace výuky Přednášky Teoretické základy dle normy jazyka C Cvičení Praktické úlohy odpřednášené látky Prostřední

Více

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++ Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++ Třídy v C++ Třídy jsou uživatelsky definované typy podobné strukturám v C, kromě datových položek (proměnných) však mohou obsahovat i funkce

Více

Konstruktory a destruktory

Konstruktory a destruktory Konstruktory a destruktory Nedostatek atributy po vytvoření objektu nejsou automaticky inicializovány hodnota atributů je náhodná vytvoření metody pro inicializaci, kterou musí programátor explicitně zavolat,

Více

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

Vláknové programování část V Vláknové programování část V Lukáš Hejmánek, Petr Holub {xhejtman,hopet}@ics.muni.cz Laboratoř pokročilých síťových technologií PV192 2012 04 17 1/46 Přehled přednášky Open MP 2/46 Open MP Standard pro

Více

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března Polymorfismus Cíle lekce Cílem lekce je vysvětlit význam pojmu polymorfismus jako základní vlastnosti objektově orientovaného programování. Lekce objasňuje vztah časné a pozdní vazby a jejich využití.

Více

Programování II. Návrh programu I 2018/19

Programování II. Návrh programu I 2018/19 Programování II Návrh programu I 2018/19 Osnova přednášky Co víme? Objektový návrh programu. Příklad. Co víme? Třída Třída je popisem objektů se společnými vlastnostmi. class private:

Více

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce.

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce. Vážení zákazníci, dovolujeme si Vás upozornit, že na tuto ukázku knihy se vztahují autorská práva, tzv copyright To znamená, že ukázka má sloužit výhradnì pro osobní potøebu potenciálního kupujícího (aby

Více

Matematika v programovacích

Matematika v programovacích Matematika v programovacích jazycích Pavla Kabelíková am.vsb.cz/kabelikova pavla.kabelikova@vsb.cz Úvodní diskuze Otázky: Jaké programovací jazyky znáte? S jakými programovacími jazyky jste již pracovali?

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Šesté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 6. týden

Více

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

Paralelní výpočetní jádro matematického modelu elektrostatického zvlákňování Paralelní výpočetní jádro matematického modelu elektrostatického zvlákňování Milan Šimko Technická univerzita v Liberci Interní odborný seminář KO MIX 19. prosince 2011 Obsah prezentace 1 MOTIVACE 2 VLÁKNOVÝ

Více

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

Paralelní a distribuované výpočty (B4B36PDV) Paralelní a distribuované výpočty (B4B36PDV) Branislav Bošanský, Michal Jakob bosansky@fel.cvut.cz Artificial Intelligence Center Department of Computer Science Faculty of Electrical Engineering Czech

Více

1. Programování proti rozhraní

1. Programování proti rozhraní 1. Programování proti rozhraní Cíl látky Cílem tohoto bloku je seznámení se s jednou z nejdůležitější programátorskou technikou v objektově orientovaném programování. Tou technikou je využívaní rozhraní

Více

Šablony, kontejnery a iterátory

Šablony, kontejnery a iterátory 11. března 2015, Brno Připravil: David Procházka Šablony, kontejnery a iterátory Programovací jazyk C++ Šablony Strana 2 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array

Více

C++ objektově orientovaná nadstavba programovacího jazyka C

C++ objektově orientovaná nadstavba programovacího jazyka C C++ objektově orientovaná nadstavba programovacího jazyka C (1. část) Josef Dobeš Katedra radioelektroniky (13137), blok B2, místnost 722 dobes@fel.cvut.cz 5. května 2014 České vysoké učení technické v

Více

Abstraktní třídy, polymorfní struktury

Abstraktní třídy, polymorfní struktury Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní třídy, polymorfní struktury BI-PA2, 2011, Přednáška 9 1/32 Abstraktní třídy, polymorfní struktury Ing. Josef Vogel, CSc Katedra softwarového inženýrství

Více

Implementace numerických metod v jazyce C a Python

Implementace numerických metod v jazyce C a Python Fakulta elektrotechnická Katedra matematiky Dokumentace k semestrální práci Implementace numerických metod v jazyce C a Python 2013/14 Michal Horáček a Petr Zemek Vyučující: Mgr. Zbyněk Vastl Předmět:

Více

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

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: 1. lekce 1. Minimální program do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: #include #include int main() { printf("hello world!\n"); return 0; 2.

Více

Algoritmizace a programování

Algoritmizace a programování Algoritmizace a programování Řídicí struktury jazyka Java Struktura programu Příkazy jazyka Blok příkazů Logické příkazy Ternární logický operátor Verze pro akademický rok 2012/2013 1 Struktura programu

Více

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

Mezipaměti počítače. L2 cache. L3 cache Mezipaměti počítače Cache paměť - mezipaměť Hlavní paměť procesoru je typu DRAM a je pomalá. Proto se mezi pomalou hlavní paměť a procesor vkládá menší, ale rychlá vyrovnávací (cache) paměť SRAM. Rychlost

Více

MAXScript výukový kurz

MAXScript výukový kurz MAXScript výukový kurz Díl čtvrtý jazyk MAXScript, část I. Jan Melichar, březen 2008 Jan Melichar (aka JME) strana 1 OBSAH ÚVOD... 4 ZÁKLADNÍ PŘÍKAZY... 5 OPERÁTORY... 6 PROMĚNNÉ... 6 POLE... 7 ZÁVĚREM...

Více

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

Ústav technické matematiky FS ( Ústav technické matematiky FS ) / 35 Úvod do paralelního programování 2 MPI Jakub Šístek Ústav technické matematiky FS 9.1.2007 ( Ústav technické matematiky FS ) 9.1.2007 1 / 35 Osnova 1 Opakování 2 Představení Message Passing Interface (MPI)

Více

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

Assembler - 5.část. poslední změna této stránky: Zpět 1 z 5 19.2.2007 7:52 Assembler - 5.část poslední změna této stránky: 9.2.2007 1. Pseudoinstrukce a direktivy Zpět Kromě instrukcí můžete v Assembleru psát také další konstrukce, které se obšem nepřekládají

Více

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

8 Třídy, objekty, metody, předávání argumentů metod 8 Třídy, objekty, metody, předávání argumentů metod Studijní cíl Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost třídám a objektům, instančním

Více

PHP tutoriál (základy PHP snadno a rychle)

PHP tutoriál (základy PHP snadno a rychle) PHP tutoriál (základy PHP snadno a rychle) Druhá, vylepšená offline verze. Připravil Štěpán Mátl, http://khamos.wz.cz Chceš se naučit základy PHP? V tom případě si prostuduj tento rychlý průvodce. Nejdříve

Více

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

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: 1. lekce 1. Minimální program do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: #include #include int main() { printf("hello world!\n"); return 0; 2.

Více

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

Správa paměti. doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 / Správa paměti doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 / 597 324 213 http://www.cs.vsb.cz/benes Miroslav.Benes@vsb.cz Obsah přednášky Motivace Úrovně správy paměti. Manuální

Více

Množina v C++ (set, multiset).

Množina v C++ (set, multiset). Množina v C++ (set, multiset). Množina je datová struktura, ve které jsou uloženy nějaké prvky. V množině nesmí být dva stejné prvky. Naopak multimnožina může obsahovat i stejné prvky. Nad množinou lze

Více

Standardní algoritmy vyhledávací.

Standardní algoritmy vyhledávací. Standardní algoritmy vyhledávací. Vyhledávací algoritmy v C++ nám umožňují vyhledávat prvky v datových kontejnerech podle různých kritérií. Také se podíváme na vyhledávání metodou půlením intervalu (binární

Více

Odvozené a strukturované typy dat

Odvozené a strukturované typy dat Odvozené a strukturované typy dat Petr Šaloun katedra informatiky FEI VŠB-TU Ostrava 14. listopadu 2011 Petr Šaloun (katedra informatiky FEI VŠB-TU Ostrava) Odvozené a strukturované typy dat 14. listopadu

Více

Úvod do programování - Java. Cvičení č.4

Úvod do programování - Java. Cvičení č.4 Úvod do programování - Java Cvičení č.4 1 Sekvence (posloupnost) Sekvence je tvořena posloupností jednoho nebo více příkazů, které se provádějí v pevně daném pořadí. Příkaz se začne provádět až po ukončení

Více

Procesy a vlákna (Processes and Threads)

Procesy a vlákna (Processes and Threads) ÚVOD DO OPERAČNÍCH SYSTÉMŮ Ver.1.00 Procesy a vlákna (Processes and Threads) Správa procesů a vláken České vysoké učení technické Fakulta elektrotechnická 2012 Použitá literatura [1] Stallings, W.: Operating

Více

Programování v jazyce C a C++

Programování v jazyce C a C++ Programování v jazyce C a C++ Příklad na tvorbu třídy Richter 1 4. prosince 2017 1 Ing. Richter Miloslav, Ph.D., UAMT FEKT VUT Brno Dvourozměrné pole pomocí tříd Zadání Navrhněte a napište třídu pro realizace

Více

POČÍTAČE A PROGRAMOVÁNÍ

POČÍTAČE A PROGRAMOVÁNÍ POČÍTAČE A PROGRAMOVÁNÍ Vícerozměrná statická a dynamická pole, Pole polí Miroslav Vavroušek PPI 08 V1.1 Opakovaní z minulé přednášky Datová pole Jednorozměrná statická datová pole Dynamická datová pole

Více

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

Základy programování. Úloha: Eratosthenovo síto. Autor: Josef Hrabal Číslo: HRA0031 Datum: 28.11.2009 Předmět: ZAP Základy programování Úloha: Eratosthenovo síto Autor: Josef Hrabal Číslo: HRA0031 Datum: 28.11.2009 Předmět: ZAP Obsah 1 Zadání úkolu: 3 1.1 Zadání:............................... 3 1.2 Neformální zápis:.........................

Více

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

Vlákna a přístup ke sdílené paměti. B4B36PDV Paralelní a distribuované výpočty Vlákna a přístup ke sdílené paměti B4B36PDV Paralelní a distribuované výpočty Minulé cvičení: Paralelizace nám může pomoct... 1 Minulé cvičení: Paralelizace nám může pomoct... B4B36PDV: Ale ne všechny

Více

Výčtový typ strana 67

Výčtový typ strana 67 Výčtový typ strana 67 8. Výčtový typ V této kapitole si ukážeme, jak implementovat v Javě statické seznamy konstant (hodnot). Příkladem mohou být dny v týdnu, měsíce v roce, planety obíhající kolem slunce

Více

Příkazy preprocesoru - Před překladem kódu překladačem mu předpřipraví kód preprocesor - Preprocesor vypouští nadbytečné (prázdné) mezery a řádky -

Příkazy preprocesoru - Před překladem kódu překladačem mu předpřipraví kód preprocesor - Preprocesor vypouští nadbytečné (prázdné) mezery a řádky - Příkazy preprocesoru - Před překladem kódu překladačem mu předpřipraví kód preprocesor - Preprocesor vypouští nadbytečné (prázdné) mezery a řádky - Preprocesor je možné ovládat pomocí příkazů - řádky začínající

Více

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky Vyučovací hodina 1vyučovací hodina: Opakování z minulé hodiny Nová látka Procvičení nové látky Shrnutí 5 min 20 min 15 min 5 min 2vyučovací hodiny: Opakování z minulé hodiny Nová látka Procvičení nové

Více

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

PB161 Programování v jazyce C++ Přednáška 4 PB161 Programování v jazyce C++ Přednáška 4 Přetěžování funkcí Konstruktory a destruktory Nikola Beneš 9. října 2017 PB161 přednáška 4: přetěžování funkcí, konstruktory, destruktory 9. října 2017 1 / 20

Více

Množina čísel int stl-set-int.cpp

Množina čísel int stl-set-int.cpp Řetězce, pole a STL V C++ je výhodné pro práci s řetězci použít třídu string, funkce C jsou stále k dispozici cstring, ukazatele a pole lze stále používat stejně, jako v C, použití iterátorů a dalších

Více

Pole a kolekce. v C#, Javě a C++

Pole a kolekce. v C#, Javě a C++ Pole a kolekce v C#, Javě a C++ C# Deklarace pole typ_prvku_pole[] jmeno_pole; Vytvoření pole jmeno_pole = new typ_prvku_pole[pocet_prvku_pole]; Inicializace pole double[] poled = 4.8, 8.2, 7.3, 8.0; Java

Více

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

Programování v C++ 2, 8. cvičení Programování v C++ 2, 8. cvičení návrhový vzor iterátor 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled 1 2 Shrnutí minule procvičené látky

Více

Paralelní architektury se sdílenou pamětí

Paralelní architektury se sdílenou pamětí Paralelní architektury se sdílenou pamětí Multiprocesory Multiprocesory se sdílenou pamětí SMP architektury Přístup do paměti OpenMP Multiprocesorové architektury I. Multiprocesor se skládá z několika

Více

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N Struktura (union) - struktura a union jsou složené typy, které "v sobě" mohou obsahovat více proměnných - struktura obsahuje v každém okamžiku všechny své proměnné, union obsahuje (=je "aktivní") pouze

Více

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.

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. Informatika 10. 9. 2013 Jméno a příjmení Rodné číslo 1) Napište algoritmus pro rychlé třídění (quicksort). 2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus

Více