Implementacja modelu FHP w technologii NVIDIA CUDA
|
|
- Juliusz Janiszewski
- 10 lat temu
- Przeglądów:
Transkrypt
1 Uniwersytet Wrocławski Wydział Fizyki i Astronomii Instytut Fizyki Teoretycznej Sebastian Szkoda Implementacja modelu FHP w technologii NVIDIA CUDA Opiekun: dr hab. Zbigniew Koza, prof. UWr.
2 2
3 Streszczenie Praca niniejsza ma na celu zbadanie możliwości zastosowania najnowszej technologii obliczeń równoległych Nvidia CUDA do przyspieszenia symulacji modelu FHP wykorzystywanego do symulacji przepływu cieczy. W rozdziale pierwszym przedstawiam zarys koncepcji modelowania procesów hydrodynamicznych metodami automatów komórkowych. Prezentuję chronologiczne przejście od pomysłu automatu komórkowego, przez proste próby zastosowania go jako modelu dyskretyzacji przestrzeni i czasu, aż do najbardziej zaawansowanego modelu FHP III wraz z podstawą jego implementacji. Rozdział drugi i trzeci opisują wykorzystaną technologię. Rozdział drugi jest wprowadzeniem do technologii Nvidia CUDA, natomiast rozdział trzeci przedstawia problematykę zastosowania tej technologii do implementacji modelu FHP. Zakończenie rozdziału trzeciego prezentuje osiągnięty wzrost wydajności obliczeń będący miarą jakości rozwiązania podjętego problemu. Ostatni rozdział służy weryfikacji poprawności działania aplikacji będącej wynikiem opracowania badanego zagadnienia przez autora niniejszej pracy. Wyniki skonfrontowane zostały z rozwiązaniami teoretycznymi oraz wynikami doświadczenia wykonanego przez grupę badawczą z Max Planck Institute for Marine Microbiology pod kierunkiem A. Khalili. Zachęcam do lektury. 3
4 4
5 Abstract The aim of the study is to examine the possibility of accelerating FHP algorithms used for hydrodynamics simulations using the newest Nvidia CUDA parallel programming technology. The first chapter presents an introduction to the cellular automata and the concept of using it as a model of discretization of time and space. It leads to the most advanced FHP III model and its implementation. The second and the third chapters describe the technology used in the study. The second chapter is an introduction to the Nvidia CUDA programming model and the third one explains how to use it for FHP implementation. The GPU over CPU speedup is presented and discussed. The last chapter verifies the correctness of the FHP algorithm implemented for this study. The results were compared to the theoretical solution of the Navier-Stokes equations and experimental results obtained by the group from Max Planck Institute for Marine Microbiology (A. Khalili). 5
6
7 Spis treści 1 Model Wstęp Automat Komórkowy (CA) HPP FHP Klasyfikacja modeli FHP Przeszkody Implementacja Węzeł Sieć Krok symulacji Technologia Wstęp CUDA Kernel Model sieci bloków wątków Nowe typy danych Zmienne wbudowane Pamięć urządzenia Wydajność Model FHP w technologii CUDA Implementacja Wydajność Poprawność implementacji Porównanie z teorią Porównanie z doświadczeniem Galeria 43 Bibliografia 47 7
8
9 1 Model 1.1 Wstęp Mechanika płynów jest działem fizyki zajmującym się między innymi badaniem ruchu cieczy i gazów oraz oddziaływaniem tych ośrodków na opływane przez nie ciała stałe. Pierwsze próby matematycznego ujęcia ruchu płynów podjął w XVIw. Galileusz, jego pracę rozwijali L. Euler i D. Bernoulli, lecz dopiero w XIX w. dzięki pracy naukowej H. Naviera oraz G. Stokesa podano równania opisujące ruch płynów, nazwane od ich nazwisk równaniami Naviera-Stokesa (N-S). Osiągnięcie to nie jest niestety w pełni satysfakcjonujące, gdyż ponad sto lat później nadal nie dość, że nie potrafimy podać analitycznego rozwiązania równań N-S, to nie jesteśmy nawet w stanie udowodnić czy szukane rozwiązanie istnieje. Problem rozwiązania równania N-S w 2000 r. został ogłoszony jako jeden z siedmiu najważniejszych dla nauki problemów matematycznych nazwanych Problemami Milenijnymi [1]. Mimo wszystko powszechnie korzysta się z tych równań rozwiązując pewne jego przypadki metodami przybliżonymi. Główne metody przybliżone to: numeryczne rozwiązywanie równań różniczkowych (FDM, FEM, FVM), dynamika molekularna (MD) oraz gaz sieciowy automatów komórkowych (LGCA). 1.2 Automat Komórkowy (CA) W latach czterdziestych dwudziestego wieku matematycy John Von Neumann i Stanisław Ulam zaproponowali model dyskretyzacji przestrzeni i czasu. Przestrzeń sprowadzili do układu sąsiadujących komórek, z których każda może przyjąć określony stan. Ewolucja układu w czasie polega na symultanicznej zmianie stanu wszystkich komórek według określonych zasad. Podejście takie nazwano automatem komórkowym. Automaty komórkowe wykorzystywane do symulacji zjawisk hydrodynamicznych nazywane są gazami sieciowymi od angielskich akronimów: LGA lattice gas automata lub LGCA lattice gas cellular automata. 9
10 ROZDZIAŁ 1. MODEL 1.3 HPP Model HPP [2] (skrót od nazwisk Hardy, de Pazzis, Pomeau) jest pierwszym (1973 r.) i najprostszym modelem gazu sieciowego. Obecnie nie ma praktycznych zastosowań, jest jednak dobrym materiałem na początek nauki o modelowaniu metodami LGCA. W modelu tym mamy do czynienia z siecią kwadratową, w której węzłach umieszczamy od zera do czterech cząstek. Każda cząstka ma jeden z czterech kierunków (N,E,S,W) oraz prędkość 1js/ t [jednostka sieci / krok czasowy]. Cząstki w węźle mają różne kierunki. Przykładowy układ widzimy na rysunku 1.3. Ewolucja układu przebiega w dwóch krokach: 1) Ruch przesuwamy każdą z cząstek o jeden węzeł zgodnie z wektorem jej prędkości. 2) Kolizja do nowo powstałego układu stosujemy reguły jak na rysunku 1.2. Rysunek 1.1: Przykładowy stan sieci w modelu HPP. Inne układy cząstek w węzłach podczas kolizji ignorujemy. Reguły zderzeń są dobrane w ten sposób, by gwarantowały spełnienie zasady zachowania masy oraz zasady zachowania pędu. 10
11 1.4. FHP 1.4 FHP Rysunek 1.2: Reguły kolizji w modelu HPP. FHP [3] [4] [5] (skrót od nazwisk Frisch, Hasslacher, Pomeau) jest udoskonaloną wersją modelu gazu sieciowego HPP, w której sieć kwadratową zamieniono na trójkątną i wprowadzono bardziej skomplikowane zasady kolizji. W modelu mamy do czynienia z siecią trójkątną, w której węzłach umieszczamy od zera do siedmiu cząstek. Każda cząstka ma jeden z sześciu kierunków (NW, NE, E, SE, SW, W) oraz prędkość 1js/ t [jednostka sieci / krok czasowy]. Cząstki w węźle mają różne kierunki. W pewnych wariantach modelu FHP stosuje się również cząstki nieruchome. Przykładowy układ przedstawia rysunek 1.3. Ewolucja układu przebiega w dwóch krokach: 1) Ruch przesuwamy każdą z cząstek o jeden węzeł zgodnie z wektorami prędkości. 2) Kolizja do nowo powstałego układu stosujemy reguły zderzeń. Rysunek 1.3: Przykładowy stan sieci w modelu FHP. 11
12 ROZDZIAŁ 1. MODEL Klasyfikacja modeli FHP Modele FHP klasyfikujemy ze względu na zastosowane reguły kolizji: FHP 1 - kolizje dwucząsteczkowe, symetryczne oraz trój-cząsteczkowe symetryczne. FHP 2 - jak wyżej, plus trójcząsteczkowe niesymetryczne oraz kolizje z nieruchomą cząstką. FHP 3 - wszystkie powyższe plus kolizje czterocząsteczkowe. Wszystkie warianty modelu FHP spełniają zasadę zachowania masy i pędu. Różne reguły zderzeń powodują różnice wyników na poziomie makroskopowym. Każdy z modeli FHP oddaje inny zakres współczynnika lepkości. Wartości współczynnika lepkości możliwe do osiągnięcia w symulacji zmniejszają się wraz ze zwiększeniem ilości zderzeń. 1.5 Przeszkody W modelu FHP przez przeszkodę należy rozumieć nieruchomą cząstkę, która podczas kolizji każdą cząsteczkę, która na nią wpadła, odbija pod kątem 180. Zderzenie pojedynczej cząstki z przeszkodą pokazuje rysunek
13 1.6. IMPLEMENTACJA stan początkowy zderzenie odbicie stan końcowy 1.6 Implementacja Węzeł Rysunek 1.4: Odbicie od przeszkody. W modelu FHP mamy do czynienia z cząsteczkami mogącymi przyjąć jeden z 6 kierunków, cząsteczką nieruchomą oraz przeszkodą. Daje to osiem możliwych stanów węzła, które mogą zachodzić jednocześnie. Wygodnym sposobem reprezentacji stanu węzła jest ciąg ośmiu bitów, w którym każdy bit odpowiada istnieniu (1) lub nieistnieniu (0) cząstki w określonym stanie, jak na rysunku 1.5. W większości języków programowania, ciąg ośmiu bi- Rysunek 1.5: Reprezentacja stanu węzła. Powyższy układ bitów ( ) 2 odpowiada liczbie dziesiętnej (19) 10. tów wykorzystywany jest do reprezentacji znaków (ang. char). Stąd węzeł w stanie jak na rysunku 1.5 można zaimplementować jak na listingu 1.1: 1 unsigned char node = 19 ; Listing 1.1: Implementacja węzła. 13
14 ROZDZIAŁ 1. MODEL Aby uzyskać pełną kontrolę nad stanem węzła, musimy mieć możliwość wykonywania operacji ustawienia (listing 1.2), usunięcia (listing 1.3) oraz sprawdzenia stanu (listing 1.4) dowolnego bitu. Listing 1.2: Ustawianie bitu na pozycji (pos) w węźle (node) 1 void b i t S e t ( unsigned char& node, int pos ) { 3 val = (1 << ( pos ) ) ; } Listing 1.3: Usuwanie bitu z pozycji (pos) w węźle (node) void b i t C l r ( unsigned char& node, int pos ) 2 { val &= not (1 << ( pos ) ) ; 4 } Listing 1.4: Sprawdzanie bitu na pozycji (pos) w węźle (node) bool bittst ( unsigned char& node, int pos ) 2 { return ( ( val ) & (1 << ( pos ) ) ) ; 4 } Sieć Sieć trójkątna wymaga specjalnego potraktowania przez programistę, gdyż musi być zrzutowana na tablicę, która zwykle utożsamiana jest z siecią kwadratową. Na rysunku 1.6 widzimy, że położenia węzłów naturalnie przechodzą w sieć kwadratową, można więc zaimplementować sieć trójkątną jako tablicę typu char o wymiarze szerokość (w) na wysokość (h), stąd: unsigned char s i e c [w*h ] ; Listing 1.5: Sieć węzłów. 14
15 1.6. IMPLEMENTACJA Rysunek 1.6: Zrzutowanie sieci trójkątnej na kwadratową. W przypadku reprezentacji sieci dwuwymiarowej za pomocą tablicy jednowymiarowej dostęp do węzła (i, j), uzyskujemy samodzielnie przeliczając indeksy, dlatego wygodnie jest posłużyć się następującą dyrektywą preprocesora: Listing 1.6: Dyrektywa preprocesora przeliczająca indeksy tablicy 2D na indeksy tablicy 1D. 1 #define pos ( i, j ) (w* j+i ) Dzięki niej zamiast stosować zapis dla tablicy dwuwymiarowej: 1 s i e c [ i ] [ j ] ; piszemy: Listing 1.7: Odczyt z tablicy 2D. Listing 1.8: Odczyt z tablicy 1D traktowanej jak tablica 2D. 1 s i e c [ pos ( i, j ) ] ; Krok symulacji Ruch Ruch polega na propagacji cząsteczek z każdego węzła do węzłów sąsiednich. Czyli dla każdego węzła musimy sprawdzić stan każdego z bitów, a w przy- 15
16 ROZDZIAŁ 1. MODEL Rysunek 1.7: Zmiana stanu z (21) 10 = ( ) 2 na ( ) 2 = (42) 10. padku zastania stanu 1 przesuwamy cząstkę w odpowiednim kierunku. Do implementacji ruchu nie wystarczy jedna sieć, gdyż przesunięcie cząsteczki z jednego węzła do sąsiedniego zmieniłoby dane zapisane w tym drugim, stąd wniosek, że należy użyć dwóch sieci. Pierwsza z nich przechowuje aktualny stan układu, z niej pobieramy dane potrzebne do przesunięcia cząstek, lecz przesuniętą cząstkę zapisujemy w drugiej sieci. W następnym kroku sieci zamieniają się rolami. Zderzenia Po wykonaniu przesunięć cząstek, musimy ponownie sprawdzić stan każdego z węzłów, tym razem jednak nie patrzymy na stan konkretnych bitów, a na stan całego węzła i postępujemy zgodnie z regułami opisanymi w punkcie Aby czynność powyższą wykonywać sprawnie, warto wpisać wszystkie możliwe stany węzła w tablicę. Ilość dopuszczalnych stanów to 2 8 = 256, co jest dość skromnym obciążeniem pamięci. Tablica zawierająca stany węzłów powinna reprezentować odwzorowanie przekształcające zastany stan na odpowiadający mu stan zgodny z regułami z rozdziału Czyli przykładowo pod indeksem 21 tablicy ma znajdować się wartość 42 ponieważ (21) 10 = ( ) 2 ma przekształcić się na ( ) 2 = (42) 10 zgodnie z regułą z rysunku 1.7. Natomiast pod indeksem 42 ma znajdować się wartość 21, ponieważ reguła ta stosuje się w dwie strony. Problematyczne w takim podejściu są reguły kolizji zależne od zmiennej losowej, gdyż powyższa tabelaryzacja reguł tego przypadku nie uwzględnia. Rozwiązaniem może być zastosowanie dwóch tablic stanów, jednej dla przypadku zmiennej losowej 0 < p 0.5, drugiej dla 0.5 < p 1. Wtedy przed każdą zmianą stanu węzła konieczne jest losowanie wartości losowej p : 0 < p 1 z rozkładu jednostajnego. 16
17 2 Technologia 2.1 Wstęp Od początku istnienia komputerów klasy PC producenci prześcigają się w udoskonalaniu ich jednostek obliczeniowych. Przez wiele lat podstawowym sposobem zwiększenia mocy obliczeniowej było zwiększenie częstotliwości zegara procesora, czyli ilości elementarnych operacji, które procesor może wykonać w czasie jednej sekundy. Do niedawna nic nie stało na przeszkodzie, aby tak właśnie rozumieć wzrost mocy obliczeniowej komputerów. Częstotliwości zegarów rosły od khz, przez MHz do GHz i osiągnęły wartości 4 GHz po czym spadły do obecnego 1 stanu, jakim jest wartość z przedziału 2-3 GHz. Na przeszkodzie dalszemu rozwojowi stanęło ciepło, dokładniej problem z jego odprowadzaniem. Przy dużych częstotliwościach zegarów, procesory produkują takie ilości energii cieplnej, że chłodzenie powietrzem nie wystarcza, prowadzi do przegrzania i uszkodzenia sprzętu. Niestety, inne techniki chłodzenia są bardzo drogie, co zmusiło producentów do spojrzenia na problem z innej strony. Aktualnie za panaceum uważa się obliczenia równoległe, czyli takie w których staramy się rozwiązać problem, dzieląc go na niezależne fragmenty, wykonywane jednocześnie przez wiele jednostek obliczeniowych. Dla takich potrzeb powstały procesory wielordzeniowe, w których zamiast zwiększać taktowanie zegara jednej jednostki obliczeniowej, wstawia się kilka wolniejszych jednostek, działających niezależnie. Nie jest to jednak idealne rozwiązanie. W algorytmach, w których czynności muszą być wykonywane po kolei, dołożenie dodatkowych jednostek liczących nie daje żadnego przyspieszenia obliczeń. Mimo istnienia klasy algorytmów trudnych do zrównoleglenia, grupa tych podatnych jest na tyle duża, że jest o co walczyć. W świecie procesorów komputerowych, wielordzeniowość jest dość nowym tematem, lecz w świecie procesorów graficznych, stosowana jest o wiele dłużej. Wynika to między innymi z tego, że algorytmy stosowane w grafice są bardzo podatne na zrównoleglanie. Nie jest więc dziwne, że producenci kart graficznych mają duże doświadczenie w produkcji jednostek wielordzeniowych, tzw r 17
18 ROZDZIAŁ 2. TECHNOLOGIA Graphics Processing Unit (GPU). Do niedawna moc obliczeniowa ukryta w kartach graficznych wykorzystywana była tylko w zastosowaniach graficznych, jednak w roku 2006 firma ATI Technologies i niespełna rok później firma NVIDIA udostępniły konkurencyjne w stosunku do siebie technologie, umożliwiające wykonywanie dowolnych obliczeń przy użyciu procesorów kart graficznych. Z różnych względów, prowadzenie w wyścigu o prym w technologii obliczeń na GPU objęła firma NVIDIA z technologią CUDA. Urządzenia zgodne z tą technologią to karty graficzne wyposażone w procesory NVI- DIA GeForce serii 8, 9, 200 i 400 oraz sprzęt specjalistyczny NVIDIA Tesla i Quadro. 2.2 CUDA CUDA (Compute Unified Device Architecture) jest środowiskiem rozszerzającym język C o zestaw funkcji i dyrektyw pozwalających na implementowanie algorytmów wykonywanych równolegle z wykorzystaniem procesorów oraz pamięci karty graficznej. Program pisany w taki sposób można podzielić na dwie części, część host wykonywaną na procesorze głównym komputera (CPU) i wykorzystującą pamięć główną RAM komputera oraz część device wykonywaną na karcie graficznej z użyciem jej pamięci i procesorów (GPU). Część wykonywana na CPU może być tworzona w językach C, C++, Java, Python i wielu innych, natomiast część wykonywana na GPU, musi być napisana w języku C/C++ wraz z jego rozszerzeniami dołączonymi przez producenta za pośrednictwem środowiska programistycznego. Ze względu na wydajność najlepszym wyborem dla części host jest C lub C Kernel Część device składa się z tzw. kerneli, czyli funkcji wywoływanych z CPU, lecz wykonywanych równolegle na urządzeniu. Sposób wykonywania kerneli nazwany został SIMT (single-instruction, multiple-thread) czyli pojedyncza instrukcja, wiele wątków. W technologii SIMT pojedyncze wywołanie kernela powoduje stworzenie N 1 wątków wykonujących te same zadania, lecz operujących na innych danych. Kernele różnią się od zwykłych funkcji języka C słowem kluczowym global, np: 18
19 2.2. CUDA Listing 2.1: Przykład kernela 1 g l o b a l void funkcja ( int * a ){ } ; oraz sposobem wywołania. W kodzie CPU kernel z listingu 2.1 wywołujemy, używając nowej składni: <<<... >>>. 1 int main ( ) { 3 funkcja <<<N,M>>>(A) ; } Listing 2.2: Wywołanie funkcji typu kernel. Dyrektywa <<<... >>> odpowiada za konfigurację wywołania funkcji na urządzeniu. Na konfigurację wywołania składają się cztery wielkości: <<<gridds,blockds,sharedms,streamno>>> ˆ gridds definiuje wymiar i rozmiar sieci bloków wątków (Rozdział 2.2.2), ˆ blockds definiuje wymiar i rozmiar bloku wątków, ˆ sharedms argument opcjonalny, ustala rozmiar pamięci współdzielonej w pojedynczym bloku wątków, ˆ streamno argument opcjonalny, definiuje numer strumienia wątków. Najważniejsze z nich są obowiązkowe parametry gridds i blockds. Służą one do definiowania abstrakcyjnego modelu sieci wątków. Pozostałe parametry mają ustalone wartości domyślne i rzadko są ustawiane ręcznie Model sieci bloków wątków Model ten służy do zarządzania równoległym wykonaniem funkcji typu kernel. Dzieli on wątki na bloki o równych rozmiarach, każdy blok wątków wykonywany jest na innym procesorze wielordzeniowym tzw. multiprocesorze. Natomiast sieć jest zbiorem bloków wątków. Zarówno sieć jak i bloki mogą być tworami jedno-, dwu- lub trójwymiarowymi. Realizację przykładowego podziału wątków widzimy na rysunku 2.1, gdzie 72 wątki podzielone zostały na sześć bloków po 12 wątków każdy. Sieć bloków zdefiniowana została jako sieć dwuwymiarowa o szerokości 3 i wysokości 2, natomiast blokom nadano rozmiar 4 na 3. Parametry gridds i blockds są zmiennymi typu dim3. Typ ten należy do rozszerzenia języka C i służy do definiowania rozmiarów. Implementacja sytuacji z rysunku 2.1 wyglądałaby tak: 19
20 ROZDZIAŁ 2. TECHNOLOGIA Rysunek 2.1: Przykładowy model sieci bloków wątków. Źródło: [6]. 20
21 2.2. CUDA Listing 2.3: Implementacja sieli bloków wątków z rysunku 2.1 int main ( ) 2 { dim3 dimgrid ( 3, 2 ) ; 4 dim3 dimblock ( 4, 3 ) ; funkcja <<<dimgrid, dimblock>>>(a) ; 6 } Nowe typy danych Rozszerzenie języka C wprowadza więcej nowych typów, nazywanych typami wektorowymi. Prawie każdy z podstawowych typów danych języka C ma swój odpowiednik z sufiksem 1, 2, 3 lub 4. Przykładowo: int2, char4, float3. Typy te są strukturami języka C o składowych (x),(x,y),(x,y,z) lub (x,y,z,w) w zależności od ich wymiaru. Zmienne wektorowe tworzone są funkcją make typ, gdzie typ jest typem wektorowym, np: Listing 2.4: Tworzenie zmiennej typu float3. f l o a t 3 x = make float3 ( float x, float y, float z ) Dokładne wyszczególnienie wszystkich nowych typów znajdziemy w [6] Zmienne wbudowane Aby wewnątrz kernela rozpoznać, w którym miejscu sieci lub bloku jesteśmy, mamy do dyspozycji wbudowane zmienne: ˆ threadidx - zmienna typu uint3, na pozycjach (x,y,z) przechowuje indeksy wątku, w którym aktualnie jesteśmy, ˆ blockidx - zmienna typu uint3, na pozycjach (x,y,z) przechowuje indeksy bloku, w którym aktualnie jesteśmy, ˆ blockdim - zmienna typu dim3, zawierająca rozmiar bloku zdefiniowany przy wywołaniu kernela, ˆ griddim - zmienna typu dim3 jest zmienną zawierającą rozmiar sieci zdefiniowany przy wywołaniu kernela. 21
22 ROZDZIAŁ 2. TECHNOLOGIA Pamięć urządzenia Karty graficzne firmy Nvidia dysponują aż pięcioma różnymi rodzajami pamięci. Różnią się one przede wszystkim prędkością, rozmiarem, rodzajami dostępu i czasem życia danych w nich umieszczonych. Pamięć globalna Głównym obszarem pamięci jest pamięć globalna. Pamięć ta jest po prostu pamięcią RAM karty graficznej. Dostęp do niej rozumiany jako odczyt i zapis mają wszystkie wątki oraz CPU. Przepustowość pamięci globalnej na urządzeniu to dla serii GTX to od 100GB/s do 180GB/s a rozmiary to od 0.5 GB do 4 GB. Aby skopiować dane z pamięci komputera do globalnej pamięci karty, musimy skorzystać ze specjalnego zestawu funkcji. Funkcje te wywoływane są w części kodu hosta. Stworzone zostały jako odpowiedniki funkcji języka C: malloc(), memcpy(), free(). Posiadają takie same nazwy jak w C, jednak poprzedzone są prefiksem cuda. ˆ cudamalloc (void** devptr, size t size) funkcja jako pierwszy argument przyjmuje wskaźnik devptr, który po jej wywołaniu będzie wskazywał na obszar pamięci o rozmiarze size podanym w bajtach jako drugi jej argument. ˆ cudamemcpy(void* dst,const void* src, size t size, enum cudamemcpykind kind) kopiuje obszar pamięci o rozmiarze size z miejsca src pamięci w miejsce dst. Argument kind może przyjąć wartości: cudamemcpyhosttohost kopiowanie z host na host czyli jak zwykłe memcpy(), cudamemcpyhosttodevice kopiowanie z host na device, cudamemcpydevicetohost kopiowanie z device na host, cudamemcpydevicetodevice kopiowanie z device na device. ˆ cudafree(void* devptr) zwalnia obszar pamięci wskazywany przez devptr. Są to podstawowe funkcje do zarządzania pamięcią, każda z nich zwraca warość typu wyliczeniowego cudaerror zawierającą informację o powodzeniu 22
23 2.2. CUDA operacji lub kod błędu. Listing 2.5: Przykładowy kod kopiujący tablicę z CPU na GPU. 1 int * d e v i c e p o i n t e r ; int * h o s t p o i n t e r ; 3 int main ( ) 5 { int s i z e = 1000; 7 h o s t p o i n t e r = new int [ s i z e ] ; 9 cudamalloc ( ( void * *) &d e v i c e p o i n t e r, \ s i z e * sizeof ( int ) ) ; 11 cudamemcpy( d e v i c e p o i n t e r, h o s t p o i n t e r, \ s i z e * sizeof ( int ),\ 13 cudamemcpyhosttodevice ) ; // } cudafree ( d e v i c e p o i n t e r ) ; Operując na tablicach wielowymiarowych należy pamiętać, że przestrzeń adresów pamięci na urządzeniu nie ma nic wspólnego ze swoim odpowiednikiem na CPU i vice versa, więc kopiowanie wskaźników z CPU na GPU nie ma sensu. W przypadku, gdy chcemy używać tablic wielowymiarowych, których rozmiar nie jest znany podczas kompilacji, najłatwiej jest definiować je jako jednowymiarowe, a następnie ręcznie przeliczać indeksy, jak w punkcie Pamięć lokalna Pamięć lokalna jest pamięcią prywatną dla każdego wątku. Pod względem parametrów jest identyczna z pamięcią globalną. Służy do przechowywania zmiennych, które w normalnym kodzie C powinny znajdować się rejestrach, lecz ze względu na niewielki rozmiar pamięci rejestrów urządzenia, w przypadku gdy zmienne te zajmują zbyt wiele miejsca, kompilator automatycznie przenosi część z nich do pamięci lokalnej. Rozmiar pamięci rejestrów to 8192 bajtów na multiprocesor. 23
24 ROZDZIAŁ 2. TECHNOLOGIA Pamięć stała Na urządzeniu znajdują się 64 KB tego typu zasobów z czego 8 KB jest buforowanych w pamięci cache. W praktyce, jeśli nie wyjdziemy poza ilość podlegającą buforowaniu, pamięć stała jest bardzo szybkim rodzajem pamięci. Niestety, możliwość zapisania w niej danych mamy tylko przez CPU, więc w kodzie należy traktować ją jako pamięć tylko do odczytu. Efektywne jej wykorzystanie polega na umiejscowieniu w niej wartości nie zmieniających się podczas działania programu. Obiekty przechowywane w pamięci stałej deklarujemy słowem kluczowym constant, a ich rozmiar musi być znany już podczas kompilacji. Aby zapisywać dane w tym obszarze, należy wykorzystać funkcję cudamemcpytosymbol(const char* symbol,const void* src,size t count,size t offset,enum cudamemcpykind kind). Funkcja ta różni się od funkcji opisywanych wcześniej tym, że zmienna symbol może być nazwą wskaźnika wskazującego zarówno na obszar pamięci globalnej jak i stałej. Przykładowy kod kopiujący tablicę z host do constant mamory może wyglądać następująco: Listing 2.6: Kopiowanie tablicy z CPU do pamięci stałej urządzenia. 1 c o n s t a n t float t a b l i c a [ ] ; 3 int main ( ) { 5 h o s t p o i n t e r = new int [ ] ; cudamemcpytosymbol ( t a b l i c a, h o s t p o i n t e r, \ 7 256* sizeof ( int ), 0, cudamemcpyhosttodevice ) //... 9 } Pamięć współdzielona Pamięć współdzielona jest to rodzaj pamięci umiejscowiony na multiprocesorze (on-chip memory), co powoduje, że ma wydajność identyczną z rejestrami. Pamięć ta jest wspólna dla wątków z tego samego bloku, a na każdy blok przypada jej 16 KB. Czas życia danych w niej zawartych jest równy czasowi życia bloku wątków. Wynika stąd potrzeba wczytywania do niej danych przy każdym uruchomieniu kernela. Według producenta, latencja (czyli czas dostępu) odczytów z pamięci współdzielonej może być nawet 100Ömniejsza niż latencja odczytów z pamięci globalnej. Najefektywniejsze jej wykorzystanie 24
25 2.2. CUDA polega na zastąpieniu komunikacji z pamięcią główną przez komunikację z pamięcią współdzieloną. Zmienne w pamięci współdzielonej definiujemy w kernalach za pomocą dyrektywy shared : Listing 2.7: Tworznie tablicy w pamięci współdzielonej. 1 g l o b a l void funkcja ( int * a ) { 3 s h a r e d int t a b l i c a [ 1 0 ] [ 1 0 ] ; //... 5 } ; Pamięć tekstur Jest to obszar pamięci stworzony z myślą o grafice, jest buforowany i optymalizowany sprzętowo pod kątem odczytów sąsiednich fragmentów pamięci przez sąsiednie wątki. Oczywiście producent w żaden sposób nie ogranicza dostępu do tych zasobów, więc je również można wykorzystać do obliczeń Wydajność Aby uzyskać maksymalną wydajność, przede wszystkim należy skupić się na znalezieniu jak najefektywniejszych możliwości zrównoleglenia jak największej części kodu sekwencyjnego. Mając do dyspozycji bardzo szybkie rodzaje pamięci, należy w miarę możliwości używać tych, których przepustowość jest największa. Bardzo niewskazane jest pisanie programów, w których często przesyłamy duże ilości danych między CPU a GPU. Przepustowość łącza PCI-Express to maksymalnie ok. 10 GBps, co przy 100 GBps przepustowości najwolniejszego rodzaju pamięci urządzenia jest wynikiem dość słabym. Praktyka pokazuje, że zamiast teoretycznych 10 GBps szyna PCI-Express przeciętnie daje przepustowości od 1 GBps do 4 GBps w zależności od jakości płyty głównej. Wiemy już, że na urządzeniu znajdują się bardzo szybkie rodzaje pamięci tj. pamięć współdzielona, stała oraz pamięć tekstur. Niestety ich zasoby są dość skąpe, rzędu 10KB na blok wątków, co nie daje możliwości swobodnego ich użycia, jaki znamy z programowania na CPU. Jednak umiejętne wykorzystanie i zastępowanie nimi najwolniejszej pamięci globalnej powoduje radykalne zwiększenie wydajności. Najlepszym zamiennikiem pamięci globalnej 25
26 ROZDZIAŁ 2. TECHNOLOGIA jest pamięć współdzielona. Jest ona bardzo szybka i jest jej względnie dużo, po 16KB na multiprocesor. Aby działała najwydajniej, należy tak pisać algorytmy, by wyeliminować tzw. konflikty pamięci, czyli aby dwa wątki nie prosiły kontrolera pamięci o dostęp do tego samego zasobu równocześnie. W przypadku, gdy mamy do czynienia z często wykorzystywanymi wartościami stałymi, warto umieścić je w pamięci stałej, jest ona równie szybka jak pamięć współdzielona, lecz z poziomu GPU jest pamięcią tylko do odczytu, co znacznie zawęża klasę jej zastosowań. Poza odpowiednim wykorzystaniem pamięci, ważne jest też odpowiednie wywołanie kernela. Producent zwraca uwagę na to, iż rdzenie multiprocesora działające zgodnie z modelem SIMT muszą wykonywać tę samą instrukcję, być może na różnych danych. W takim razie, jeśli np. instrukcjami warunkowymi spowodujemy, że któryś z rdzeni będzie musiał wykonać zadania dodatkowe, to inne będą na niego czekać, co spowoduje drastyczny spadek wydajności obliczeń. 26
27 3 Model FHP w technologii CUDA 3.1 Implementacja Pomysł na implementację modelu FHP w technologii CUDA sprowadza się do odpowiedniego podziału sieci modelu na mniejsze fragmenty odpowiadające blokom wątków, tak aby każdemu wątkowi odpowiadał dokładnie jeden węzeł. Następnie wykonujemy kroku symulacji przesuwamy cząstki i wykonujemy zderzenia. Pierwszym, intuicyjnym podejściem jest podział jak na rysunku 3.1. Podejście takie bardzo dobrze sprawdza się w implementacji Rysunek 3.1: Intuicyjny podział sieci na bloki. zderzeń, każdemu wątkowi przyporządkowano bowiem dokładnie jeden węzeł, w którym wątek ten zmienia zastany stan według tablicy reguł zderzeń. Nie ma mowy o konfliktach pamięci, zarówno odczyt z pamięci globalnej jak i zapis do niej wykonywany jest raz. 27
28 ROZDZIAŁ 3. MODEL FHP W TECHNOLOGII CUDA Listing 3.1: Implementacja kernela wykonującego zderzenia. 1 g l o b a l void z d e r z e n i a ( int * siecpo, int * seeds dev ) { 3 int i = blockdim. x * blockidx. x + threadidx. x ; int j = blockdim. y * blockidx. y + threadidx. y ; 5 7 int index = wconst* j+i ; i f ( getrandomdouble ( seeds dev, index ) <0.5) 9 siecpo [ index ] = tablicalp devc [ siecpo [ index ] ] ; else 11 siecpo [ index ] = tablicarp devc [ siecpo [ index ] ] ; } Ze względu na to, iż funkcja ta jest dość krótka, dla zwiększenia wydajności, warto dać jej dodatkowe obowiązki, które nie będą wymagały komunikacji między blokami wątków np. wykonywanie pomiarów wielkości fizycznych. Taki model podziału na bloki nie sprawdzi się jednak w przypadku implementacji funkcji odpowiedzialnej za ruch cząstek. Problemem są węzły na granicach bloków. Istnieje możliwość utraty informacji, jeśli różne wątki będą chciały pisać do tego samego węzła w tym samym czasie. Synchronizacja wątków jest możliwa poprzez użycie w kernelu funkcji wbudowanej syncthreads(), jednak synchronizuje ona wątki tylko w obrębie bloku, czyli zasięg jej działania ogranicza się co najwyżej do jednego multiprocesora. Możliwości efektywnej synchronizacji wątków należących do różnych bloków nie ma. Efektywny sposób obejścia tego problemu polega na zdecydowanie trudniejszym podziale na bloki niż w przypadku zderzeń. Rozwiązaniem jest takie ułożenie bloków, aby na siebie zachodziły (rysunek 3.2), dane z nich będziemy kopiować do małych sieci tymczasowych w pamięci współdzielonej, tam wykonamy wszystkie przesunięcia. Cząstki na skraju sieci w pamięci współdzielonej mogą mieć kierunek powodujący wyjście takiej cząstki poza obszar sieci. Moglibyśmy tę sytuację zaniedbać, ze względu na zachodzenie na siebie bloków. Nie stracimy informacji o tej cząsteczce, po prostu blok sąsiedni wykona jej ruch. Jednak pozwolenie programowi na pisanie poza pamięć przeznaczoną dla niego może prowadzić do fatalnych konsekwencji, tym 28
29 3.1. IMPLEMENTACJA bardziej, że system operacyjny nie ma wglądu do tego, co dzieje się na GPU, więc komunikaty typu segmentation fault nie występują, kod wykonuje się normalnie, a na końcu uzyskuje się błędne wyniki. Stwórzmy więc w pamięci współdzielonej tablicę o dwa węzły szerszą niż ta, w której przechowujemy pobrane informacje. Do niej będziemy zapisywać przesunięte cząstki, lecz do pamięci głównej wracać będzie tylko informacja z najbardziej wewnętrznego prostokąta. Sytuację przedstawia rysunek 3.2. Prostokąt A to obszar sieci Rysunek 3.2: Podział na bloki dla funkcji wykonującej ruch cząstek. wczytany z pamięci głównej, prostokąt C służy do wyłapywania ruchów wychodzących poza prostokąt A, natomiast prostokąt B to część C z której informacja po wykonaniu ruchów wróci do pamięci głównej. Oczywiście w rzeczywistości, prostokąty te mają dużo większe rozmiary, np Funkcja wykonująca ruch czątek według schematu z rysunku 3.1 przedstawiona została na listingu { Listing 3.2: Funkcja wykonująca ruch cząstek. g l o b a l void ruch ( int * siecprzed, int * siecpo ) s h a r e d int A[ 3 2 ] [ 1 6 ] ; 4 s h a r e d int C [ 3 4 ] [ 1 8 ] ; 6 int i=threadidx. x+blockdim. x* blockidx. x 2*blockIdx. x ; int j=threadidx. y+blockdim. y* blockidx. y 2*blockIdx. y ; 8 int index = width * j+i ; 10 A[ threadidx. x ] [ threadidx. y ] = s i e c P r z e d [ index ] ; 29
30 ROZDZIAŁ 3. MODEL FHP W TECHNOLOGII CUDA Rysunek 3.3: Odpowiednik rysunku 3.1 dla funkcji wykonującej ruch cząstek. Część C z rysunku 3.2 nie została narysowana ze względu na czytelność. 12 // wykonaj p r z e s u n i e c i a z A do C // i f ( threadidx. x>0 and threadidx. x<31 and \ 16 threadidx. y>0 and threadidx. y<15) { 18 siecpo [ index ]=C[ threadidx. x +1][ threadidx. y +1]; } 20 } Listing 3.2 linijka po linijce. Omówmy listing 3.2. Argumentami funkcji ruch są wskaźniki na tablice reprezentujące sieci przed wykonaniem ruchu siecprzed i po wykonaniu ruchu siecpo, jak w rozdziale W liniach 3,4 tworzymy w pamięci współdzielonej tablice A oraz C z rysunku 3.2. Linie 6,7,8 odpowiadają za wyznaczenie indeksu węzła w w tablicach siecprzed oraz siecpo. Wyznaczenie indeksów (i,j) węzła za pomocą zmiennych wbudowanych (rozdział 2.2.4) nie jest zadaniem trywialnym. Wewnątrz kernela możemy określić, w któ- 30
31 3.1. IMPLEMENTACJA rym wątku aktualnie jesteśmy, do którego bloku wątków należymy oraz jakie są parametry wywołania kernela, czyli wymiary modelu sieci bloków wątków. Wyznaczenie miejsca (i,j) w sieci (tablicy) przy pomocy tych danych odbywa się następująco: szerokość bloku, czyli jego wymiar w kierunku x, czyli blockdim.x, mnożymy przez składową x numeru bloku, blockidx.x, a następnie dodajemy do wyniku składową x numeru wątka threadidx.x. Przeanalizujmy przykład z rysunku 2.1. Załóżmy, że znajdujemy się w wątku (2,1) bloku (1,1) i chcemy uzyskać pierwszą składową i położenia wątka w sieci. W bloku o indeksie blockidx.x = 0 mamy 4 wątki o indeksach threadidx.x = 0, 1, 2, 3, w następnym bloku blockidx.x = 1 chcemy dojść do wątka o indeksie threadidx.x = 2, więc przejdziemy indeksy threadidx.x = 0, 1, 2 w bloku blockidx.x = 1. W pierwszym bloku przeszliśmy indeksy i = 0, 1, 2, 3 natomiast idąc dalej, przechodzimy i = 4, 5, 6, co ilustruje tabela 3.1. Tablica 3.1: Tabela ilustrująca przeliczanie indeksów wewnątrz kernela. i blockidx.x threadidx.x Stąd: int i = blockdim.x * blockidx.x + threadidx.x = 4 * = 6. Podejście takie działa dla podziału na bloki jak na rysunku 3.1, dlatego zastosowane zostało w listiungu 3.1. W przypadku podziału potrzebnego do wykonania ruchu cząstek, w którym bloki sieci nachodzą na siebie, musimy nanieść poprawki widoczne w omawianym listingu w linijce 6. Widzimy, że wynik wcześniejszego rozumowania został pomniejszony o 2*blockIdx.x, co wynika z nakładania się zielonych prostokątów na rysunku 3.3. Dla bloku o coraz wyższym indeksie, przesunięcie w lewo w stosunku do rysunku 3.1 jest coraz większe, skalowanie jest linowe ze współczynnikiem 2, gdyż prostokąty z rysunku 3.3 mają dwa wspólne pola. Oczywiście, w kierunku y wszystko odbywa się analogicznie. W linii 10 każdy wątek wykonuje kopiowanie stanu wyznaczonego węzła z pamięci globalnej siecprzed do pamięci współdzielonej A. Następną czynnością jest przemieszczenie cząstek w pamięci współdzielonej z tablicy A do C. Na koniec zapisujemy wynik do siecpo pamięci globalnej, kopiując wyłącznie 31
32 ROZDZIAŁ 3. MODEL FHP W TECHNOLOGII CUDA obszar oznaczony na rysunku 3.2 jako B (wiersze 15 19). 3.2 Wydajność Celem pracy była implementacja modelu FHP w technologii Nvidia CUDA, w taki sposób, aby istniejące algorytmy sekwencyjne przyspieszyć, wykorzystując architekturę równoległą kart graficznych. Kod opisany w rozdziale 3.1 przetestowany został na kartach graficznych GTX260 oraz GTX285 wyposażonych w procesory GT200. Wyniki skonfrontowane zostały z implementacją sekwencyjną testowaną na komputerze wyposażonym w procesor Pentium(R) Dual-Core CPU E5200@2.50GHz oraz pamięć RAM typu DDR2. Zarówno wersja wykonywana na CPU, jak i ta w technologii CUDA uruchamiane były na systemie Ubuntu Desktop x86-64 ze sterownikiem Nvidia Zmierzono czas wykonania 1000 kroków symulacji na CPU (t CP U ) oraz na GPU (t GP U ). Wykres 3.4 przedstawia stosunek t CP U /t GP U w zależności od ilości węzłów sieci modelu FHP. W implementacji przedstawionej w rozdziale 3.1 jeden wątek zajmuje się jednym węzłem, więc na rysunku liczbę węzłów traktować można jako ilość wątków w jednym kroku symulacji. Rysunek 3.4 podzielić możemy na 3 obszary, do 10 5, od 10 5 do 10 7 i powyżej 10 7 węzłów. Widzimy, że w pierwszym z nich wydajność wzrasta wraz ze wzrostem rozmiarów sieci. Małe przyspieszenie dla małych rozmiarów sieci związane jest ze zbyt małą liczbą zadań w stosunku do liczby rdzeni na urządzeniu. Liczba zadań przypadających na multiprocesor musi być odpowiednio duża, aby dobrze spożytkować jego moc obliczeniową. Karty graficzne z procesorami typu GT200 maksymalnie mogą obsługiwać 1024 wątki na multiprocesor jednocześnie. Maksymalna liczba aktywnych wątków na multiprocesor pomnożona przez liczbę procesorów jest minimalną sensowną wielkością sieci, dla GTX285 jest to = Maksimum wydajności osiągane jest dla 30 razy większej wielkości sieci tj węzłów i do rozmiarów około 10 7 przyspieszenie obliczeń na GPU względem CPU osiąga poziom prawie 50 dla słabszego GTX260 oraz około 60 dla GTX285. W obszarze powyżej 10 7 węzłów wydajność spada. Z rysunku 3.5 widzimy, że czasy wykonania programów na GPU wzrastają liniowo wraz ze wzrostem ilości węzłów, natomiast rysunek 3.6 pokazuje, że dla bardzo dużych sieci > 10 7 wraz z dalszym wzrostem rozmiarów, czasy działania na CPU przestają zmieniać się liniowo. Stąd spadek przyspieszenia w tym obszarze widoczny na rysunku
33 3.2. WYDAJNOŚĆ Rysunek 3.4: Przyspieszenie uzyskane na Nvidia GT200 względem Pentium(R) Dual-Core CPU 33
34 ROZDZIAŁ 3. MODEL FHP W TECHNOLOGII CUDA Rysunek 3.5: Zależność czasu wykonania 1000 kroków na GPU od rozmiarów sieci. Rysunek 3.6: Czas wykonania 1000 kroków na GPU i CPU w funkcji rozmiaru sieci. 34
35 4 Poprawność implementacji Aby sprawdzić poprawność implementacji, porównałem wynik działania programu z rozwiązaniem teoretycznym i wynikiem eksperymentalnym. W przypadku symulacji fizycznych oczekiwany wynik powinien być jak najbardziej zbliżony do danych doświadczalnych lub modelu teoretycznego, jeśli takowy istnieje. 4.1 Porównanie z teorią Jak wiemy z sekcji 1.1 model teoretyczny, czyli równania Naviera-Stokesa, nie ma ogólnego rozwiązania. Jednym z nielicznych przypadków, dla których możemy podać analityczne rozwiązanie, jest przepływ cieczy między dwiema równoległymi płaszczyznami. Zapiszmy równania N-S [1] w dwóch wymiarach: t u i + 2 j=1 u j u i x j = η u i p x i + f i ( x, t) (4.1) gdzie i 1, 2, u( x, t) prędkość, η - jest dodatnim współczynnikiem lepkości, p( x, t) ciśnienie, f( x, t) funkcja opisująca oddziaływanie zewnętrzne np. grawitację oraz x 1 = x, x 2 = y. Równanie to opisuje ruch cieczy w R 2. Przedstawia ono zależność między wektorem prędkości u( x, t) R 2 i ciśnieniem p( x). Przepływ taki nazywamy przepływem Poiseuille a [7], rysunek 4.1. Roz- Rysunek 4.1: Przepływ Poiseuille. 35
36 ROZDZIAŁ 4. POPRAWNOŚĆ IMPLEMENTACJI piszmy równanie N-S dla składowej x: ( ) t u u x x + u x x + u u x 2 y y = η x u 2 x + 2 y u 2 x p x + f x( x, t) (4.2) Powyższe wyrażenie dla przepływu Poiseuille a znacznie się upraszcza: ˆ u t x = 0. Przepływ jest stacjonarny, niezależny od czasu. 2 = 0 oraz u x 2 x = 0. Ponieważ u x zależy tylko od składowej y. Dla dowolnie wybranego przekroju w kierunku OX rozkład u x jest taki sam. u ˆ u x x x ˆ u y u x y = 0 gdyż u y = 0. Wektor prędkości ma tylko składową poziomą. ˆ f x ( x, t) = 0. Ponieważ f i ( x, t) jest członem opisującym wkład sił zewnętrznych które w tym przypadku nie występują. Uwzględniając wszystkie powyższe punkty: 0 = η 2 y 2 u x p x (4.3) Tak uproszczone równanie N-S jesteśmy w stanie rozwiązać analitycznie, gdyż jest to równanie różniczkowe o rozdzielonych zmiennych: 2 y u 2 x = 1 p η x (4.4) zakładając, że p x = const i dwukrotnie całkując obustronnie, dostajemy: u x = 1 p 2η x y2 + C 1 y + C 2 (4.5) gdzie C 1,C 2 są stałymi całkowania. W miejscu spotkania się płaszczyzn i cieczy, czyli dla y = 0 oraz y = h, prędkość u x = 0, stąd warunek brzegowy u x (0) = 0 i u x (h) = 0. Prowadzi on do wyznaczenia stałych C 2 = 0 oraz C 1 = 1 p h. Ostatecznie, rozwiązaniem równania N-S dla przepływu Poiseuille a η x jest: u x (y) = 1 p y (y h) (4.6) 2η x 36
37 4.1. PORÓWNANIE Z TEORIĄ Przyjmując gradient ciśnienia za stały wzdłuż całego przekroju rury, p = x const, możemy zapisać p = p, gdzie p jest różnicą ciśnień na końcach x l układu, a l długością rury. Jeśli przepływ odbywa się w prawo, jak na rysunku 4.1, to p < 0, więc: u x (y) = p y (y h) (4.7) 2ηl Powyższe rozwiązanie mówi, że rozkład prędkości dla dowolnego przekroju równoległego do osi OY ma charakter paraboliczny. Wykonując doświadczenie numeryczne oczekujemy, że przepływ przez pustą rurę będzie miał taki właśnie charakter [8]. Wynik działania aplikacji widać na rysunku 4.2. Zielona linia jest parabolą 4.7 o współczynnikach dopasowanych metodą najmniejszych kwadratów. Widać, że dopasowanie jest bardzo dobre. Rysunek 4.2: Przepływ Poiseuille a symulowany modelem FHP. Punkty są wynikiem doświadczenia komputerowego, zielona linia jest parabolą o współczynnikach wyznaczonych metodą najmniejszych kwadratów z dopasowania wzoru 4.7 do danych numerycznych. 37
38 ROZDZIAŁ 4. POPRAWNOŚĆ IMPLEMENTACJI 4.2 Porównanie z doświadczeniem Na początku 2010 r. grupa badawcza z Mathematical Modeling Group z Max Planck Institute for Marine Microbiology pod kierunkiem A. Khalili wykonała doświadczenie mające na celu wyznaczenie linii prądu dla przepływu stacjonarnego w ośrodku porowatym. Doświadczenie polegało na zbudowaniu układu przeszkód jak na rysunku 4.3 w płaskim kanale o długości 7.1 cm i grubości 0.16 cm, wymuszeniu przepływu cieczy i wykonaniu pomiarów metodami micropiv [9]. Particle Image Velocimetry (PIV), jest metodą pomiarową służącą do pomiaru prędkości przepływu cieczy i wyznaczenia li- Rysunek 4.3: Układ przeszkód w doświadczeniu micropiv. Rysunek 4.4: Wynik doświadczenia micropiv. Zdjęcie wykonał Kolja Kindler z MPI-Bremen. 38
39 4.2. PORÓWNANIE Z DOŚWIADCZENIEM nii prądu. W cieczy umieszcza się cząstki będące znacznikami fluorescencyjnymi, które płyną wraz z prądem. Pomiar polega na oświetleniu znaczników wiązką lasera i odpowiednio częstym wykonywaniu zdjęć, z których obraz jest odpowiednio analizowany. Jednym z elementów analizy jest uśrednianie kolejnych pomiarów dlatego metoda może służyć jedynie do badania przepływów stacjonarnych. Wynik doświadczenia przedstawia rysunek 4.4. Symulacja dla identycznego układu wykonane zostało metodami komputerowymi, przy użyciu algorytmu FHP zaimplementowanego na potrzeby niniejszej pracy w technologii Nvidia CUDA. Wynik symulacji przedstawia rysunek 4.6. Kolory przedstawiają rozkład modułu prędkości, kolory ciemniejsze (niebieski) przedstawiają prędkość mniejszą, jaśniejsze (czerwony) większą. Skalę barw przedstawia rysunek 4.5. Wynikiem działania programu wykonującego symulację jest pole prędkości, czyli w każdym węźle sieci otrzymujemy średnią wartość v x oraz v y. Aby wyznaczyć linie prądu, należy przecałkować dwuwymiarowe dyskretne pole prędkości. Całkowanie wykonane zostało metodą Rysunek 4.5: Skala barw odpowiadających modułowi prędkości. Rysunek 4.6: Wynik symulacji metodą FHP w technologii Nvidia CUDA. 39
40 ROZDZIAŁ 4. POPRAWNOŚĆ IMPLEMENTACJI Runge-Kutta czwartego rzędu. Podczas wykonywania kroku całkowania możemy trafić w miejsce między węzłami, musimy wtedy interpolować wartość modułu prędkości w takim punkcie na podstawie węzłów sąsiednich. Interpolacja została dokonana metodą biliniową. Jakościowe porównanie wyników doświadczalnych z wynikami symulacji przedstawiają rysunki 4.7. Podobieństwo wyników jest uderzające. 40
41 4.2. PORÓWNANIE Z DOŚWIADCZENIEM Rysunek 4.7: Porównanie wyników doświadczenia (po lewej) z symulacją (po prawej). 41
42 ROZDZIAŁ 4. POPRAWNOŚĆ IMPLEMENTACJI 42
43 5 Galeria Rysunki zamieszczone w galerii przedstawiają wyniki symulacji przeprowadzonych programem napisanym na potrzeby niniejszej pracy. Wynikiem działania programu jest pole prędkości, czyli wartość średnia składowej poziomej oraz pionowej wektora prędkości dla każdego węzła. Rysunki 5.1, 5.3, 5.4 przedstawiają linie prądu wygenerowane z tego pola prędkości przy pomocy programu Paraview [10]. Na rysunku 5.2 widzimy barwową reprezentację średniej długości wektora prędkości. Obraz 5.2 jest zrzutem ekranu interfejsu graficznego napisanego w technologii OpenGL. Wszystkie obliczenia i operacje graficzne odbywają się bezpośrednio na karcie graficznej. Dla sieci 1372 na 702 (blisko 1 milion węzłów) program generuje ok. 150 klatek na sekundę. Rysunek 5.1: Przepływ przez rurę z płaską przeszkodą, linie prądu wygenerowano w programie Paraview[10]. 43
44 ROZDZIAŁ 5. GALERIA Rysunek 5.2: Scieżki Von Karmana za cylindryczną przeszkodą, rozkład prędkości. Rysunek 5.3: Przepływ przez rurę z płaską przeszkodą, linie prądu wygenerowano w programie Paraview[10]. Przepływ turbulentny. 44
Implementacja modelu FHP w technologii NVIDIA CUDA
Uniwersytet Wrocławski Wydział Fizyki i Astronomii Instytut Fizyki Teoretycznej Sebastian Szkoda Implementacja modelu FHP w technologii NVIDIA CUDA Opiekun: dr hab. Zbigniew Koza, prof. UWr. 1 Model 1.1
Porównanie wydajności CUDA i OpenCL na przykładzie równoległego algorytmu wyznaczania wartości funkcji celu dla problemu gniazdowego
Porównanie wydajności CUDA i OpenCL na przykładzie równoległego algorytmu wyznaczania wartości funkcji celu dla problemu gniazdowego Mariusz Uchroński 3 grudnia 2010 Plan prezentacji 1. Wprowadzenie 2.
Programowanie kart graficznych
CUDA Compute Unified Device Architecture Programowanie kart graficznych mgr inż. Kamil Szostek AGH, WGGIOŚ, KGIS Wykorzystano materiały z kursu Programowanie kart graficznych prostsze niż myślisz M. Makowski
CUDA Median Filter filtr medianowy wykorzystujący bibliotekę CUDA sprawozdanie z projektu
CUDA Median Filter filtr medianowy wykorzystujący bibliotekę CUDA sprawozdanie z projektu inż. Daniel Solarz Wydział Fizyki i Informatyki Stosowanej AGH 1. Cel projektu. Celem projektu było napisanie wtyczki
Katarzyna Jesionek Zastosowanie symulacji dynamiki cieczy oraz ośrodków sprężystych w symulatorach operacji chirurgicznych.
Katarzyna Jesionek Zastosowanie symulacji dynamiki cieczy oraz ośrodków sprężystych w symulatorach operacji chirurgicznych. Jedną z metod symulacji dynamiki cieczy jest zastosowanie metody siatkowej Boltzmanna.
Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA
Wprowadzenie do programowania w środowisku CUDA Środowisko CUDA 1 Budowa procesora CPU i GPU Architektura GPU wymaga większej ilości tranzystorów na przetwarzanie danych Control ALU ALU ALU ALU Cache DRAM
CUDA część 1. platforma GPGPU w obliczeniach naukowych. Maciej Matyka
CUDA część 1 platforma GPGPU w obliczeniach naukowych Maciej Matyka Bariery sprzętowe (procesory) ok na. 1 10 00 la raz t y Gdzie jesteśmy? a ok. 2 razy n 10 lat (ZK) Rozwój 1985-2004 i dalej? O roku ów
Programowanie Współbieżne
Programowanie Współbieżne Agnieszka Łupińska 5 października 2016 Hello World! helloworld.cu: #include global void helloworld(){ int thid = (blockidx.x * blockdim.x) + threadidx.x; printf("hello
Programowanie procesorów graficznych NVIDIA (rdzenie CUDA) Wykład nr 1
Programowanie procesorów graficznych NVIDIA (rdzenie CUDA) Wykład nr 1 Wprowadzenie Procesory graficzne GPU (Graphics Processing Units) stosowane są w kartach graficznych do przetwarzania grafiki komputerowej
Programowanie procesorów graficznych GPGPU. Krzysztof Banaś Obliczenia równoległe 1
Programowanie procesorów graficznych GPGPU Krzysztof Banaś Obliczenia równoległe 1 OpenCL projektowanie kerneli Przypomnienie: kernel program realizowany przez urządzenie OpenCL wątek (work item) rdzeń
i3: internet - infrastruktury - innowacje
i3: internet - infrastruktury - innowacje Wykorzystanie procesorów graficznych do akceleracji obliczeń w modelu geofizycznym EULAG Roman Wyrzykowski Krzysztof Rojek Łukasz Szustak [roman, krojek, lszustak]@icis.pcz.pl
znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.
Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo
Programowanie procesorów graficznych GPGPU
Programowanie procesorów graficznych GPGPU 1 GPGPU Historia: lata 80 te popularyzacja systemów i programów z graficznym interfejsem specjalistyczne układy do przetwarzania grafiki 2D lata 90 te standaryzacja
Podstawy Programowania C++
Wykład 3 - podstawowe konstrukcje Instytut Automatyki i Robotyki Warszawa, 2014 Wstęp Plan wykładu Struktura programu, instrukcja przypisania, podstawowe typy danych, zapis i odczyt danych, wyrażenia:
Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.
Część XIX C++ w Każda poznana do tej pory zmienna może przechowywać jedną liczbę. Jeśli zaczniemy pisać bardziej rozbudowane programy, okaże się to niewystarczające. Warto więc poznać zmienne, które mogą
Przygotowanie kilku wersji kodu zgodnie z wymogami wersji zadania,
Przetwarzanie równoległe PROJEKT OMP i CUDA Temat projektu dotyczy analizy efektywności przetwarzania równoległego realizowanego przy użyciu komputera równoległego z procesorem wielordzeniowym z pamięcią
Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1 Tablice wielowymiarowe C umożliwia definiowanie tablic wielowymiarowych najczęściej stosowane
Programowanie Równoległe wykład, 21.01.2013. CUDA, przykłady praktyczne 1. Maciej Matyka Instytut Fizyki Teoretycznej
Programowanie Równoległe wykład, 21.01.2013 CUDA, przykłady praktyczne 1 Maciej Matyka Instytut Fizyki Teoretycznej Motywacja l CPU vs GPU (anims) Plan CUDA w praktyce Wykład 1: CUDA w praktyce l aplikacja
Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja
Szukanie rozwiązań funkcji uwikłanych (równań nieliniowych)
Szukanie rozwiązań funkcji uwikłanych (równań nieliniowych) Funkcja uwikłana (równanie nieliniowe) jest to funkcja, która nie jest przedstawiona jawnym przepisem, wzorem wyrażającym zależność wartości
PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec
PROE wykład 2 operacje na wskaźnikach dr inż. Jacek Naruniec Zmienne automatyczne i dynamiczne Zmienne automatyczne: dotyczą kontekstu, po jego opuszczeniu są usuwane, łatwiejsze w zarządzaniu od zmiennych
Wektory, układ współrzędnych
Wektory, układ współrzędnych Wielkości występujące w przyrodzie możemy podzielić na: Skalarne, to jest takie wielkości, które potrafimy opisać przy pomocy jednej liczby (skalara), np. masa, czy temperatura.
Programowanie kart graficznych
Programowanie kart graficznych Sławomir Wernikowski swernikowski@wi.zut.edu.pl Wykład #1: Łagodne wprowadzenie do programowania w technologii NVIDIA CUDA Terminologia: Co to jest GPGPU? General-Purpose
Numeryczna symulacja rozpływu płynu w węźle
231 Prace Instytutu Mechaniki Górotworu PAN Tom 7, nr 3-4, (2005), s. 231-236 Instytut Mechaniki Górotworu PAN Numeryczna symulacja rozpływu płynu w węźle JERZY CYGAN Instytut Mechaniki Górotworu PAN,
Programowanie Równoległe wykład 12. OpenGL + algorytm n ciał. Maciej Matyka Instytut Fizyki Teoretycznej
Programowanie Równoległe wykład 12 OpenGL + algorytm n ciał Maciej Matyka Instytut Fizyki Teoretycznej CUDA z OpenGL 1. Dane dla kerneli znajdują się na karcie GFX. 2. Chcemy liczyć i rysować używając
utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,
Lista 3 Zestaw I Zadanie 1. Zaprojektować i zaimplementować funkcje: utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy, zapisz
JCuda Czy Java i CUDA mogą się polubić? Konrad Szałkowski
JCuda Czy Java i CUDA mogą się polubić? Konrad Szałkowski Agenda GPU Dlaczego warto używać GPU Budowa GPU CUDA JCuda Przykładowa implementacja Co to jest? GPU GPU Graphical GPU Graphical Processing GPU
Architektura komputerów
Architektura komputerów Wykład 7 Jan Kazimirski 1 Pamięć podręczna 2 Pamięć komputera - charakterystyka Położenie Procesor rejestry, pamięć podręczna Pamięć wewnętrzna pamięć podręczna, główna Pamięć zewnętrzna
Szablony funkcji i szablony klas
Bogdan Kreczmer bogdan.kreczmer@pwr.wroc.pl Zakład Podstaw Cybernetyki i Robotyki Instytut Informatyki, Automatyki i Robotyki Politechnika Wrocławska Kurs: Copyright c 2011 Bogdan Kreczmer Niniejszy dokument
Symulacje komputerowe dynamiki płynów Model FHP i przepływ Poiseuille a
Symulacje komputerowe dynamiki płynów Model FHP i przepływ Poiseuille a Beata Kowal 1 Wstęp 1.1 Model FHP Model gazu sieciowego służy do symulowania przepływu płynów. Model gazu FHP oparty jest na sieci
Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.
Część XXII C++ w Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Ćwiczenie 1 1. Utwórz nowy projekt w Dev C++ i zapisz go na
Metody numeryczne Wykład 4
Metody numeryczne Wykład 4 Dr inż. Michał Łanczont Instytut Elektrotechniki i Elektrotechnologii E419, tel. 4293, m.lanczont@pollub.pl, http://m.lanczont.pollub.pl Zakres wykładu Metody skończone rozwiązywania
Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.
Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych. 1. Rodzaje pamięci używanej w programach Pamięć komputera, dostępna dla programu,
Jak napisać program obliczający pola powierzchni różnych figur płaskich?
Część IX C++ Jak napisać program obliczający pola powierzchni różnych figur płaskich? Na początku, przed stworzeniem właściwego kodu programu zaprojektujemy naszą aplikację i stworzymy schemat blokowy
Wydajność systemów a organizacja pamięci. Krzysztof Banaś, Obliczenia wysokiej wydajności. 1
Wydajność systemów a organizacja pamięci Krzysztof Banaś, Obliczenia wysokiej wydajności. 1 Motywacja - memory wall Krzysztof Banaś, Obliczenia wysokiej wydajności. 2 Organizacja pamięci Organizacja pamięci:
Podstawy OpenCL część 2
Podstawy OpenCL część 2 1. Napisz program dokonujący mnożenia dwóch macierzy w wersji sekwencyjnej oraz OpenCL. Porównaj czasy działania obu wersji dla różnych wielkości macierzy, np. 16 16, 128 128, 1024
Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego
Arytmetyka cyfrowa Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego (binarnego). Zapis binarny - to system liczenia
Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1
Podstawy programowania, Poniedziałek 30.05.2016, 8-10 Projekt, część 1 1. Zadanie Projekt polega na stworzeniu logicznej gry komputerowej działającej w trybie tekstowym o nazwie Minefield. 2. Cele Celem
1 Podstawy c++ w pigułce.
1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,
Moc płynąca z kart graficznych
Moc płynąca z kart graficznych Cuda za darmo! Czyli programowanie generalnego przeznaczenia na kartach graficznych (GPGPU) 22 października 2013 Paweł Napieracz /20 Poruszane aspekty Przetwarzanie równoległe
JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6
JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 6 1 SPECYFIKATOR static Specyfikator static: Specyfikator ten powoduje, że zmienna lokalna definiowana w obrębie danej funkcji nie jest niszczona
Tesla. Architektura Fermi
Tesla Architektura Fermi Tesla Tesla jest to General Purpose GPU (GPGPU), GPU ogólnego przeznaczenia Obliczenia dotychczas wykonywane na CPU przenoszone są na GPU Możliwości jakie daje GPU dla grafiki
Programowanie Równoległe wykład 13. Symulacje komputerowe cieczy LBM w CUDA. Maciej Matyka Instytut Fizyki Teoretycznej
Programowanie Równoległe wykład 13 Symulacje komputerowe cieczy LBM w CUDA Maciej Matyka Instytut Fizyki Teoretycznej Transport cieczy i gazów W wielu dziedzinach trzeba rozwiązać zagadnienie transportu
Wydajność systemów a organizacja pamięci, czyli dlaczego jednak nie jest aż tak źle. Krzysztof Banaś, Obliczenia wysokiej wydajności.
Wydajność systemów a organizacja pamięci, czyli dlaczego jednak nie jest aż tak źle Krzysztof Banaś, Obliczenia wysokiej wydajności. 1 Organizacja pamięci Organizacja pamięci współczesnych systemów komputerowych
Programowanie Równoległe Wykład, CUDA praktycznie 1. Maciej Matyka Instytut Fizyki Teoretycznej
Programowanie Równoległe Wykład, 07.01.2014 CUDA praktycznie 1 Maciej Matyka Instytut Fizyki Teoretycznej Motywacja l CPU vs GPU (anims) Plan CUDA w praktyce Wykład 1: CUDA w praktyce Wykład 2: Cuda +
Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład 6 Wskaźniki Krzysztof Banaś Podstawy programowania 1 Adresy zmiennych Język C pozwala na operowanie adresami w pamięci stąd, między innymi, kwalifikowanie C jako języka relatywnie
WYDZIAŁ LABORATORIUM FIZYCZNE
1 W S E i Z W WARSZAWIE WYDZIAŁ LABORATORIUM FIZYCZNE Ćwiczenie Nr 3 Temat: WYZNACZNIE WSPÓŁCZYNNIKA LEPKOŚCI METODĄ STOKESA Warszawa 2009 2 1. Podstawy fizyczne Zarówno przy przepływach płynów (ciecze
Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:
Wskaźniki są nieodłącznym elementem języka C. W języku C++ także są przydatne i korzystanie z nich ułatwia pracę, jednak w odróżnieniu do C wiele rzeczy da się osiągnąć bez ich użycia. Poprawne operowanie
Wysokowydajna implementacja kodów nadmiarowych typu "erasure codes" z wykorzystaniem architektur wielordzeniowych
Wysokowydajna implementacja kodów nadmiarowych typu "erasure codes" z wykorzystaniem architektur wielordzeniowych Ł. Kuczyński, M. Woźniak, R. Wyrzykowski Instytut Informatyki Teoretycznej i Stosowanej
Szablony funkcji i klas (templates)
Instrukcja laboratoryjna nr 3 Programowanie w języku C 2 (C++ poziom zaawansowany) Szablony funkcji i klas (templates) dr inż. Jacek Wilk-Jakubowski mgr inż. Maciej Lasota dr inż. Tomasz Kaczmarek Wstęp
========================= Zapisujemy naszą funkcję kwadratową w postaci kanonicznej: 2
Leszek Sochański Arkusz przykładowy, poziom podstawowy (A1) Zadanie 1. Wykresem funkcji kwadratowej f jest parabola o wierzchołku 5,7 Wówczas prawdziwa jest równość W. A. f 1 f 9 B. f 1 f 11 C. f 1 f 1
dr inż. Jarosław Forenc
Informatyka 2 Politechnika Białostocka - Wydział Elektryczny Elektrotechnika, semestr III, studia stacjonarne I stopnia Rok akademicki 2010/2011 Wykład nr 7 (24.01.2011) dr inż. Jarosław Forenc Rok akademicki
Ćwiczenie 2 Numeryczna symulacja swobodnego spadku ciała w ośrodku lepkim (Instrukcja obsługi interfejsu użytkownika)
Ćwiczenie 2 Numeryczna symulacja swobodnego spadku ciała w ośrodku lepkim (Instrukcja obsługi interfejsu użytkownika) 1 1 Cel ćwiczenia Celem ćwiczenia jest rozwiązanie równań ruchu ciała (kuli) w ośrodku
CUDA. cudniejsze przyk ady
CUDA cudniejsze przyk ady Agenda: CPU vs. GPU Mnożenie macierzy CPU Mnożenie macierzy - GPU Sploty Macierze CPU vs. GPU CPU: GPU: Mnożenie wykonywane w kolejnych iteracjach pętli. Przechodzimy przez pierwszy
Wydajność systemów a organizacja pamięci. Krzysztof Banaś, Obliczenia wysokiej wydajności. 1
Wydajność systemów a organizacja pamięci Krzysztof Banaś, Obliczenia wysokiej wydajności. 1 Wydajność obliczeń Dla wielu programów wydajność obliczeń można traktować jako wydajność pobierania z pamięci
Spis treści. I. Skuteczne. Od autora... Obliczenia inżynierskie i naukowe... Ostrzeżenia...XVII
Spis treści Od autora..................................................... Obliczenia inżynierskie i naukowe.................................. X XII Ostrzeżenia...................................................XVII
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się
Równoległy algorytm wyznaczania bloków dla cyklicznego problemu przepływowego z przezbrojeniami
Równoległy algorytm wyznaczania bloków dla cyklicznego problemu przepływowego z przezbrojeniami dr inż. Mariusz Uchroński Wrocławskie Centrum Sieciowo-Superkomputerowe Agenda Cykliczny problem przepływowy
Programowanie strukturalne i obiektowe. Funkcje
Funkcje Często w programach spotykamy się z sytuacją, kiedy chcemy wykonać określoną czynność kilka razy np. dodać dwie liczby w trzech miejscach w programie. Oczywiście moglibyśmy to zrobić pisząc trzy
Teraz bajty. Informatyka dla szkół ponadpodstawowych. Zakres rozszerzony. Część 1.
Teraz bajty. Informatyka dla szkół ponadpodstawowych. Zakres rozszerzony. Część 1. Grażyna Koba MIGRA 2019 Spis treści (propozycja na 2*32 = 64 godziny lekcyjne) Moduł A. Wokół komputera i sieci komputerowych
Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat
Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Program, to lista poleceń zapisana w jednym języku programowania zgodnie z obowiązującymi w nim zasadami. Celem programu jest przetwarzanie
Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?
Część XVIII C++ Funkcje Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Umiemy już podzielić nasz
Lab 9 Podstawy Programowania
Lab 9 Podstawy Programowania (Kaja.Gutowska@cs.put.poznan.pl) Wszystkie kody/fragmenty kodów dostępne w osobnym pliku.txt. Materiały pomocnicze: Wskaźnik to specjalny rodzaj zmiennej, w której zapisany
Laboratorium 5: Tablice. Wyszukiwanie binarne
Wojciech Myszka Laboratorium 5: Tablice. Wyszukiwanie binarne 2016-05-07 09:02:17 +0200 1. Tablice Do tej pory nie było potrzeby odwoływać się do zmiennych złożonych. Programy były bardzo proste i korzystały
C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów
Operatory są elementami języka C++. Istnieje zasada, że z elementami języka, takimi jak np. słowa kluczowe, nie można dokonywać żadnych zmian, przeciążeń, itp. PRZECIĄŻANIE OPERATORÓW Ale dla operatorów
Skalowalność obliczeń równoległych. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1
Skalowalność obliczeń równoległych Krzysztof Banaś Obliczenia Wysokiej Wydajności 1 Skalowalność Przy rozważaniu wydajności przetwarzania (obliczeń, komunikacji itp.) często pojawia się pojęcie skalowalności
Modelowanie wieloskalowe. Automaty Komórkowe - podstawy
Modelowanie wieloskalowe Automaty Komórkowe - podstawy Dr hab. inż. Łukasz Madej Katedra Informatyki Stosowanej i Modelowania Wydział Inżynierii Metali i Informatyki Przemysłowej Budynek B5 p. 716 lmadej@agh.edu.pl
Tworzenie programów równoległych cd. Krzysztof Banaś Obliczenia równoległe 1
Tworzenie programów równoległych cd. Krzysztof Banaś Obliczenia równoległe 1 Metodologia programowania równoległego Przykłady podziałów zadania na podzadania: Podział ze względu na funkcje (functional
Programowanie współbieżne Wykład 2. Iwona Kochańska
Programowanie współbieżne Wykład 2 Iwona Kochańska Miary skalowalności algorytmu równoległego Przyspieszenie Stały rozmiar danych N T(1) - czas obliczeń dla najlepszego algorytmu sekwencyjnego T(p) - czas
Programowanie w języku Python. Grażyna Koba
Programowanie w języku Python Grażyna Koba Kilka definicji Program komputerowy to ciąg instrukcji języka programowania, realizujący dany algorytm. Język programowania to zbiór określonych instrukcji i
2. Układy równań liniowych
2. Układy równań liniowych Grzegorz Kosiorowski Uniwersytet Ekonomiczny w Krakowie zima 2017/2018 rzegorz Kosiorowski (Uniwersytet Ekonomiczny w Krakowie) 2. Układy równań liniowych zima 2017/2018 1 /
Algorytm. Krótka historia algorytmów
Algorytm znaczenie cybernetyczne Jest to dokładny przepis wykonania w określonym porządku skończonej liczby operacji, pozwalający na rozwiązanie zbliżonych do siebie klas problemów. znaczenie matematyczne
Czym są właściwości. Poprawne projektowanie klas
Z akcesorów get i set korzysta każdy kto programuje w C#. Stanowią one duże udogodnienie w programowaniu obiektowym. Zapewniają wygodę, bezpieczeństwo i znacząco skracają kod. Akcesory są ściśle związane
Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady
Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4 Dr inż. Dariusz JĘDRZEJCZYK Wskaźniki Dynamiczna alokacja pamięci Przykłady 11/3/2016 AGH, Katedra Informatyki Stosowanej i Modelowania 2 Wskaźnik to
Definicje i przykłady
Rozdział 1 Definicje i przykłady 1.1 Definicja równania różniczkowego 1.1 DEFINICJA. Równaniem różniczkowym zwyczajnym rzędu n nazywamy równanie F (t, x, ẋ, ẍ,..., x (n) ) = 0. (1.1) W równaniu tym t jest
1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami
1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami Celem tych zajęć jest zrozumienie i oswojenie z technikami programowania przy pomocy wskaźników w języku C++. Proszę przeczytać rozdział 8.
Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjne i interfejsy Streszczenie Celem wykładu jest omówienie klas abstrakcyjnych i interfejsów w Javie. Czas wykładu 45 minut. Rozwiązanie w miarę standardowego zadania matematycznego (i nie
PROGRAMOWANIE WSPÓŁCZESNYCH ARCHITEKTUR KOMPUTEROWYCH DR INŻ. KRZYSZTOF ROJEK
1 PROGRAMOWANIE WSPÓŁCZESNYCH ARCHITEKTUR KOMPUTEROWYCH DR INŻ. KRZYSZTOF ROJEK POLITECHNIKA CZĘSTOCHOWSKA 2 Trendy rozwoju współczesnych procesorów Budowa procesora CPU na przykładzie Intel Kaby Lake
Programowanie aplikacji równoległych i rozproszonych
Programowanie aplikacji równoległych i rozproszonych Dr inż. Krzysztof Rojek krojek@icis.pcz.pl Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska Strumienie operacji na GPU Domyślne
Nowinki technologiczne procesorów
Elbląg 22.04.2010 Nowinki technologiczne procesorów Przygotował: Radosław Kubryń VIII semestr PDBiOU 1 Spis treści 1. Wstęp 2. Intel Hyper-Threading 3. Enhanced Intel Speed Technology 4. Intel HD Graphics
Przetwarzanie Równoległe i Rozproszone
POLITECHNIKA KRAKOWSKA - WIEiK KATEDRA AUTOMATYKI I TECHNOLOGII INFORMACYJNYCH Przetwarzanie Równoległe i Rozproszone www.pk.edu.pl/~zk/prir_hp.html Wykładowca: dr inż. Zbigniew Kokosiński zk@pk.edu.pl
Implementacja sieci neuronowych na karcie graficznej. Waldemar Pawlaszek
Implementacja sieci neuronowych na karcie graficznej Waldemar Pawlaszek Motywacja Czyli po co to wszystko? Motywacja Procesor graficzny GPU (Graphics Processing Unit) Wydajność Elastyczność i precyzja
1 Podstawy c++ w pigułce.
1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,
JAK DZIAŁAJĄ FUNKCJE PODZIAŁ PAMIĘCI
JAK DZIAŁAJĄ FUNKCJE PODZIAŁ PAMIĘCI Gdy wywołujesz daną funkcję, program przechodzi do tej funkcji, przekazywane są parametry i następuje wykonanie ciała funkcji. Gdy funkcja zakończy działanie, zwracana
1 Układy równań liniowych
II Metoda Gaussa-Jordana Na wykładzie zajmujemy się układami równań liniowych, pojawi się też po raz pierwszy macierz Formalną (i porządną) teorią macierzy zajmiemy się na kolejnych wykładach Na razie
Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta 16.09.2006. Strona 1 z 26. Powrót. Full Screen. Zamknij.
Programowanie Sobera Jolanta 16.09.2006 Strona 1 z 26 1 Wprowadzenie do programowania 4 2 Pierwsza aplikacja 5 3 Typy danych 6 4 Operatory 9 Strona 2 z 26 5 Instrukcje sterujące 12 6 Podprogramy 15 7 Tablice
Algorytmy sztucznej inteligencji
www.math.uni.lodz.pl/ radmat Przeszukiwanie z ograniczeniami Zagadnienie przeszukiwania z ograniczeniami stanowi grupę problemów przeszukiwania w przestrzeni stanów, które składa się ze: 1 skończonego
Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018
Informatyka I Klasy i obiekty. Podstawy programowania obiektowego dr inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2018 Plan wykładu Pojęcie klasy Deklaracja klasy Pola i metody klasy
Języki i techniki programowania Ćwiczenia 2
Języki i techniki programowania Ćwiczenia 2 Autor: Marcin Orchel Spis treści: Język C++... 5 Przekazywanie parametrów do funkcji... 5 Przekazywanie parametrów w Javie.... 5 Przekazywanie parametrów w c++...
Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1
Tablice i struktury czyli złożone typy danych. Programowanie Proceduralne 1 Tablica przechowuje elementy tego samego typu struktura jednorodna, homogeniczna Elementy identyfikowane liczbami (indeksem).
Język ludzki kod maszynowy
Język ludzki kod maszynowy poziom wysoki Język ludzki (mowa) Język programowania wysokiego poziomu Jeśli liczba punktów jest większa niż 50, test zostaje zaliczony; w przeciwnym razie testu nie zalicza
Obliczenia iteracyjne
Lekcja Strona z Obliczenia iteracyjne Zmienne iteracyjne (wyliczeniowe) Obliczenia iteracyjne wymagają zdefiniowania specjalnej zmiennej nazywanej iteracyjną lub wyliczeniową. Zmienną iteracyjną od zwykłej
Algorytm. Słowo algorytm pochodzi od perskiego matematyka Mohammed ibn Musa al-kowarizimi (Algorismus - łacina) z IX w. ne.
Algorytm znaczenie cybernetyczne Jest to dokładny przepis wykonania w określonym porządku skończonej liczby operacji, pozwalający na rozwiązanie zbliżonych do siebie klas problemów. znaczenie matematyczne
lekcja 8a Gry komputerowe MasterMind
lekcja 8a Gry komputerowe MasterMind Posiadamy już elementarną wiedzę w zakresie programowania. Pora więc zabrać się za rozwiązywanie problemów bardziej złożonych, które wymagają zastosowania typowych
Mechatronika i inteligentne systemy produkcyjne. Modelowanie systemów mechatronicznych Platformy przetwarzania danych
Mechatronika i inteligentne systemy produkcyjne Modelowanie systemów mechatronicznych Platformy przetwarzania danych 1 Sterowanie procesem oparte na jego modelu u 1 (t) System rzeczywisty x(t) y(t) Tworzenie
Informatyka I: Instrukcja 4.2
Informatyka I: Instrukcja 4.2 1 Wskaźniki i referencje - bezboleśnie Nauczyliśmy się do tej pory, że funkcje w języku C mogą zwracać wartość. Co jednak, gdybyśmy chcieli napisać funkcję, która rozwiąże
Czym jest całka? Całkowanie numeryczne
Całkowanie numeryczne jest to zagadnienie z metod elementów skończonych (MES). Korzystając z całkowania numerycznego możemy obliczyć wartość dowolnej całki jednowymiarowej oznaczonej. Wynik jest zawsze
Tablice, funkcje - wprowadzenie
Tablice, funkcje - wprowadzenie Przemysław Gawroński D-10, p. 234 Wykład 5 25 marca 2019 (Wykład 5) Tablice, funkcje - wprowadzenie 25 marca 2019 1 / 12 Outline 1 Tablice jednowymiarowe 2 Funkcje (Wykład
CUDA obliczenia ogólnego przeznaczenia na mocno zrównoleglonym sprzęcie. W prezentacji wykorzystano materiały firmy NVIDIA (http://www.nvidia.
CUDA obliczenia ogólnego przeznaczenia na mocno zrównoleglonym sprzęcie W prezentacji wykorzystano materiały firmy NVIDIA (http://www.nvidia.com) 1 Architektura karty graficznej W porównaniu z tradycyjnym
FUNKCJA LINIOWA - WYKRES
FUNKCJA LINIOWA - WYKRES Wzór funkcji liniowej (Postać kierunkowa) Funkcja liniowa jest podstawowym typem funkcji. Jest to funkcja o wzorze: y = ax + b a i b to współczynniki funkcji, które mają wartości