Szakdolgozat. Brosch Balázs 2009.

Méret: px
Mutatás kezdődik a ... oldaltól:

Download "Szakdolgozat. Brosch Balázs 2009."

Átírás

1 Szakdolgozat Brosch Balázs 2009.

2 Budapesti Mőszaki és Gazdaságtudományi Egyetem Villamosmérnöki és Informatikai Kar Irányítástechnika és Informatika Tanszék Brosch Balázs Párhuzamos algoritmusok megvalósítása MPI környezetben SZAKDOLGOZAT KONZULENS Dr. Szeberényi Imre BUDAPEST,

3 ITT LESZ A FELADATKIÍRÁS 3

4 Nyilatkozat Alulírott, Brosch Balázs, a Budapesti Mőszaki és Gazdaságtudományi Egyetem hallgatója kijelentem, hogy ezt a szakdolgozatot meg nem engedett segítség nélkül, saját magam készítettem, és a szakdolgozatban csak a megadott forrásokat használtam fel. Minden olyan részt, melyet szó szerint, vagy azonos értelemben de átfogalmazva más forrásból átvettem, egyértelmően, a forrás megadásával megjelöltem.... Brosch Balázs 4

5 Tartalmi összefoglaló A szakdolgozat oktatási anyag formájában a C programozási nyelvre alapozva foglalja össze a Message Passing Interface (MPI) azon szolgáltatásait, amelyek elsajátításával bármely párhuzamosítható tudományos probléma megoldására képessé válnak a mérnökhallgatók. A párhuzamos programozás fontossága mellet szóló érvek bemutatása után ismertetem a párhuzamos számítást lehetıvé tevı architektúra és programozási modelleket, melyek között elhelyezem az MPI-t. Egy gyakran elıkerülı probléma részfeladatokra bontásával, és azok különbözı processzekhez rendelésével, valamint a terhelés kiegyensúlyozás problémakörének bemutatásával és a futási idı vizsgálatával elısegítem a hallgatók párhuzamos programozási szemléletének kialakítását. Az üzenetküldéses modell elemeinek bemutatásával ismertetem a blokkoló és a nem-blokkoló pont-pont kommunikációs függvényeket. Az alapvetı kollektív kommunikációs függvények mellett mint például a szinkronizáló sorompó, az üzenetszórás, az adatok szétosztása és összegyőjtése, illetve a közben való mőveletvégzés az összetett kollektív kommunikációs függvények is terítékre kerülnek. A konverziós problémák és feloldásuk oldaláról közelítem meg az MPI származtatott adattípusok és struktúrák átvitelét biztosító lehetıségeit. A cartesian topológiákat elınyös alkalmazhatóságát kétdimenziós adathalmazok feldolgozása kapcsán mutatom be. Kitérek továbbá a szekvenciális és a koordináta processzazonosítók közötti kapcsolatra, valamint a cartesian topológiák tovább bontási lehetıségére, a cartesian résztopológiákra is. Az üzenetküldéses kommunikációt árnyaló lehetıségek közül a felhasználó által definiált redukáló mőveletekre és az üzenetpróbálás alkalmazására mutatok be gyakorlati jelentıségő példákat. A kommunikátorok két fı csoportjának az intra- és inter-kommunikátoroknak az összehasonlításával rámuatatok szerepükre, valamint részletezem létre hozási lehetıségeiket. A gráf topológiák jellemzıinek és létre hozási módjának bemutatása mellett néhány a cartesian topológiákkal való hasolóságot valamint azoktól való eltérést is megemlítek. Végül két bonyolultabb párhuzamosítható feladatot fogalmazok meg, melynek megoldásával a hallgatók bizonyíthatják az MPI környezetben való szemeszter során kialakult jártasságukat. 5

6 Abstract The thesis as an educational material assumes C programming language knowledge summarizes those services of Message Passing Interface (MPI), which let the engineering undergraduates perform any parallelizable scientific problem. After listing arguments about the importance of parallel programming I introduce the required architectures and programming models, where also MPI belongs, for parallel computing. By splitting a common problem into subproblems, assigning them to processes and in addition explaining the meaning of load balancing and examing the parts of run time undergraduates are leaded into the parallel programming approach. Blocking and non-blocking point-to-point communication functions are detailed through presenting the elements of the message passing model. Beside the basic collective communication functions like barrier synchronization, broadcast, scattering, gathering and reducing datas the complex communicaton functions are also described. From the view of data converting problems and solutions I cover the topic of derived datatypes and I explain how MPI provides derived data transferring possibilities. I introduce Cartesian topologies by emphasizing their advantageous adaptability apropos of two dimensional set of data. Furthermore I reveal the contact between sequential and coordinate process identifiers and I show how to further joint Cartesian topologies into subtopologies. To fine message passing communication I describe how to create user-defined reduction operations and I also provide practical examples for the adaptability of message probing. By comparing the two main types of communicators: intra- and intercommunicators I point their role and I detail the possibilities how to create them. Presenting the properties and the way of creating graph topologies I draft some similarities and differences to Cartesian topologies. To conclude the course I suggest two complex parallelizable problem to the undergraduates to solve proving the perfection in MPI environment which they have learnt in this course. 6

7 Tartalomjegyzék I. Oktatási anyag tervezése... 9 I.1. Célkitőzés...9 I.2. Oktatási módszertan, a tananyag szerkezete...10 I.3. Mintapéldák jellegzetességei...10 II. Tananyag bemutatása II.1. Bevezetés a párhuzamos programozás elméletébe...11 II.1.1. Miért fontos a párhuzamos programozás?...11 II.1.2. A hatékony párhuzamos számításhoz szükséges hardver és szoftver adottságok...11 II.1.3. Architektúra modellek...12 II.1.4. Párhuzamos programozási modellek...14 II.1.5. MPI bevezetı...14 II.1.6. Egy egyszerő MPI program bemutatása...15 II.2. Párhuzamos programozási szemlélet kialakítása...17 II.2.1. Az MPI által definiált párhuzamos programozási eszköztár fıbb elemei..17 II.2.2. A feladat részfeladatokra bontása és a részfeladatok processzekhez rendelése...17 II.2.3. Futási idı vizsgálata...19 II.3. Pont-pont kommunikáció és fajtáinak megismerése...20 II.3.1. Az üzenetküldéses modell elemei...20 II.3.2. Blokkoló függvények...21 II A blokkoló függvények felépítése...21 II Joker processz-azonosító, illetve üzenetcímke használata...23 II Hogyan valósítja meg az MPI az üzenetátvitelt?...24 II A holtpont oka, és elkerülésének módja...24 II.3.3. Nem-blokkoló függvények...26 II A nem-blokkoló függvények használatának koncepciója...26 II A nem-blokkoló függvények felépítése...27 II A küldı függvények variánsai...31 II.4. Kollektív kommunikáció és fajtáinak megismerése...33 II.4.1. Alapvetı függvények...33 II Szinkronizáló sorompó...33 II Üzenetszórás...34 II Szétosztás...35 II Összegyőjtés...36 II Összegyőjtés mőveletvégzéssel...37 II.4.2. Alapvetı függvények variánsai...38 II Különbözı mérető részek szétosztása...38 II Különbözı mérető részek összegyőjtése...39 II.4.3. Összetett függvények...40 II Összegyőjtés és mindenkinek elküldés...40 II Összegyőjtés mőveletvégzéssel és mindenkinek elküldés...42 II Szétosztás mindenkitıl mindenkinek...43 II Összegyőjtés mőveletvégzéssel és szétosztás

8 II.5. Származtatott adattípusok és struktúrák létrehozása és átvitele...46 II.5.1. Hogyan továbbítja az MPI az adattípusokat?...46 II.5.2. Adatok csomagolt átvitele...47 II.5.3. Új adattípus (struktúra) létrehozása...48 II Az új adattípus (struktúra) elıkészítése...49 II Az új adattípus (struktúra) véglegesítése...51 II.6. Cartesian topológiák áttekintése...52 II.6.1. Cartesian topológia létrehozása...52 II.6.2. A szekvenciális és a koordináta processz-azonosítók közötti konverzió...53 II.6.3. Cartesian topológia résztopológiákra bontása...54 II.7. Az üzenetküldéses kommunikációt árnyaló lehetıségek...57 II.7.1. Felhasználó által definiált redukáló mőveletek...57 II Az új redukáló mővelet megírása függvényként...57 II A megírt függvény regisztrálása...58 II A kész redukáló mővelet használata...59 II.7.2. Üzenetpróbálás...60 II Az üzenetpróbáló függvény felépítése...60 II Az üzenetpróbáló függvény használata...61 II Szignál üzenetek kezelése...62 II.8. Intra- és inter-kommunikátorok összehasonlítása...64 II.8.1. Intra-kommunikátorok...65 II Intra-kommunikátorok létrehozása széthasítással...65 II Intra-kommunikátorok létrehozása lemásolással...66 II Intra-kommunikátorok létrehozása módosítással...66 II.8.2. Inter-kommunikátorok...70 II Inter-kommunikátor létrehozása két intra-kommunikátor összekapcsolásával...71 II Inter-kommunikátorok adatainak lekérdezése...72 II.9. Gráf topológiák...74 II.9.1. Gráf topológiák létrehozása...74 II.9.2. Gráf topológiák adatainak lekérdezése...75 II.10. Egy komolyabb párhuzamos algoritmus önálló megvalósítása...78 III. Továbbfejlesztési lehetıségek IV. Összefogalás V. Irodalomjegyzék VI. Mellékletek

9 I. Oktatási anyag tervezése I.1. Célkitőzés A szakdolgozat egy a Budapesti Mőszaki és Gazdaságtudományi Egyetem Villamosmérnöki és Informatikai Karának M.Sc. képzésében bevezetendı választható tárgy tematikájára tesz egy javaslatot, mely a párhuzamos programozás mérnökhallgatókkal való megismertetésével kívánja a napjainkban egyre növekvı számítási teljesítmény igény kiszolgálására irányuló törekvést támogatni. Mivel a párhuzamos programozási modellek közül az üzenet-átadásos módszer lazán csatolt rendszerek esetén is hatékony megvalósíthatósága miatt a legszélesebb körben implementálható [1], ezért az oktatási anyag középpontjában a leginkább fejlesztett üzenet-átadásos párhuzamos programozási modell standard interfésze, a Message Passing Interface (MPI) áll. A tematika kidolgozása során három fı irányelvet tartottam szem elıtt: A mérnökhallgatókat a problémamegoldási szemléletükben a soros programírás koncepciójából egy paradigma-váltáson keresztül átvezetni a párhuzamos programokban való gondolkodásig. Az egyes tananyagrészeket igyekeztem lényegre törıen, ugyanakkor precízen és kétértelmőséget nem hagyva összeállítani, hogy a tanulás során ne kelljen más forráshoz fordulni, hanem lehessen kizárólag az elsajátítandó kompetenciákra összpontosítani. Továbbá a fejezetek végén segítségképp ellenırzı kérdésekkel hangsúlyoztam ki az adott téma lényeges pontjait. Alapvetı C nyelvő programozási ismeretekre építve, az MPI biztosította lehetıségeknek törekedtem olyan mélységő ismeretét átadni, melynek birtokában a mérnökhallgatók a tudományos életben felmerülı bármilyen párhuzamosítható problémát képessé válnak megoldani. A párhuzamos programok írásában való készség kialakítását számos példaprogram bemutatásával céloztam meg. 9

10 I.2. Oktatási módszertan, a tananyag szerkezete A tematikát egy tízalkalmas, egyenként kilencven perces számítógépes laboratórium sorozatra terveztem. A tantárgy célja, hogy a kurzust elvégezve a hallgatók egy bonyolultabb párhuzamos algoritmust önállóan elkészítsenek. Az ehhez szükséges ismereteket kilenc témakörbe győjtöttem, a tizedik fejezet pedig a feladatkiírásokról szól, melyek mellé megoldási javaslatokat is mellékeltem. Minden fejezet a téma felvezetésével kezdıdik, majd az elméleti részek tárgyalásával, illetve annak példaprogramokkal történı illusztrálásával folytatódik. A téma felvezetésekor és az elmélet tárgyalásakor mindig kiemelt helyet kap a tárgyalt rész gyakorlati jelentıségének bemutatása. Az elsajátítandó technológiák és eszközök magyarázatait ahol szükséges ábrákkal tettem érthetıbbé. A témakörök tartalmát és terjedelmét úgy alakítottam ki, hogy egy laboratóriumi alkalom során egy fejezet otthoni elızetes készülést követıen végigkövethetı legyen. Tapasztalatom, hogy a tanulás akkor a leghatékonyabb, ha az elméletet azonnal gyakorlatba ültetjük, és addig nem haladunk tovább, amíg minden, megvalósítást érintı kérdést nem tisztáztunk; ezért szemléletes mintapéldákkal mutatom be az éppen tárgyalt technológiát. Továbbá az elıbbit erısítve, minden fejezet végén egy a tanultak használatát igénylı önállóan megoldandó feladatot fogalmazok meg. Ezek a feladatok kis lépcsıfokokként alkalmanként nem jelentenek nagy kihívást a hallgatók számára, viszont fokozatosan már egy bonyolultabb párhuzamos algoritmus megírására készítenek fel. A laboratóriumi foglalkozások elvégzése az adott fejezet elızetes elolvasását igényi. A hallgatók felkészültségének mérésére, illetve a számonkérések elıkészítésére, de elsı sorban a hallgatók tanulásának támogatására, ellenırzı kérdéseket fogalmaztam meg. Ezek az ellenırzı kérdések az adott fejezetben leírtakra kérdeznek rá, és a rájuk adott válaszok tételesen és a kérdések sorrendjében megtalálhatók a leírásban. I.3. Mintapéldák jellegzetességei Minden fejezethez tartozik példaprogram: a fontosabbakhoz több, a kevésbé fontosakhoz kevesebb. A legegyszerőbb hello programtól a bonyolult párhuzamos algoritmus mintamegoldásáig összesen harmincöt példaprogramot készítettem. A példaprogramok mindig az elméleti rész szorosan összetartozó egységei után következnek, és középpontjukban mindig az ismertetett technológia áll. Tehát a példaprogramok kipróbálására szóló felhívásokat az elméleti leírásba ágyaztam, hogy ezzel is ergonómikusabbá és könnyebben tanulhatóvá tegyem az oktatási segédanyagot. A példaprogramok a bonyolultabb algoritmusokat leszámítva rendszerint a standard kimenetre írnak, átláthatóbbá téve a bemutatott technológia mőködését. A példaprogramok közül kiemelném a párhuzamosan futó processzek szempontjából kritikus eseteknek, a holtpontoknak a lehetséges okaira rámutató és azokat kiküszöbölı példaprogramokat. Az MPI eszköztárának megismerésén és használatán túl a példaprogramok a programozó elıl elrejtett implementáció mőködésének megismerését is célozzák. Összefoglalva törekedtem arra, hogy a gyakran felmerülı kérdéseket megelızve, a példaprogramok az MPI eszköztárának használatát tisztázva, azokat precízen bemutassák. A példaprogramok a könnyebb kipróbálhatóság érdekében a CD mellékleten találhatóak. 10

11 II. Tananyag bemutatása II.1. Bevezetés a párhuzamos programozás elméletébe A párhuzamos programozás [2] során nagyszámú akár többmagos processzorú számítógépet úgy kapcsolunk össze, hogy a független processzorok egymással egyidıben dolgozhassanak egy komplex probléma egy-egy kis részén. Így olyan feladattal is boldogulunk, ami túl nagy lenne egyetlen számítógép számára. Ahhoz, hogy élhessünk a párhuzamos számítás elınyeivel, a programunkat párhuzamossá kell tennünk, hogy kiértékelése egynél több processzen történhessen egyszerre, ahol egy processz alatt a program (vagy alprogramjának) egy példányát értjük, amint autonóm módon egy fizikai processzoron kiértékelıdik. A párhuzamos programozás elsıdleges célja, hogy számítási teljesítmény-növekedést érjünk el ugyanazon program soros végrehajtásához képest. II.1.1. Miért fontos a párhuzamos programozás? Nagy számítás igényő tudományos problémák [3] megoldása A tudományos problémák komplexitása és nagy adatmérete nagy számítási kapacitást igényel. Ilyen például a biomolekulák kutatása, az idıjárás elırejelzés és a globális felmelegedés modellezése; de említhetünk olyan példát is, amit sokkal közelebb érzünk a mindennapjainkhoz: például az autópályák forgalmának elırejelzése, modellezése a dugók elkerülése céljából. Technológiai határ elérése A rendelkezésre álló számítási kapacitás sosem volt elegendı, hogy kiszolgálja a növekvı igényeket, ezért a 80-as években amikor úgy tőnt, hogy elérték a technológiai határt a párhuzamos programozás fejlesztésébe kezdtek. Napjainkban újra nagy teret kap a párhuzamosítás, és jelentıs energiákat fordítanak a párhuzamos programozás fejlesztésére és szabványosítására. Többmagos processzorok alkalmazásának felfutása A többmagos processzorok elterjedésével a párhuzamos programozás hatékony eszközt ad a kezünkbe ezek számítási kapacitásának kihasználására. II.1.2. A hatékony párhuzamos számításhoz szükséges hardver és szoftver adottságok A National Science Foundation Office of Cyberinfrastructure a párhuzamos számítás következı sarokköveit fogalmazta meg [4]: A processzorok és a memória összekapcsolódásának gyors kommunikációt kell biztosítania a független processzorok között, valamint gyors adatátvitelt a memóriával. Rendelkezésre kell állnia egy protokollnak, ami a processzek összekapcsolódását definiálja. A megoldandó számítási problémának és a feldolgozandó adatnak hatékonyan kisebb, egymástól független egységekre bonthatónak kell lennie. A mechanizmusnak alkalmasnak kell lennie arra, hogy a részfeladatokat különbözı processzekhez rendelje. 11

12 II.1.3. Architektúra modellek A számítógép architektúrákat és programozási modelleket az adat és az utasítás mennyiségének függvényében a Flynn-féle osztályozás [5] négy csoportra osztja. Egy utasítás végrehajtása egy adaton. Single Instruction Single Data (SISD) Több utasítás végrehajtása egy adaton. Multiple Instruction Single Data (MISD) Egy utasítás végrehajtása több adaton. Single Instruction Multiple Data (SIMD) Több utasítás végrehajtása több adaton. Multiple Instruction Multiple Data (MIMD) Párhuzamos programozás során a több adattal (MD) dolgozó modelleket használjuk. A SIMD architektúra esetében ugyanolyan processzek értékelıdnek ki, a MIMD architektúra esetében pedig különbözı processzek is, amelyek egymástól részben függetlenül hajtódnak végre. A processzek futhatnak ugyanazon processzoron is, de a párhuzamos számítás akkor a leghatékonyabb, ha minden processzt egy külön processzorhoz rendelünk hozzá. A MIMD architektúra kétféle módon valósítható meg: közös memóriával [6] vagy elosztott memóriával [6]. A közös memóriás MIMD architektúra esetén a processzorok és a memóriák oly módon vannak összekapcsolva, hogy minden processzor hozzáférhet minden memóriához (1. ábra). Az összekapcsoló hálózat adatátviteli szélessége korlátozza a szükséges kommunikáció mennyiség miatt a processzorok számát. 1. ábra A fı memórián kívül a számítógépek két további memóriával is rendelkeznek: regiszterekkel és cache-sel. A regiszterek nagyon gyors, processzoron belüli memóriák, amik azokat az adatokat tárolják, amin a processzor éppen dolgozik. A regiszterek gyorsaságuk miatt költségesek, ezért mennyiségük az összes memóriához képest kicsi. A cache memória ugyan lassabb a regisztereknél, de jóval gyorsabb a fı memóriánál. Így az ára is olcsóbb a regisztereknél, viszont drágább a fı memóriánál. Használata azon a tapasztalaton nyugszik, hogy mind az utasítások, mind az adatok esetében többnyire szekvenciálisak a memória-hozzáférések, így az éppen szükséges kis mennyiségő szekvenciális utasítás és adat cache-ben való elhelyezésével jelentıs mértékben csökkenthetı a fı memóriához való látszólagos hozzáférési idı. Valójában a cache és a regiszterek között állandóan és kis egységekben történik az adatforgalom, míg a fı memória és cache között ritkábban és nagyobb egységekben (2. ábra). A cache különösen nagy szerepet kap a közös 12

13 memóriás architektúrák esetén, hiszen a több processzor egyidejő memória-hozzáférési kísérlete telítheti a buszt, jelentıs késleltetést okozva mind az adat, mint az utasítás hozzáférésekben. 2. ábra Bár a cache használata nagymértékő hozzáférési idı csökkenéshez vezet, alkalmazásával viszont az adat-konzisztencia problémájával szembesülünk. Ez abból fakad, hogy a közös memória használat révén több processzor olvashat és írhat át egyazon változót. Például, ha az A processzor hozzáfér egy olyan változónak az A processzor cache-ében tárolt másolatához, amit ezt megelızıen egy B processzor megváltoztatott (a saját cache-ében és esetleg már a fı memóriában is), akkor az A processzor már hibás, érvénytelen adattal dolgozik. Az ily módon kialakuló adat-inkonzisztenciát az adatforgalom figyelésével és a közös változók idıben való frissítésével küszöbölhetjük ki. Az elosztott memóriás MIMD architektúra esetén minden processzor saját memóriával rendelkezik (3. ábra). Lényegében különálló számítógépek kapcsolódnak össze egy feladat kiszámítása céljából. Az egyes számítógépeket node -oknak hívjuk. Minden node-nak gyors hozzáférése van a saját memóriájához, ezenkívül más node memóriájához is, amit nagysebességő összekapcsoló hálózat biztosít. Mivel egy tisztán elosztott memóriás architektúra esetén a memória nem közös, ezért a más node-ok memóriájában lévı adatok elérését a párhuzamos programozás eszköztára teszi lehetıvé. 3. ábra A nagy teljesítményő párhuzamos számítást biztosító architektúrák egyik legújabb változata a Symmetric Multi-Processing (SMP) [7], amely ötvözi a közös memóriás és az elosztott memóriás modelleket. Másként fogalmazva: közös memóriás architektúrák 13

14 kapcsolódnak össze nagysebességő hálózattal. Ez esetben egy-egy közös memóriás architektúra felel meg egy-egy node -nak, és ezek a node-ok az elosztott memóriás architektúrának megfelelıen kapcsolódnak össze. II.1.4. Párhuzamos programozási modellek Üzenet-átadásos módszer Ahogy a neve is takarja, a processzek üzenetekkel kommunikálnak egymással. Ennek a modellnek a legelterjedtebb standard interfészét nevezzük Message Passing Interface-nek (MPI) [8]. Hasonló feladatokra alkalmas a Parallel Virtual Machine (PVM) [9] is. Az üzenetküldéses modell használata leginkább az elosztott memóriás rendszerekre jellemzı, de a közös memóriás és az SMP architektúrákra is alkalmazható. Ez utóbbi esetekben viszont az üzenetküldéses megközelítésbıl fakadóan a közös memória, mint elıny nincs kihasználva. Közös memóriás módszer Ezen modell használata a közös memóriás architektúrákon terjedt el, mert a közös memória nagyban leegyszerősíti a fordítók írását. Ez a módszer jellemzıen úgy nyilvánul meg, hogy a soros kódot kommentszerő utasításokkal (direktívákkal) egészítjük ki, amelyek kijelölik, hogy a fordító milyen arányban ossza szét az adatokat és az elvégzendı feladatokat a processzorok között; viszont az adatszétosztás és számítás valamint a processzorok közötti kommunikáció részletei a fordítóra vannak bízva. Példaként említhetı az OpenMP [10]. Egy másik standard interfész a High Performance Fortran (HPF) [11], amely mind elosztott memóriás, mind közös memóriás architektúrákon alkalmazható. Az HPF hátránya, hogy bár SMP architektúrákon is használható, de nem támogatja a hierarchikus struktúrákat, így ezek egyszerően elosztott rendszerekként kezelıdnek. Mind az OpenMP-t, mind az HPF-t elsısorban hurkok párhuzamosítására használják, amely kismértékő párhuzamosítás és az MPI által megvalósítható program szintő párhuzamosítás között jelentıs hatékonyságbeli különbség figyelhetı meg az MPI javára. Új megközelítés A hatékonyság fokozását célzó törekvés, mely az MPI elosztott memóriás és üzenetátadásos modelljét ötvözi az OpenMP közös memóriás és többszálú modelljével egyetlen párhuzamos modellben SMP architektúrára alapozva. II.1.5. MPI bevezetı Az MPI (Message Passing Interface) a nagy számításteljesítményő üzenet-átadásos párhuzamos programozás standard interfésze, ami azt jelenti, hogy olyan C függvények győjteménye, amik mindegyike a processzek közötti kommunikáció támogatására szolgál. Az MPI bár meghívható függvényeket tartalmaz, mégsem könyvtár, hanem szabvány, aminek több megvalósítása, implementációja létezik. Az MPI program legalább két processzbıl áll, amelyek egyedi azonosítóval rendelkeznek, és amelyek egymással párhuzamosan hajtódnak végre. A processzek MPI függvényekkel kommunikálnak egymással, miközben egyenként egy nagy számítási feladat egy-egy kis részén dolgoznak. Az MPI elsı verziójában nem lehet futási idıben, dinamikusan processzt létre hozni, hanem a processzek számát futtatás elıtt rögzíteni kell. 14

15 II.1.6. Egy egyszerő MPI program bemutatása Az MPI egy szabvány, melynek több implementációja létezik. Munkám során az MPI LAM (Local Area Multicomputer) [12] implementációját használtam, amit Linux operációs rendszeren internet kapcsolat mellett a sudo apt-get install lam-dev paranccsal lehet telepíteni. Az alapértelmezett beállításoktól eltérı konfigurációhoz egy többlépéses telepítésen kell végighaladni, ami párhuzamos algoritmusok bemutatásához szükségtelen, így nem térünk ki rá. Tekintsük az alábbi egyszerő kódot! --- hello.c --- #include <stdio.h> #include <mpi.h> // MPI header file importálása int main(int argc, char *argv[]) { int nprocs, myrank; MPI_Init(&argc,&argv); // MPI inicializálása MPI_Comm_size(MPI_COMM_WORLD, &nprocs); // Hány processz indult? MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // Mi az azonosítóm? printf("hello, az azonositom: %d (a %d db processzbol)\n", myrank, nprocs); } MPI_Finalize(); return 0; // MPI leállítása Az MPI függvényekkel kibıvített C kód lefordítása elıtt el kell indítanunk a LAM-ot a lamboot paranccsal. Ezt követıen a LAM mindaddig futni fog, amíg a lamhalt paranccsal le nem állítjuk. Az MPI programok futtatásához a LAM futása szükséges, hiszen a LAM valósítja meg az MPI-t. A kódunkat az mpicc -o hello hello.c paranccsal fordítjuk le. A lefordított kód futatásának elindításakor megadjuk, hogy hány példányban fusson le a kódunk, azaz hány processz induljon. A példában szereplı program olyan, hogy mindegyik processz ugyanezt hajtja végre. Például, ha négy példányban szeretnénk futtatni, akkor ezt az mpirun -np 4 hello paranccsal tesszük. Az MPI header file importálásán és a változók deklarálásán kívül a legelsı lépés az MPI inicializálása. Ezt követıen érdemes csak a C utasításokat használni, mert az MPI szabvány nem definiálja, hogy az MPI inicializálása elıtt lévı C utasításokat minden processznek végre kell-e hajtania. Elkerülve az MPI implementációk közötti különbségekbıl fakadó hibákat, a kód hordozhatóságát támogatva, érdemes ennek megfelelıen eljárni. Az MPI_Comm_size(MPI_COMM_WORLD, &nprocs); függvénnyel lekérdezzük, hogy összesen hány process indult, és számuk az nprocs változóba kerül. Az MPI_Comm_rank(MPI_COMM_WORLD, &myrank); függvénnyel lekérdezzük a processz egyedi azonosítóját, amire minden processz más-más választ kap, és ez az adott processz myrank változójába kerül. Ez alapján, az azonosító alapján tudjuk megkülönböztetni a processzeket, és a kommunikáció során is ezt használjuk a címzéshez. 15

16 A szükséges mőveletek, számítások jelen esetben standard kimenetre írás után leállítjuk az MPI-t és visszatérünk a main függvénybıl. A program futásának eredménye a következı: Hello, az azonositom: 1 (a 4 db processzbol) Hello, az azonositom: 2 (a 4 db processzbol) Hello, az azonositom: 3 (a 4 db processzbol) Hello, az azonositom: 0 (a 4 db processzbol) Az, hogy a processzek milyen sorrendben írnak a standard kimenetre nincs definiálva, és jelentısen függ a végrehajtó architektúrától. Ha befejeztük az MPI programjaink futtatását, akkor fontos, hogy a fent leírt módon leállítsuk a LAM-ot. Ellenırzı kérdések: 1.) Hogyan érünk el számítási teljesítmény-növekedést a párhuzamos programozás alkalmazásával? 2.) Miért fontos a párhuzamos programozás? 3.) Mik a hatékony párhuzamos számításhoz szükséges hardver és szoftver adottságok? 4.) A számítógép architektúrákat és programozási modelleket mi alapján osztja fel a Flynn-féle osztályozás? Mik ezek a csoportok, és közülük melyeket használjuk a párhuzamos programozás során? 5.) A közös memóriás MIMD architektúra esetén mi jellemzı a processzorok és a memóriák kapcsolatára? Adat inkonzisztenciához vezethet-e ebben az esetben a cache használata? 6.) Mi a cache memória használatának elınye és hátránya? 7.) Az elosztott memóriás MIMD architektúra esetén mi jellemzı a processzorok és a memóriák kapcsolatára? Adat inkonzisztenciához vezethet-e ebben az esetben a cache használata? 8.) Mi a fı koncepciója az üzenetküldéses párhuzamos programozási modellnek? Milyen architektúrán terjedt el leginkább? Milyen szintő párhuzamosítás jellemzı rá? 9.) Mi a fı koncepciója a direktíva alapú párhuzamos programozási modellnek? Milyen architektúrán terjedt el leginkább? Milyen szintő párhuzamosítás jellemzı rá? Feladatok: 1.) Üzemeljük be az MPI-t megvalósító LAM-ot! 2.) Próbáljuk ki az hello.c példaprogramot! 16

17 II.2. Párhuzamos programozási szemlélet kialakítása II.2.1. Az MPI által definiált párhuzamos programozási eszköztár fıbb elemei A kommunikációt menedzselı függvények Ide tartozik az MPI kommunikáció inicializálása és lezárása, a processzek számának és azonosítójának lekérdezése, valamint a processzek között alcsoportok kialakítása. Pont-pont kommunikációt megvalósító függvények Ez a fajta kommunikáció mindig processzpárok között történik. Minden üzenetet a küldésen kívül fogadni is kell. Ezen kommunikációt lebonyolító függvényeknek több változata van, melyek közül a megfelelı kiválasztásához a futási idıbeli kommunikáció megtervezésére és átlátására van szükség. Csoporton belüli kommunikációt megvalósító függvények Ezt a fajta kommunikációt kollektív kommunikációnak hívjuk, mert egy processzcsoport tagjai között zajlik. Az ide tartozó függvényeket rendkívüli hatékonyságuk miatt használjuk. Az egyszerő üzenetszóráson kívül sokkal komplexebb üzenetküldési módok is rendelkezésünkre állnak. Például egyetlen függvényhívással megvalósítható, hogy egy processz bufferében lévı adatokat feldaraboljunk és szétosszunk az összes processz között; vagy ennek az ellentéte, hogy összegyőjtsünk különbözı processzek buffereibıl adatokat egy processz bufferébe. Az adatok összegyőjtése közben ráadásul tetszıleges mőveletet végezhetünk rajtuk, és ekkor csak a végeredmény érkezik meg az üzenetet fogadó processzre. Továbbá lehetıség van több processzrıl több processzre küldeni adatokat egyetlen függvényhívással. Tetszıleges adatstruktúrák kialakítására szolgáló függvények Lehetıség van összetett, a megoldandó feladathoz leginkább illeszkedı adatstruktúrák létrehozására, küldésére és fogadására. II.2.2. A feladat részfeladatokra bontása és a részfeladatok processzekhez rendelése Alapvetıen két dolgot lehet részekre bontani: a feldolgozandó adatokat és az elvégzendı mőveleteket. A részekre bontás célja, hogy az egyes részek egymással párhuzamosan, azaz egyidıben hajtódjanak végre, így nyerve idıt a soros végrehajtáshoz képest. Viszont a kommunikációra fordított idıvel romlik a hatékonyságunk. A fentiek miatt a probléma megoldása során használt modell kitalálása meghatározó jelentıséggel bír a program megírásának késıbbi menetére. A párhuzamos programunk leprogramozása elıtt tehát érdemes alaposan megvizsgálnunk, hogy a problémát milyen módon lehet a legoptimálisabban párhuzamosítani. Tekintsük a következı, nagy adathalmazon viszonylag egyszerő mőveleteket végrehajtó szekvenciálisan kiértékelıdı programot! 1. melléklet: main2_2.c 17

18 A program egy 24 bit/pixel színmélységő tetszıleges BMP képen végez mőveleteket, majd az eredményt egy új BMP fájlba menti. Elsı ránézésre kitőnik, hogy a fájlkezelést leíró kódrész nagyságrendekkel hosszabb a mőveletvégzést leíró kódrésznél. Amennyiben nagymérető képen végzünk mőveleteket, akkor mégis a mőveletvégzéshez szükséges idı a jelentısebb. A program párhuzamosításakor fájlkezelést és feldolgozó mőveleteket különböztethetünk meg egymástól. A fájlkezelés megléte miatt érdemes master - slave (munkavezetı - dolgozó) modellt alkalmazni. A fájlmőveleteket a masterhez, a feldolgozó mőveleteket pedig a slave processzekhez rendeljük. A feldolgozandó adatokat minél több részre osztjuk, annál nagyobb a párhuzamosítás hatásfoka. Szükség esetén a master processz is végezhet mőveleteket, de ekkor hatékonyság szempontjából szők keresztmetszetté válik, hiszen amíg feldolgozó mőveleteket végez, addig nem tud adatszétosztással és összegyőjtéssel, valamint fájlkezeléssel foglalkozni. Úgy képzeljük el a párhuzamos programunkat, hogy minden processzorhoz egyetlen processzt rendelünk, de ezt a hozzárendelést az MPI-t megvalósító LAM teljesen elrejti elılünk. A párhuzamos programot úgy írjuk meg, hogy bizonyos speciális feladatokhoz egyegy külön processzt rendelünk, a feldolgozó mőveletekhez pedig egy tetszıleges tagszámú csoportot. Tehát olyan programot írunk, aminek futtatása elıtt paraméterként megadjuk, hogy hány példányban hajtódjon végre. A mőveletek végrehajtása közben szükséges, hogy a processzek kommunikáljanak egymással. A master processz beolvassa a fájlból az adatokat, részekre osztja és szétküldi a slave processzeknek. Gyakran elıfordul, hogy a slave processzeknek, ahhoz, hogy fel tudják dolgozni a master processztıl kapott adatokat, egymással is kommunikálniuk kell. A jelen képfeldolgozás esetében az egyes processzek képrészletének szélén lévı pixelek feldolgozásához a szomszédos pixelek ismerete szükséges, melyek más processzek képrészletéhez tartoznak. Az adatokat úgy érdemes szétosztani a processzek között, hogy a mőveletvégzés során minél kevesebb kommunikációra legyen szükség, hiszen a kommunikációra fordított idı rontja a hatékonyságot a szekvenciálisan végrehajtható soros programhoz képest. A képfeldolgozás esetében sávokra érdemes osztani a képet, hogy csak két szomszédos processzel kelljen kommunikálnia minden processznek. Egyforma számítási teljesítményő processzorokból álló architektúrát feltételezve amit az MPI-t megvalósító LAM elrejt elılünk, egyforma mérető sávokat készítünk, illetve egy megmaradó kisebbet. Terhelés kiegyensúlyozás Amikor például azt vizsgáljuk, hogy az elıbb említett kisebb sáv hozzárendelhetı-e a master processzhez, vagy már szők keresztmetszetté tenné a rendszer számítási teljesítménye szempontjából, akkor a terhelés optimális elosztását keressük. A rendelkezésünkre álló architektúrát a lehetı legjobban kell kihasználnunk, amit a processzek és hozzájuk rendelhetı feladatok megfelelı párosításával érünk el. Olyan módon kell szétosztanunk a processzek között a terhelést, hogy minimalizáljuk azt az idıt, amikor egyes processzek várakoznak, miközben mások dolgoznak; különben elpazaroljuk a számításra fordítható erıforrásainkat. A terhelés kiegyensúlyozás azonos mőveleteket végzı processzek esetében kézenfekvı; míg különbözı feladatokat ellátó processzek között már mélyebb meggondolást igényel. 18

19 II.2.3. Futási idı vizsgálata A futási idı minden processz esetében alapvetıen három részre osztható: Számításra fordított idı A mőveletvégzésre, számolásra fordított idı az egyedüli hasznos dolog a számunkra, mert mind a várakozással, mind a kommunikációval romlik a hatékonyságunk. Amiatt írunk párhuzamos programokat, hogy a végrehajtáshoz, lefuttatáshoz szükséges idıt radikálisan lecsökkentsük. Optimális esetben, n számú processzel számolva, a soros végrehajtáshoz szükséges idı 1/n-szerese alatt végeznénk, de az elkerülhetetlen kommunikáció és (minimális várakozás) miatt ez a javulási arány teljesen nem érhetı el. Várakozással töltött idı Várakozási idınek azt az idıt nevezzük, amikor egy processz más processzektıl vár adatokat, és közben semmilyen hasznos munkát nem végez. Leggyakrabban a fájlmőveletek miatt várakoznak processzek, ugyanis ezt általában mindig egyetlen processz végzi. A várakozási idı futási idıt lassító hatásának csökkentését a mőveletvégzés és a kommunikáció egymással való átlapolásával érhetjük el. Ehhez rendelkezésre állnak olyan pont-pont kommunikációt megvalósító függvények, amiknek nem kell visszatérniük ahhoz, hogy az utánuk következı kód kiértékelıdhessen. Kommunikációhoz szükséges idı Az adatok küldéséhez és fogadásához szükséges idı egyértelmően hátrány a soros program futási idejéhez képest. Az MPI által definiált függvények széles választékából a kommunikációs folyamat optimálisan megtervezhetı, minimalizálva ezzel a kommunikációhoz szükséges idıt. Ellenırzı kérdések: 1.) Mik az MPI által definiált párhuzamos programozási eszköztár fıbb elemei? Hogyan jellemezhetık röviden? 2.) Mindig egyenes arányosság van a kódrészek hosszúsága és a hozzájuk tartozó futási idık között? Hogyan befolyásolja ez a feladatok processzekhez rendelését? 3.) Milyen irányelveket tartunk szem elıtt a terhelés kiegyensúlyozás megtervezésekor? 4.) Milyen fıbb részekre bontható a futási idı? Ezek közül melyik a hasznos, és melyek a hátrányosak a párhuzamos programozás hatékonyságának szempontjából? Feladatok: 1.) Tanulmányozzuk át az 1. mellékletben található main2_2.c soros programot és gondolkodjunk el rajta, hogyan párhuzamosítanánk azt! A gondolatmenetünket írjuk le, vagy rajzoljuk el! 19

20 II.3. Pont-pont kommunikáció és fajtáinak megismerése Az MPI az üzenetküldéses párhuzamos programozás standard interfésze, tehát alapvetıen kommunikációs formákat definiál. A legalapvetıbb közülük a két processz közötti pont-pont kommunikáció. Elsı megközelítésre egyszerőnek tőnik, hogy egy adott üzenetet az egyik processz oldalán el kell küldeni, és a másik oldalán fogadni kell. A gyakorlatban viszont bár tényleg csak egy küldı és egy fogadó függvényt kell használni, mégis alapos megfontolást igényel a használatuk. Például, ha egy processznek egyszerre több üzenetet küldenek, akkor melyiket fogadja el? A kérdést közelebbrıl megvizsgálva, valójában, ha az idınek megfelelıen kis felbontásával rendezzük sorba az üzenetek küldésének idıpontját, akkor a kérdés megoldódni látszik. A gyakorlatban viszont nem az üzenetek küldésének idıpontja a mérvadó, hanem hogy az adott processz mikor jut a programjának azon részére, amikor az üzenetek fogadásával tud foglalkozni. Tehát a helyzet inkább ahhoz hasonló, mint amikor az embernek megtelik a postaládája. Mi is csak akkor vesszük észre, hogy üzeneteink érkeztek, amikor megnézzük a postaládánkat. Ezt követıen ahogy nekünk is, a processznek is el kell döntenie, hogy milyen sorrendben dolgozza fel az üzeneteket. A másik, kommunikációt árnyaló kérdés, hogy mibıl tudja az üzenetet küldı processz, hogy akinek az üzenetet küldte, az már annak az ismeretében dolgozik-e tovább? Erre létezik minden pont-pont kommunikációt megvalósító függvénynek blokkoló és nem blokkoló változata. A blokkoló függvények addig nem térnek vissza, amíg a másik oldalon a címzett processz nem fogadta az üzenetet; a nem blokkoló függvények pedig a címzett processz fogadásától függetlenül visszatérnek. A blokkoló függvények esetében elıny az üzenet fogadásának bizonyossága, hátrány viszont a várakozási idı; a nem blokkoló függvények esetében pedig az az elıny, hogy nincs várakozási idı, viszont hátrány, hogy nincs visszajelzés az üzenet fogadásáról. II.3.1. Az üzenetküldéses modell elemei Forrás- és célprocessz A pont-pont kommunikáció megvalósításában az MPI-ban mindkét oldalnak aktívan részt kell vennie. Az egyik processz küldi az üzenetet (forrásprocessz), a másik processz pedig fogadja (célprocessz). Általában a forrásprocessz és a célprocessz egymáshoz képest aszinkron módon dolgoznak, így az üzenetek küldése és fogadása is aszinkron módon történik. Emiatt fordulhat elı olyan eset, hogy a forrásprocessz már jóval azelıtt elküld egy üzenetet, mielıtt a célprocessz észlelné annak érkezését. Ugyanígy, az aszinkronitásra vezethetı vissza az az eset is, amikor a célprocessz elıbb fogadna egy üzenetet, mint azt a forrásprocessz elküldi. Üzenet felépítése Egy üzenet alapvetıen két fı részbıl áll: borítékból és tartalomból. Ezek jelentése nagyon hasonló a hagyományos postai gyakorlatban megszokottakhoz. A boríték tartalmazza a forrásprocessz és a célprocessz azonosítóját, annak a kommunikátornak a nevét, amelybe mindkét processz tartozik, és egy üzenetcímkét. A kommunikátor egy processz csoportot jelöl, amelybe a forrás- és célprocessz is beletartozik. A kommunikátor onnan kapta a nevét, hogy csak az egy csoportba, kommunikátorba tartozó processzek kommunikálhatnak egymással. A látszattal ellentétben, ez inkább támogatás, mint megkötés, mert az MPI_COMM_WORLD kommunikátorba minden processz beletartozik, és a további kommunikátorok létrehozásával csak 20

21 a kommunikációs lehetıségeinket növeljük (nagyban támogatva a késıbb bemutatott csoportos kommunikációt). Az üzenetcímke az üzenetek árnyaltabb beazonosítására szolgál, hiszen adott forrás- és célprocessz között is lehet egyszerre több üzenet. Az üzenet tartalma egy adattömbként, bufferként képzelhetı el, amely mellett rendelkezésünkre áll a tömb adattípusa és a mérete is, hogy hány darab adattípusban definiált egységet tartalmaz. Azáltal, hogy az MPI ilyen strukturált módon definiálja az üzenetek tartalmát, nagyban támogatja, hogy különbözı számábrázolást használó számítógépek is összekapcsolódhassanak, valamint a tetszıleges adattípus definiálásának lehetıségével leegyszerősíti az összetett adatstruktúrák átvitelét is. Függı üzenetek Az üzenetküldés menete addig, hogy a forrásprocessz kezdeményezi az üzenetküldést, egyértelmő; az üzenet borítékának és tartalmának átvitele viszont már összetettebb. Ez utóbbit az MPI-t megvalósító LAM elrejti elılünk, de a helyesen mőködı párhuzamos program tervezésekor fontos érteni, hogy mi történik a háttérben. Mivel az üzenetek küldése és fogadása nem szinkronizált, ezért a processzekre gyakran vár egy vagy több olyan üzenet, amit már elküldtek, de még nem fogadtak. Ezeket függı üzeneteknek nevezzük. Az MPI egy fontos tulajdonsága, hogy a függı üzeneteket nem rendezi FIFO sorba, hanem lehetıséget ad a célprocessznek, hogy az üzenetek tulajdonságai alapján választhasson közülük, hogy melyiket fogadja. Az üzenetfogadáshoz a célprocessz egy fogadó borítékkal rendelkezik, amit az MPI a függı üzenetek borítékjaihoz hasonlít, és ha egyezést talál, akkor a célprocessz fogadja az adott üzenetet. Ha nincs egyezés, akkor a fogadás mindaddig nem fejezıdik be, amíg a megfelelı üzenetet el nem küldték. Emellett a célprocessznek rendelkeznie kell az üzenet tartalmának fogadásához elegendı szabad memória területtel, amit mindig elızetesen kell lefoglalnia. II.3.2. Blokkoló függvények II A blokkoló függvények felépítése A legalapvetıbb pont-pont kommunikációs függvények az MPI_Send és az MPI_Recv. Mindketten blokkolják a hívó processzt, amíg a kommunikáció (üzenetátvitel) teljesen be nem fejezıdik. int MPI_Send ( void *buf, int count, MPI_Datatype dtype, int dest, int tag, MPI_Comm comm ); // Küldendı adatokat tartalmazó buffer // Küldendı adategységek száma // Adategység típusa // Célprocessz azonosítója // Üzenetcímke // Kommunikátor, melybe mindkét // processz beletartozik Az elsı három paraméter az üzenet tartalma, a második három pedig a boríték. Mivel az MPI_Send-et a forrásprocessz hívja meg, ezért elegendı csak a célprocessz azonosítójának a megadása az üzenetcímke és a kommunikátor megjelölése mellett. Tehát minden paraméter bemenı. Ha a mővelet sikerült, akkor MPI_Success-szel tér vissza a függvény. Ha ezt nem is vizsgáljuk, a függvény akkor sem fog addig visszatérni, amíg az üzenetküldés teljesen be nem fejezıdött. 21

22 int MPI_Recv ( void *buf, int count, MPI_Datatype dtype, int source, int tag, MPI_Comm comm, MPI_Status *status ); // Fogadó buffer // Maximum fogadható // adategységek száma // Adategység típusa // Forrásprocessz azonosítója // Üzenetcímke // Kommunikátor, melybe mindkét // processz beletartozik // Információ a fogadott üzenetrıl Az elıbbivel megegyezik a paraméterek sorrendje, ugyanakkor néhánynak közülük más a jelentésük és egy paraméterrel több van. Míg az elıbbi esetben a buf a küldendı adatokat tartalmazó buffert jelentette, addig itt a fogadó buffert, amit az üzenet fogadása elıtt elızetesen le kell foglalnunk a memóriában. A count mindkét esetben az adategységek számának megadására szolgál, ám míg az MPI_Send esetében a ténylegesen elküldeni kívánt adategységek számát jelenti, addig az MPI_Recv-nél a fogadó buffer méretét. Az azonos adattípus használata mind a küldı, mind a fogadó oldalon a programozó felelıssége; ugyanis eltérés esetén a kimenetel definiálatlan. Az MPI_Recv esetében a source és tag paraméterek arra szolgálnak, hogy a célprocessz a függı üzenetek közül kiválaszthassa azt, amelyikre szüksége van. A forrás azonosítójának helyén, illetve az üzenetcímke helyén használhatunk joker azonosítót, illetve címkét, és ekkor bármilyen forrásprocessztıl bármilyen üzenetcímkével fogadhatunk üzeneteket. Ennek tipikus alkalmazása a master processz esete, amikor az bármelyik slave processz üzenetküldését válogatás nélkül fogadja. A korábbi két paraméterrel ellentétben a kommunikátort mindig egyértelmően kell megadnunk. A status paraméterrel az üzenet fogadásával kapcsolatos információkhoz férünk hozzá. Például joker processzazonosító vagy üzenetcímke használata esetén, ennek segítségével kérdezhetjük le a küldı processz azonosítóját, az üzenet címkéjét, illetve a küldött adategységek számát. Az adategységek számának lekérdezésére azért van szükség joker azonosító vagy címke használata esetén, mert a különbözı üzenetek általában különbözı hosszúak; és mivel nem teljesen specifikált, hogy ki a két fél, az üzenet hosszát sem tudjuk elıre. A buf és a status kimenı paraméterek, a maradék öt pedig bemenı paraméter. Az MPI_Recv az MPI_Send-hez hasonlóan hibakóddal tér vissza, de csak akkor, ha az üzenetátvitel teljesen befejezıdött. Tekintsünk egy immár párhuzamosan megírt programot, melyben egy processz átküld egy tömböt egy másik processznek! 2. melléklet: main3_2_1.c Az MPI inicializálása után, a már megismert módon, lekérdezzük a processzek számát, illetve minden elindult processz lekérdezi az azonosítóját. Az azonosítókat használjuk feltételként, amikor a processzek között különbséget teszünk. Az üzenetet elıbb a 0 azonosítójú processz elküldi, majd az 1 azonosítójú fogadja. A program futtatásához elıször elindítjuk a LAM-ot a lamboot paranccsal. Ezt követıen lefordítjuk a kódot az mpicc -o main3_2_1 main3_2_1.c paranccsal. Két példányban való futtatáshoz az mpirun -np 2 main3_2_1 parancsot adjuk ki. 22

23 A program futásának eredménye a következı: 1.processz uzenetfogadas elott: processz uzenetfogadas utan: A LAM-ot a lamhalt paranccsal állíthatjuk le. II Joker processz-azonosító, illetve üzenetcímke használata Ha tetszıleges processztıl akarunk üzenetet fogadni, akkor az MPI_Recv függvényben a forrásprocessz azonosítójának helyére az MPI_ANY_SOURCE joker azonosítót írjuk. Tekintsünk egy olyan programot, amelyben a master processz a slave processzektıl tetszıleges sorrendben fogadja az adatokat! 3. melléklet: main3_2_2a.c A master processz tetszıleges sorrendben tudja fogadni az egyes slave processzek üzeneteit, tehát a joker processz-azonosító használatával kiküszöböltük, hogy az egyes slave processzeknek a sorukra kelljen várniuk. Amint egy processz végzett a munkájával, egybıl kiszolgálja a master. A slave processzek beazonosítása az MPI_Status típusú status struktúra status.mpi_source változójából kinyerhetı információval történik. Ha tetszıleges üzenetcímkével akarunk üzenetet fogadni, akkor az MPI_Recv függvényben az üzenetcímke helyére az MPI_ANY_TAG joker üzenetcímkét írjuk. Ekkor az üzenetcímke értékét az MPI_Status típusú status struktúra status.mpi_tag változójából nyerhetjük ki. Akár a processz-azonosító és az üzenetcímke helyére is tehetünk egyszerre jokert, lehetıvé téve, hogy több processztıl, többféle üzenetet fogadhassunk azok küldési sorrendjében, minimalizálva a blokkoló függvényekre jellemzı várakozási idıt. Tekintsünk egy olyan programot, amelyben a master processz a slave processzektıl tetszıleges sorrendben különbözı mérető tömböket fogad! 4. melléklet: main3_2_2b.c A fogadott adattípus és az MPI_Recv függvény által visszaadott status változó ismeretében az MPI_Get_count függvénnyel lekérdezhetjük a ténylegesen küldött adategységek számát. int MPI_Get_count( MPI_Status *status, // Információ a fogadott üzenetrıl MPI_Datatype dtype, // Adategység típusa int *count ); // Ténylegesen küldött // adategységek száma Az egyetlen kimenı paraméter a count változó, hiszen a függvény a ténylegesen küldött adategységek számának meghatározására szolgál. Ne tévesszük össze az MPI_Recv függvényben szereplı buffer méretével! Az MPI_Get_count hibakóddal tér vissza. 23

24 A program futásának eredménye a következı: 0.processz uzenetfogadas elott: processztol 111 uzenetcimkevel 10 darab adat erkezett Ezek: processztol 222 uzenetcimkevel 5 darab adat erkezett Ezek: processz uzenetfogadas utan: II Hogyan valósítja meg az MPI az üzenetátvitelt? Ahhoz, hogy hatékony párhuzamos programot írhassunk, fontos értenünk, hogy minként kezeli az MPI az üzenetküldı és -fogadó függvényhívásainkat. Amikor meghívjuk az MPI_Send függvényt, akkor két dolog történhet: Az egyik, hogy az üzenet átmásolódik a forrásprocesszrıl az MPI egy belsı bufferébe, ahonnan majd késıbb a célprocesszre kerül; vagy a másik lehetıség, hogy az üzenet addig a forrásprocessz bufferében tárolódik, amíg a célprocessz készen nem áll annak fogadásra, amikor is megtörténik az átvitel. Az elsı esetben a forrásprocessz továbbdolgozhat, miután az MPI belsı bufferébe másolódott a küldendı üzenet. A második esetben pedig ugyan kevesebbszer kell bufferbıl bufferbe másolni, és a felhasznált memóriaterület is kisebb, viszont ami a párhuzamos programozás szempontjából nagy hátrány, az az, hogy a forrásprocessznek várakoznia kell a célprocesszel való szinkronizációra. Attól függıen, hogy a küldendı adat mérete nagyobb-e, mint az MPI rendelkezésre álló, belsı memóriaterülete, az üzenet vagy azonnal az MPI belsı bufferébe kerül, ahonnan késıbb aszinkron módon továbbítódik; vagy a küldı és fogadó processz egymáshoz szinkronizálódik. Mind az MPI_Send, mind az MPI_Recv blokkoló függvények, ami azt jelenti, hogy egyikük sem tér vissza az üzenetátvitel befejezéséig. Az MPI_Recv esetében elég intuitív módon adódik az üzenetátvitel befejezésének jelentése, ami tehát a fogadó borítékkal megegyezı borítékú levél teljes tartalmának a fogadó processz bufferébe való másolásának befejezése. Az MPI_Send esetében pedig azt jelenti az üzenetátvitel befejezése, hogy forrásprocessz az üzenetet teljes egészében átadta az MPI-nak. Ez jelentheti a célprocesszel szinkronizált adatátvitel befejeztét, de az MPI belsı bufferébe való adatátvitel befejeztét is. Tehát a lényeg az, hogy ekkor már a forrásprocessz buffere felülírható. II A holtpont oka, és elkerülésének módja Holtpont akkor alakul ki, amikor legalább két processz blokkoló függvényhívásaik miatt vár egymásra. Két, egymással üzenetet cserélı processz példáján mutatjuk be, hogy pontosan milyen függvényhívási sorrendek okoznak holtpontot. A következı esetben biztosan holtpont alakul ki, mivel mindkét processz elıbb fogadni akarja a másik üzenetét, amit a fogadó függvények blokkolása miatt egyikük sem tud elküldeni. if( myrank == 0 ) /* 0.processz */ { // Üzenetfogadás: 1.processz -> 0.processz MPI_Recv( fogad, 10, MPI_DOUBLE, 1, TAG1, MPI_COMM_WORLD, &status ); // Üzenetküldés: 0.processz -> 1.processz MPI_Send( kuld, 10, MPI_DOUBLE, 1, TAG0, MPI_COMM_WORLD ); } 24

25 else if( myrank == 1 ) /* 1.processz */ { // Üzenetfogadás: 0.processz -> 1.processz MPI_Recv( fogad, 10, MPI_DOUBLE, 0, TAG0, MPI_COMM_WORLD, &status ); // Üzenetküldés: 1.processz -> 0.processz MPI_Send( kuld, 10, MPI_DOUBLE, 0, TAG1, MPI_COMM_WORLD ); } A teljes program: 5. melléklet: main3_2_4a.c A holtpontmentes párhuzamos program tervezésének legbiztosabb módja, hogy logikusan végigvezetjük gondolatban, hogy a függvényhívások sorrendjébıl fakadó feltételrendszernek van-e feloldása. A párhuzamos programok írásánál ennek az átlátása kulcsfontosságú. Ugyanakkor miközben végigkísérjük a függvényhívások feltételrendszerét, a korábban említett terhelés kiegyensúlyozásra vonatkozó modellünkön is finomíthatunk, figyelembe véve az egyes feladatok idıszükségletét. A következı kommunikáció biztosan holtpontmentes, mert a különbözı üzenetek küldése és fogadása nincs egymással átlapolva. A soron lévı üzenetet elküldjük illetve fogadjuk, és csak ezt követıen kerül sorra a következı üzenet. Tehát, még ha a küldött üzenet nagyobb is, mint az MPI belsı buffere, az üzenetátvitel nem okoz holtpontot, mert a két processz a korábban megismert módon szinkronizálódik egymáshoz. if( myrank == 0 ) /* 0.processz */ { // Üzenetfogadás: 1.processz -> 0.processz MPI_Recv( fogad, N, MPI_DOUBLE, 1, TAG1, MPI_COMM_WORLD, &status ); // Üzenetküldés: 0.processz -> 1.processz MPI_Send( kuld, N, MPI_DOUBLE, 1, TAG0, MPI_COMM_WORLD ); } else if( myrank == 1 ) /* 1.processz */ { // Üzenetküldés: 1.processz -> 0.processz MPI_Send( kuld, N, MPI_DOUBLE, 0, TAG1, MPI_COMM_WORLD ); // Üzenetfogadás: 0.processz -> 1.processz MPI_Recv( fogad, N, MPI_DOUBLE, 0, TAG0, MPI_COMM_WORLD, &status ); } A teljes program: 6. melléklet: main3_2_4b.c Ha mindkét processz elıször elküldi az üzenetét és csak azután fogadnak, akkor szükséges, hogy legalább az egyik üzenet függı üzenetként az MPI belsı bufferébe kerülhessen, hogy a hozzá tartozó MPI_Send (az MPI-ra bízva az üzenetét) visszatérhessen, és az MPI_Recv függvény fogadhassa az üzenetet. Ez a kommunikációs sorrend akkor mőködik holtpontmentesen, ha az MPI belsı buffere akkora, hogy legalább az egyik üzenet teljes egészében elfér benne. A következı példaprogram N paraméterét változtatva a program hol lefut, hol holtpontra kerül. 25

26 if( myrank == 0 ) /* 0.processz */ { // Üzenetküldés: 0.processz -> 1.processz MPI_Send( kuld, N, MPI_DOUBLE, 1, TAG0, MPI_COMM_WORLD ); // Üzenetfogadás: 1.processz -> 0.processz MPI_Recv( fogad, N, MPI_DOUBLE, 1, TAG1, MPI_COMM_WORLD, &status ); } else if( myrank == 1 ) /* 1.processz */ { // Üzenetküldés: 1.processz -> 0.processz MPI_Send( kuld, N, MPI_DOUBLE, 0, TAG1, MPI_COMM_WORLD ); // Üzenetfogadás: 0.processz -> 1.processz MPI_Recv( fogad, N, MPI_DOUBLE, 0, TAG0, MPI_COMM_WORLD, &status ); } A teljes program: 7. melléklet: main3_2_4c.c II.3.3. Nem-blokkoló függvények II A nem-blokkoló függvények használatának koncepciója A blokkoló függvényekkel ellentétben melyek csak az üzenetátvitel befejezésekor tértek vissza, a nem-blokkoló függvények már az üzenetátvitel kezdeményezése után visszatérnek kiküszöbölve ezzel az átvitel okozta késleltetést és a lehetséges holtpontot. Ez úgy valósul meg, hogy az üzenetátvitel kezdeményezése és teljesítése nem egy, hanem két függvényhívás hatására történik. A két függvényhívás között a processz szabadon végezhet egyéb számításokat, kihasználva az egyébként várakozással töltött idıt. A nem-blokkoló függvények két függvényhívása ugyanazt a kommunikációs hatást váltja ki, mint a blokkoló függvények egyetlen függvényhívása, csupán az MPI által definiált lehetıségeket más felületen keresztül használják fel. Ezen egyenértékőségük miatt a blokkoló és nem-blokkoló függvényeket lehet vegyesen is használni. Például, hogy a küldés blokkoló és a fogadás nem-blokkoló; vagy fordítva, hogy a küldés nem-blokkoló és a fogadás blokkoló. Visszatérve, a nem-blokkoló függvényekkel megvalósított kommunikáció egy processz részérıl két függvényhívást jelent. Ezek közül az elsı függvény a küldés vagy a fogadás kezdeményezése, amelyeket késleltetett küldésnek vagy késleltetett fogadásnak nevezünk. Miután a processz kezdeményezte az üzenetátvitelt, két különbözı módon ellenırizheti annak teljesülését. Az egyik lehetıség, hogy ellenırzi, de ha még nem fejezıdött be teljesen az átvitel, akkor folytatja az egyéb számításait, kihasználva a további várakozási idıt; a másik lehetıség pedig, hogy az ellenırzésbıl csak az átvitel teljes befejeztekor tér vissza. Intuitív módon az elıbbit tesztelésnek, az utóbbit pedig várakozásnak hívjuk. Az üzenet átvitelének kezdeményezése után a processznek valamilyen módon hivatkoznia kell tudnia a megkezdett átvitelre. Az MPI erre a célra lekérdezési paramétert definiál. Minden nem-blokkoló függvény ilyen lekérdezési paraméterrel tér vissza, mellyel azonosíthatók a megkezdett átvitelek. 26

27 II A nem-blokkoló függvények felépítése Mindkét blokkoló függvénynek megvan a nem-blokkoló megfelelıje. int MPI_Isend ( void *buf, int count, MPI_Datatype dtype, int dest, int tag, MPI_Comm comm, MPI_Request *request ); // Küldendı adatokat tartalmazó buffer // Küldendı adategységek száma // Adategység típusa // Célprocessz azonosítója // Üzenetcímke // Kommunikátor, melybe mindkét // processz beletartozik // Lekérdezési paraméter Az MPI_Isend paraméterezése a plusz lekérdezési paramétert leszámítva teljesen megegyezik az MPI_Send-ével; viszont meghívásakor csak az üzenetátvitel kezdeményezése történik meg. Tehát az MPI_Send-del ellentétben amely csak akkor tér vissza, ha az MPI-ra bízta az üzenetét, az MPI_Isend ezt nem várja meg, hanem az átvitel kezdeményezése után azonnal visszatér. Emiatt az MPI_Isend meghívását követıen ne módosítsuk (ne írjuk, ne olvassuk) annak paramétereit, hiszen amíg meg nem bizonyosodtunk az üzenetküldés befejeztérıl, addig ezen paraméterek megváltoztatása a küldött üzenet sérüléséhez vezethet. int MPI_Irecv ( void *buf, int count, MPI_Datatype dtype, int source, int tag, MPI_Comm comm, MPI_Request *request ); // Fogadó buffer // Maximum fogadható // adategységek száma // Adategység típusa // Forrásprocessz azonosítója // Üzenetcímke // Kommunikátor, melybe mindkét // processz beletartozik // Lekérdezési paraméter Az MPI_Irecv paraméterezése hasonló az MPI_Recv-éhez, csupán abban különbözik, hogy az MPI_Status *status helyett, MPI_Request *request paraméter szerepel. Az MPI_Irecv által visszaadott lekérdezési paramétert felhasználva ellenırizhetjük a hozzá tartozó üzenetfogadás állapotát, vagy megvárhatjuk annak teljes befejezését. Mivel az MPI_Irecv használatakor csak az üzenetfogadás kezdeményezése történik meg, ezért amíg nem bizonyosodtunk meg arról, hogy teljesen befejezıdött az üzenetfogadás, addig ne módosítsuk (ne olvassuk, ne írjuk) az MPI_Irecv paramétereit, mert ez az üzenet sérüléséhez vezethet. Az üzenetátvitel (processzenként küldés vagy fogadás) teljes befejezését kétféleképpen ellenırizhetjük: tesztelve vagy várakozva. Tesztelés esetén úgy jutunk információhoz a nem-blokkoló függvényhez tartozó átvitel állapotáról, hogy az akár befejezıdött, akár nem, a tesztelı függvény visszatér és az eredmény függvényében dolgozhatunk tovább. Várakozás esetén ahogy a neve is sejteti a várakozó függvény csak az átvitel teljes befejeztekor tér vissza. Úgy is fogalmazhatunk, hogy az üzenetátvitel teljesülésének a tesztelés nem-blokkoló, míg a várakozás blokkoló változata. 27

28 int MPI_Wait ( MPI_Request *request, MPI_Status *status ); // A késleltetett küldés vagy fogadás // lekérdezési paramétere // Információ a fogadott üzenetrıl A request lekérdezési paraméter a megkezdett átvitelek azonosítására szolgál, és az MPI_Isend illetve az MPI_Irecv tér vele vissza. A status -ból fogadás esetén információt nyerhetünk ki az üzenetrıl (ténylegesen fogadott adategységek száma, valamint joker használata esetén a forrásprocessz azonosítójának és az üzenetcímkének az értéke); küldés esetén pedig hibakódot tartalmaz. Az MPI_Wait csak akkor tér vissza, ha az üzenetátvitel a hívó processz oldaláról teljesen befejezıdött. Sikeres átvitel esetén a korábbi függvényekhez hasonlóan MPI_Success-ezel tér vissza. (Üzenetküldés esetén a status másfajta hibakódot tartalmaz.) Összefoglalva, a request bemenı, a status pedig kimenı paraméter. int MPI_Test ( MPI_Request *request, int *flag, MPI_Status *status ); // A késleltetett küldés vagy fogadás // lekérdezési paramétere // Az átvitel teljesülését jelzı zászló // Információ a fogadott üzenetrıl A request paraméterrıl ugyanaz mondható el, mint az MPI_Wait esetében. Az MPI_Test abban különbözik az MPI_Wait-tıl, hogy akár befejezıdött az átvitel, akár nem, az MPI_Test mindenképpen visszatér, és a processz az eredmény függvényében folytathatja egyéb munkáját. A flag igaz értékével jelzi az átvitel befejeztét; és ekkor a status tartalma megegyezik az MPI_Wait esetén leírtakkal. Ha pedig a flag értéke hamis, akkor a status értéke definiálatlan marad. Emiatt a flag -nek csak igaz értéke mellett vizsgáljuk a status tartalmát. Üzenetfogadás esetén, ha a flag értéke igaz, akkor a status -ból kinyerhetjük a ténylegesen fogadott adategységek számát, valamint joker használata esetén a forrásprocessz azonosítójának és az üzenetcímkének az értékét is. (A flag igaz vagy hamis értékét logikai értelemben vesszük, tehát igaz > 0, hamis = 0.) Összefoglalva, a request bemenı, a flag és a status pedig kimenı paraméterek. 28

29 Leginkább a holtpont elkerülésének céljából használjuk a megismert nem-blokkoló függvényeket. A várakozási idı kihasználása a másik jelentıs tényezı, amit ha fix hosszúságú feladattal kívánunk kitölteni, akkor MPI_Wait-et; ha pedig a változó hosszúságú feladattal akarjuk optimálisan kihasználni, akkor MPI_Test-et használunk. Tekintsünk egy példaprogramot az MPI_Wait használatára! if( myrank == 0 ) /* 0.processz */ { // Üzenetfogadás kezdeményezése: 1.processz -> 0.processz MPI_Irecv( fogad, N, MPI_DOUBLE, 1, TAG1, MPI_COMM_WORLD, &request ); // Üzenetküldés: 0.processz -> 1.processz MPI_Send( kuld, N, MPI_DOUBLE, 1, TAG0, MPI_COMM_WORLD ); // Várakozás MPI_Wait( &request, &status ); } else if( myrank == 1 ) /* 1.processz */ { // Üzenetfogadás kezdeményezése: 0.processz -> 1.processz MPI_Irecv( fogad, N, MPI_DOUBLE, 0, TAG0, MPI_COMM_WORLD, &request ); // Üzenetküldés: 1.processz -> 0.processz MPI_Send( kuld, N, MPI_DOUBLE, 0, TAG1, MPI_COMM_WORLD ); // Várakozás MPI_Wait( &request, &status ); } A teljes program: 8. melléklet: main3_3_2a.c A kódrészlet üzenetcserét valósít meg. Mindkét processz elıször kezdeményezi az üzenetfogadást, majd blokkolva elküldi saját üzenetét, végül várakozik a másik üzenetének megérkezéséig. Ilyen módon akárhány processz kommunikációja holtpontmentesen összekapcsolható. 29

30 Tekintsünk egy példaprogramot az MPI_Test használatára! if( myrank == 0 ) /* 0.processz */ { // Üzenetfogadás kezdeményezése: 1.processz -> 0.processz MPI_Irecv( fogad, N, MPI_DOUBLE, 1, TAG1, MPI_COMM_WORLD, &request ); // Üzenetküldés: 0.processz -> 1.processz MPI_Send( kuld, N, MPI_DOUBLE, 1, TAG0, MPI_COMM_WORLD ); // Elsı tesztelés esztelés MPI_Test(&request, &flag, &status); while (!flag) { /* Egyéb számítások a várakozási idı kihasználására */ for(j;j<=100;j++) szamol*=j; // Tesztelés MPI_Test(&request, &flag, &status); } // Számítás befejezése for(j;j<=100;j++) szamol*=j; } else if( myrank == 1 ) /* 1.processz */ { // Üzenetfogadás kezdeményezése: 0.processz -> 1.processz MPI_Irecv( fogad, N, MPI_DOUBLE, 0, TAG0, MPI_COMM_WORLD, &request ); // Üzenetküldés: 1.processz -> 0.processz MPI_Send( kuld, N, MPI_DOUBLE, 0, TAG1, MPI_COMM_WORLD ); // Elsı tesztelés esztelés MPI_Test(&request, &flag, &status); while (!flag) { /* Egyéb számítások a várakozási idı kihasználására */ for(j;j<=100;j++) szamol+=j; // Tesztelés MPI_Test(&request, &flag, &status); } // Számítás befejezése for(j;j<=100;j++) szamol+=j; } A teljes program: 9. melléklet: main3_3_2b.c 30

31 II A küldı függvények variánsai Az eddig megismert üzenetküldı függvényeket, mind a blokkolót, mind a nemblokkolót tovább specifikálhatjuk. Variánsaik négy csoportba oszthatók. Standard mód A leguniverzálisabb küldési mód, mert minden egyes üzenetküldés esetén az MPI választja meg küldés megvalósításának módját. Az eddigiekben az idetartozó függvények mőködését részleteztük. Szinkronizált mód A küldött üzenet mindig közvetlenül az egyik processz bufferébıl a másik processz bufferébe kerül, tehát még ideiglenesen sem kerül az MPI belsı bufferébe. A blokkoló esetben a függvény csak akkor tér vissza, ha a fogadó oldalon már megkezdıdött az adatok fogadása; nem-blokkoló esetben pedig csak a szinkronizált átvitelt kezdeményezi a függvény. Tehát egyik esetben sem lehetünk biztosak abban, hogy az üzenet teljes egészében megérkezett a fogadó oldalra; a blokkoló esetben viszont annyit biztosan tudunk, hogy a küldı függvény visszatérésekor az üzenet átmásolása már megkezdıdött. Bufferelt mód A küldött üzenet mindig az MPI belsı bufferébe másolódik, és csak onnan tovább a célprocesszre. Ha nincs elég szabad hely az MPI belsı bufferében, akkor hibakóddal tér vissza a függvény. Blokkoló esetben a függvény csak az MPI belsı bufferébe való másolás befejezése után tér vissza, míg nem-blokkoló esetben a másolás kezdeményezése után azonnal visszatér. Ready (Elıkészített) mód Ez a küldési mód azt feltételezi, hogy fogadó oldalon már kezdeményeztek egy üzenetfogadást. Mőködésében teljesen egyenértékő a standard küldı függvénnyel, viszont elınye, hogyha plusz információval rendelkezünk a fogadó processz állapotáról (tudniillik, hogy az már kezdeményezte egy olyan üzenet fogadását, aminek borítéka megegyezik a küldött üzenet borítékával), akkor az MPI belsı protokollja hatékonyabban tudja továbbítani az üzenetet. Ennek a gyorsabb megvalósításnak viszont az a hátránya, hogy ha az üzenet célprocessz oldali várását feltételezve küldünk, és ott még nem kezdeményezték a fogadást, akkor hibát okozunk és a további kimenetel definiálatlan. A blokkoló és nem-blokkoló változat között ugyanaz a különbség, mint a standard mód két változata között. Elnevezések, paraméterek Küldési mód Blokkoló függvény Nem-blokkoló függvény Standard MPI_Send MPI_Isend Szinkronizált MPI_Ssend MPI_Issend Bufferelt MPI_Bsend MPI_Ibsend Ready (Elıkészített) MPI_Rsend MPI_Irsend A blokkoló függvények paraméterlistája az MPI_Send-ével egyezik meg, a nem-blokkoló függvényeké pedig az MPI_Isend-ével. Az MPI_Recv vagy az MPI_Irecv valamelyikét tetszılegesen használhatjuk az üzenetek fogadására, függetlenül a küldési módtól. 31

32 Ellenırzı kérdések: 1.) Mi történik, ha egyszerre több üzenetet küldenek ugyanannak a processznek? 2.) Milyen sorrendben dolgozza fel a fogadó processz a várakozó üzeneteket? 3.) Mik az üzenetküldéses modell elemei? 4.) Milyen módon kommunikál egymással a forrás- és a célprocessz, és ez milyen esetekhez vezet? 5.) Milyen részekbıl áll egy üzenet? 6.) Mikrıl kell gondoskodni függı üzenetek fogadásakor? 7.) Mikor, milyen esetekben használunk joker processz-azonosítót és üzenetcímkét? 8.) Honnan tudjuk meg a forrásprocessz azonosítóját, az üzenet címkéjét, illetve a küldött adategységek számát joker azonosító és címke használata esetén? 9.) Hogyan valósítja meg az MPI az üzenetátvitelt? Milyen két eset lehetséges? 10.) Miben különböznek a nem-blokkoló függvények a blokkoló függvényektıl? 11.) Mikor használunk MPI_Wait-et és mikor MPI_Test-et? Feladatok: 1.) Próbáljuk ki a main3_2_1.c példaprogramot! 2.) Próbáljuk ki a main3_2_2a.c példaprogramot! 3.) Próbáljuk ki a main3_2_2b.c példaprogramot! 4.) Ellenırizzük, hogy tényleg holtpontra kerül-e a main3_2_4a.c példaprogram! 5.) Próbáljuk ki, hogy minden N érték esetén lefut-e a main3_2_4b.c példaprogram! 6.) Keressük meg, hogy mely N értékek esetén fut le, és mely N értékek esetén kerül holtpontra a main3_2_2b.c példaprogram! 7.) Próbáljuk ki a main3_3_2a.c példaprogramot! 8.) Próbáljuk ki a main3_3_2b.c példaprogramot! 9.) Írjunk egy programot, amelyben egy master és legalább három slave processz kommunikál egymással! 32

33 II.4. Kollektív kommunikáció és fajtáinak megismerése A csoporton belüli, vagy más szóval kollektív kommunikáció, a pont-pont kommunikációhoz hasonlóan szintén üzenetek küldését és fogadását jelenti, azzal a különbséggel, hogy az nem csak két, hanem több processz között történik. A párhuzamos programjainkat megírhatnánk kizárólag pont-pont kommunikáció alkalmazásával is, de támogatásként az MPI a gyakran szükséges üzenet-átviteli függvényhívás-sorrendeket optimálisan megvalósított szolgáltatássá összefogva bocsátja rendelkezésünkre. Ilyen módon a kollektív kommunikáció megvalósításának bonyolultságától eltekintve élvezhetjük hatékony hatásukat, és használhatjuk tömör kifejezıképességüket. Mivel kollektív kommunikáció során egy csoport összes tagja között történik üzenetátvitel, ezért nincs szükség a pont-pont kommunikációnál megszokott üzenetcímkére, viszont arra figyelni kell, hogy a csoport összes processze meghívja a kollektív kommunikációt megvalósító függvényt. A processzek kommunikátorba csoportosulnak; és csak az egy kommunikátorba tartozó processzek tudnak kommunikálni egymással. Az MPI_COMM_WORLD az összes processzt tartalmazza, de ezen belül létrehozhatunk kisebb halmazokat, azaz újabb kommunikátorokat is. II.4.1. Alapvetı függvények II Szinkronizáló sorompó Amikor egy processz olyan munkát végez, amelynek eredményére a többi processznek szüksége van, akkor a többi processznek várnia kell erre a processzre. Leggyakrabban a slave processzek várnak a master processzre, amíg az fájlmőveleteket végez. Az MPI_Barrier függvény megállítja az összes processzt mindaddig, amíg a csoport valamennyi tagja meg nem hívja ıt. int MPI_Barrier ( MPI_Comm comm ); // A szinkronizálandó processzek // közös kommunikátora Bár az MPI_Barrier nem továbbít adatokat, mégis szinkronizálja az egy kommunikátorba (csoportba) tartozó processzeket azáltal, hogy csak azt követıen tér vissza, amikor már a csoport összes tagja meghívta ıt. 33

34 II Üzenetszórás Az MPI_Bcast függvény hatására a forrásprocesszrıl az adott kommunikátorba tartozó összes processzre átmásolódik a küldött adat (4. ábra). A egyes processzeken ugyanolyan nevőnek kell lennie a fogadóbuffernek, mint a forrásprocessz küldıbuffere. Ez általában könnyen teljesíthetı is, mivel a változó deklarálások a programkód elején, az összes processz által végrehajtott területen vannak. A programozó felelıssége gondoskodni arról, hogy az adott csoportba tartozó összes processz meghívja ezt a függvényt, különben a kimenetel definiálatlan. Ugyanez a kitétel érvényes az összes többi kollektív kommunikációt megvalósító függvényre is. 4. ábra int MPI_Bcast ( void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm ); // A küldıbuffer és egyben // a fogadóbufferek kezdıcíme // Adategységek száma a küldıbufferben // Adategység típusa a küldıbufferben // Forrásprocessz azonosítója // Kommunikátor, melybe az összes // címzett és a küldı processz is // beletartozik Összefoglalásul, a buffer kimenı, illetve bemenı paraméter; a maradék négy pedig mind bemenı paraméterek. Tekintsünk egy példaprogramot az MPI_Bcast használatára! 10. melléklet: main4_1_2.c 34

35 II Szétosztás Az MPI_Scatter az MPI_Bcast-hoz hasonlóan egy processzrıl küld adatokat az összes kommunikátorbeli processzre saját magát szintén beleértve ; viszont az MPI_Bcast-tal ellentétben már különbözı adatokat küld. Meghívásakor a forrásprocessz a bufferében lévı tömböt egyenlı hosszúságú részekre darabolja fel, amiket az egyes processzeknek azonosítójuk sorrendjében oszt szét (5. ábra). 5. ábra int MPI_Scatter ( void* send_buffer, // A küldıbuffer kezdıcíme int send_count, // Az egy processznek küldendı // adategységek száma MPI_datatype send_type, // Adategység típusa a küldıbufferben void* recv_buffer, // A fogadóbufferek kezdıcíme int recv_count, // Egy fogadóbufferben // az adategységek száma MPI_Datatype recv_type, // Adategység típusa a fogadóbufferekben int root, // Forrásprocessz azonosítója MPI_Comm comm ); // Kommunikátor, melybe az összes // címzett és a küldı processz is // beletartozik Összefoglalva, a fogadóbufferek kivételével az összes paraméter bemenı. 35

36 II Összegyőjtés Az MPI_Gather az adott kommunikátorba tartozó összes processzrıl összegyőjti az adatokat egyetlen processz bufferébe (6. ábra), tehát az MPI_Scatter-nek pont inverz mővelete. 6. ábra int MPI_Gather ( void* send_buffer, int send_count, MPI_datatype send_type, void* recv_buffer, int recv_count, MPI_Datatype recv_type, int dest, MPI_Comm comm ); // A küldıbufferek kezdıcíme // Az egyes küldıbufferekben lévı, // küldendı adategységek száma // Adategység típusa // a küldıbufferekben // A fogadóbuffer kezdıcíme // A fogadóbufferben // az adategységek száma // Adategység típusa // a fogadóbufferben // Célprocessz azonosítója // Kommunikátor, melybe az összes // küldı és a címzett processz is // beletartozik Összefoglalva, a fogadóbuffer kivételével az összes paraméter bemenı. Tekintsünk egy példaprogramot az MPI_Scatter és az MPI_Gather használatára! 11. melléklet: main4_1_4.c 36

37 II Összegyőjtés mőveletvégzéssel Az MPI_Reduce az MPI_Gather-hez hasonlóan az adott kommunikátorba tartozó összes processzrıl győjti össze az adatokat. Amiben az MPI_Reduce több, mint az MPI_Gather, az az, hogy az összegyőjtött adatokon mőveletet végez, és csak a mővelet eredményét menti a célprocesszre (7. ábra). Alapértelmezésben csak olyan mőveletek definiáltak, amelyek csökkentik (redukálják) az küldött üzenet méretét. Ha tömböket győjtünk össze, akkor az azonos indexő elemek között végezhetünk mőveletet. 7. ábra int MPI_Reduce ( void* send_buffer, void* recv_buffer, int count, MPI_Datatype datatype, MPI_Op operation, int dest, MPI_Comm comm ); // A küldıbufferek kezdıcíme // A fogadóbuffer kezdıcíme // Az egyes küldıbufferekben lévı, // küldendı adategységek száma // Adategység típusa // a küldıbufferekben // Redukáló mővelet // Célprocessz azonosítója // Kommunikátor, melybe az összes // küldı és a címzett processz is // beletartozik Összefoglalva, a fogadóbuffer kivételével az összes paraméter bemenı. Tekintsünk egy példaprogramot az MPI_Reduce használatára! 12. melléklet: main4_1_5.c 37

38 Néhány alapértelmezett redukáló mővelet MPI_MAX MPI_MIN MPI_SUM MPI_PROD MPI_LAND MPI_BAND MPI_LOR MPI_BOR MPI_LXOR MPI_BXOR Maximum Minimum Összeg Szorzat Logikai És Bitenkénti És Logikai Vagy Bitenkénti Vagy Logikai Kizáró Vagy Bitenkénti Kizáró Vagy II.4.2. Alapvetı függvények variánsai Ha különbözı mértékben szeretnénk szétosztani a terhelést a különbözı processzek között, akkor ezt az adattömb különbözı mérető részekre darabolásával, processzek közötti szétosztásával, majd a feldolgozást követıen összegyőjtésével tehetjük. Ennek hatékony megvalósítására szolgálnak a különbözı elemszámú tömbrészekkel dolgozó szétosztó (MPI_Scatterv) és összegyőjtı (MPI_Gatherv) függvények. II Különbözı mérető részek szétosztása Az MPI_Scatterv függvény segítségével az MPI_Scatter-rel megvalósítható adattömb feldarabolást és szétosztást valósíthatunk meg, viszont az egyes processzekhez már tetszıleges elemszámú tömbrészletet rendelhetünk. int MPI_Scatterv ( void* send_buffer, int* send_counts, int* displacements, MPI_Datatype sendtype, void* recv_buffer, int recv_count, MPI_Datatype recvtype, int root, MPI_Comm comm ); // A küldıbuffer kezdıcíme // Az egyes processzeknek küldendı // tömbrészek elemszámai // Az egyes processzeknek küldendı // tömbrészeknek a küldıbuffer // kezdıcíméhez képesti relatív // kezdıcímei // Adategység típusa // a küldıbufferben // Az adott fogadóbuffer kezdıcíme // Az adott fogadóbufferben // az adategységek száma // Adategység típusa // a fogadóbufferekben // Forrásprocessz azonosítója // Kommunikátor, melybe az összes // címzett és a küldı processz is // beletartozik 38

39 Az egyes processzeknek küldendı tömbrészletek elemszámait és a küldıbuffer kezdıcíméhez viszonyított relatív kezdıcímeit a send_counts és displacesments int típusú tömbökben a processzek azonoítójának megfelelıen helyezzük el. A többi paraméter megegyezik az MPI_Scatter-nél megismertekkel. Összefoglalva, a fogadóbufferek kivételével az összes paraméter bemenı. II Különbözı mérető részek összegyőjtése Az MPI_Gatherv függvény az MPI_Gather-nél megismert adatösszegyőjtı funkciót látja el, viszont az MPI_Scatterv inverzeként már különbözı elemszámú tömbrészeket is össze tud rendezni egyetlen processz bufferébe. int MPI_Gatherv ( void* send_buffer, int send_counts, MPI_Datatype sendtype, void* recv_buffer, int* recv_counts, int* displacements, MPI_Datatype recvtype, int root, MPI_Comm comm ); // A küldıbufferek kezdıcíme // Az egyes küldıbufferekben lévı, // küldendı adategységek száma // Adategység típusa // a küldıbufferekben // A fogadóbuffer kezdıcíme // Az egyes processzektıl fogadott // tömbrészletek elemszámai // Az egyes processzek által küldött // tömbrészeknek a fogadóbuffer // kezdıcíméhez képesti relatív // kezdıcímei // Adategység típusa // a fogadóbufferben // Célprocessz azonosítója // Kommunikátor, melybe az összes // küldı és a címzett processz is // beletartozik Az egyes processzek tömbrészletének elemszámai az adott processz send_count változójában, illetve a célprocessz recv_count tömbjében az adott processz azonosítójának megfelelı indexő helyen vannak. A célprocesszre érkezı tömbrészletek a fogadóbuffer kezdıcíméhez képest a displacements tömbnek szintén az adott processz azonosítójának megfelelı indexő helyén lévı relatív kezdıcímre kerülnek. Összefoglalva, a fogadóbufferek kivételével az összes paraméter bemenı. Tekintsünk egy példaprogramot az MPI_Scatterv és az MPI_Gatherv használatára! 13. melléklet: main4_2_2.c Az 11. mellékletben szereplı main4_1_4.c példaprogramhoz képest ahol az MPI_Scatter-et használtuk, az MPI_Scatterv alkalmazával megvalósított üzenetküldés ugyan nagyobb elıkészítést igényel; viszont így, hogy a master processzhez kevesebb feldolgozást rendeltünk, az kevésbé válik szők keresztmetszetté, amikor a slave processzek már elkészültek a feldolgozással, és már visszaküldenék az adatokat. Ahogy a példaprogramban is bemutatásra került, az sendcounts illetve recvcounts tömböket, valamint a displacements tömböt értelemszerően csak a forrásprocesszen 39

40 (MPI_Scatterv esetén) illetve a célprocesszen (MPI_Gatherv esetén) kell megadni. A többi paramétert, mint például a recvcount illetve sendcount változókat az adott processznek megfelelıen kell megadni. Ekkor minden processz ugyanolyan nevő változót tesz a paraméterlistájára, viszont processzenként ezeknek a változóknak lehet más és más az értéke. Összefoglalásul Alapvetı kollektív kommunikációs függvények és variánsaik MPI_Barrier - MPI_Bcast - MPI_Scatter MPI_Scatterv MPI_Gather MPI_Gatherv MPI_Reduce - II.4.3. Összetett függvények Az összetett kollektív függvények több, egymást követı kollektív függvényhívást valósítanak meg egyetlen függvényhívásban. Használatukkal tömörebbé és kifejezıbbé tehetjük a programkódunkat, és gyorsíthatjuk processzeink futását. II Összegyőjtés és mindenkinek elküldés Az MPI_Allgather függvény az MPI_Gather-hez hasonlóan az összes kommunikátorbeli processzrıl győjt össze az adatokat, viszont azokat nem csak egy, hanem az összes processzen letárolja (8. ábra). Tehát az MPI_Gather és az MPI_Bcast egymás utáni alkalmazását helyettesíti. 8. ábra 40

41 int MPI_Allgather ( void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm ); // A küldıbufferek kezdıcímei // Az egyes küldıbufferekben lévı, // küldendı adategységek száma // Adategység típusa // a küldıbufferekben // A fogadóbufferek kezdıcímei // Az egyetlen processztıl fogadandó // adategységek száma // Adategység típusa // a fogadóbufferekben // Kommunikátor, melybe az összes // küldı és címzett processz is // beletartozik A sendcount -ba a processzek által egyenként küldött adategységek számát írjuk; a recvcount -ba pedig az egy processztıl fogadott adategységek számát. A recvbuf tömbnek processzenként tehát a processzek számaszor recvcount méretőnek kell lennie. Összefoglalva, a fogadóbufferek kivételével az összes paraméter bemenı. Tekintsünk egy példaprogramot az MPI_Allgather használatára! 14. melléklet: main4_3_1.c A példaprogramban, annak érdekében, hogy demonstrálhassuk az MPI_Allgather mőködését, mindegyik processz a standard kimenetre írja a fogadott üzenetét. Ha több processz írna párhuzamosan ugyanazon kimenetre, akkor a kimenetel definiálatlan lenne, ami természetesen nem megengedhetı. Az MPI_Barrier függvény segítségével érjük el, hogy ne legyen kavarodás, hanem a processzek várjanak egymásra. A már elkészült párhuzamos programok esetén általában csak egyetlen processz szokott írni a kimenetre, vagy olvasni a bemenetrıl, illetve a fájlokat kezelni; elkerülve ezzel a függvény mőködésének szemléltetése céljából bemutatott kisorosítást. 41

42 II Összegyőjtés mőveletvégzéssel és mindenkinek elküldés Az MPI_Allreduce függvény ugyanannyival több az MPI_Reduce-nál, mint az MPI_Allgather az MPI_Gather-nél; azaz az összegyőjtött adatokkal végzett mővelet eredményét az összes processzen tárolja le (9. ábra). Ha tömbök elemein végzünk mőveletet, akkor az eredmények is minden processzen tömbben tárolódnak le. 9. ábra Az egyes processzek küldıbufferének azonos indexő elemein értelmezettek a mőveletek; az eredmények pedig ezen indexeknek megfelelı helyre tárolódnak le minden egyes processz fogadóbufferébe. A jobb átláthatóság kedvéért a 9. ábrán eredményenként különbözı nyilat használtunk. int MPI_Allreduce ( void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm ); // A küldıbufferek kezdıcímei // A fogadóbufferek kezdıcímei // Az egyes küldıbufferekben // lévı, küldendı adategységek // száma // Adategység típusa // a küldıbufferekben // Redukáló mővelet // Kommunikátor, melybe // az összes küldı és címzett // processz is beletartozik Összefoglalva, a fogadóbufferek kivételével az összes paraméter bemenı. Tekintsünk egy példaprogramot az MPI_Allreduce használatára! 15. melléklet: main4_3_2.c 42

43 II Szétosztás mindenkitıl mindenkinek Az MPI_Alltoall függvény ugyanazt a hatást eredményezi, mintha a kommunikátorban lévı összes processz egy-egy MPI_Scatter függvényhívást kezdeményezne. Az eddigi összes összetett kommunikációs függvényhez hasonlóan, itt is minden processz küld adatot minden processznek. A processzek azonosítói és a processzek fogadóbuffereibe érkezı adatok sorrendje között fontos összefüggés van: Az átvitt adatok akár tömbök, akár pusztán változók az ıket küldı processzek azonosítójának megfelelı helyre kerülnek fogadáskor (10. ábra). 10. ábra Tehát az i -edik processz által a j -edik processznek küldött adat a j -edik processz fogadóbufferében az i * egyetlen processznek küldött adat hossza kezdıcímő helyre kerül. Ha az adatok hosszától eltekintünk, akkor az MPI_Alltoall mővelet mátrixtranszponálásra emlékeztet. int MPI_Alltoall ( void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm ); // A küldıbufferek kezdıcímei // Az egy processz által // egy processznek küldött // adategységek száma // Adategység típusa // a küldıbufferekben // A fogadóbufferek kezdıcímei // Az egyetlen processztıl fogadandó // adategységek száma // Adategység típusa // a fogadóbufferekben // Kommunikátor, melybe // az összes küldı és címzett // processz is beletartozik Összefoglalva, a fogadóbufferek kivételével az összes paraméter bemenı. Tekintsünk egy példaprogramot az MPI_Alltoall használatára! 16. melléklet: main4_3_3.c 43

44 II Összegyőjtés mőveletvégzéssel és szétosztás Az MPI_Reduce_scatter a processzek küldıbuffereinek azonos indexő elemein végez mőveletet, és az eredményeket szétosztja az egyes processzek között (11. ábra). 11. ábra Az MPI_Reduce_scatter az eddig bemutatott összetett kollektív kommunikációs függvényekkel ellentétben, nem feltétlen egyenlı mértékben osztja szét az érkezı adatokat jelen esetben a mőveletek eredményeit a processzek között. Lehetıség van arra, hogy számszerően megadjuk a szétosztás arányát. A recvcounts tömb i -edik indexő helyére írt számnak megfelelı számú adategység érkezik az i -edik processz fogadóbufferébe. int MPI_Reduce_scatter ( void* sendbuf, void* recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm ); // A küldıbufferek kezdıcímei // A fogadóbufferek kezdıcímei // Az egyes processzek által // fogadott tömbrészletek // elemszámai // Adategység típusa // a küldıbufferekben // Redukáló mővelet // Kommunikátor, melybe // az összes küldı és címzett // processz is beletartozik Összefoglalva, a fogadóbufferek kivételével az összes paraméter bemenı. Tekintsünk egy példaprogramot az MPI_Reduce_scatter használatára! 17. melléklet: main4_3_4.c 44

45 Összefoglalásul Amint láttuk, az MPI_Reduce_scatter-rel megvalósítható az egyenlı mértékő és a különbözı mértékő adatszétosztást is. Ellenben adad olyan függvény, mint például, az MPI_Allreduce, ahol a mővelet jellegébıl fakadóan csak az adatokat egyenlı mértékben szétosztó változat létezhet. Mind az MPI_Allgather-nek, mind az MPI_Alltoall-nak létezik az adatokat különbözı mértékben szétosztó változata is (MPI_Allgatherv és MPI_Alltoallv), melyek használata és paraméterezése az eddig megismert függvények alapján intuitívan adófik. Összetett kollektív kommunikációs függvények és variánsaik MPI_Allgather MPI_Allgatherv MPI_Allreduce - MPI_Alltoall MPI_Alltoallv MPI_Reduce_scatter Ellenırzı kérdések: 1.) Van-e végeredménybeli különbség a között, hogy üzenetátvitelekre kollektív kommunikációs függvényeket használunk, vagy pedig pont-pont kommunikációs függvények sorozatát? Ha van különbség, akkor miben van? Ha nincs, akkor miért használunk mégis kollektív kommunikációs függvényeket? 2.) Mi egy kommunikátor szerepe? Mire kell figyelni a kollektív kommunikációs függvények meghívásánál? 3.) Melyek az alapvetı kollektív kommunikációs függvények? Hogyan jellemezhetıek röviden? 4.) Melyek az alapvetı kollektív kommunikációs függvények variánsai? Hogyan jellemezhetık röviden? 5.) Melyek az összetett kollektív kommuniációs függvények? Hogyan jellemezhetık röviden? Feladatok: 1.) Próbáljuk ki a main4_1_2.c példaprogramot! 2.) Próbáljuk ki a main4_1_2.c példaprogramot! 3.) Próbáljuk ki a main4_1_4.c példaprogramot! 4.) Próbáljuk ki a main4_1_5.c példaprogramot! 5.) Próbáljuk ki a main4_2_2.c példaprogramot! 6.) Próbáljuk ki a main4_3_1.c példaprogramot! 7.) Próbáljuk ki a main4_3_2.c példaprogramot! 8.) Próbáljuk ki a main4_3_3.c példaprogramot! 9.) Próbáljuk ki a main4_3_4.c példaprogramot! 10.) Írjunk egy programot, amelyben egy master és legalább három slave processz a lehetı leghatékonyabban dolgozik együtt és kommunikál egymással! Fogalmazzuk meg röviden, hogy miben rejlik a megírt program hatékonysága! 45

46 II.5. Származtatott adattípusok és struktúrák létrehozása és átvitele Az adatok, amikkel dolgozunk, és amiket küldeni, fogadni szeretnénk általában különbözı adattípusúak, és gyakran szétszórva helyezkednek el egy tömbben. Ha az eddig tanultak felhasználásával szeretnénk elküldeni ezeket a különbözı típusú és egy tömbben szétszórva elhelyezkedı adatokat, akkor az egynemő és a tömbben egymás mellett elhelyezkedı adatokat összefogva kisebb mérető, különálló üzenetekben küldenénk el. Például, ha egy háromszögeket tartalmazó struktúratömböt szeretnénk átküldni, illetve fogadni, akkor ez az oldalak és a szögek különbözı adattípusa miatt nagyon körülményes lenne. Vagy például, ha egy kétdimenziós mátrix almátrixait szeretnénk szétosztani a slave processzek között, akkor az almátrixok minden egyes sorát külön üzenetben küldhetnénk; nem beszélve arról, hogy az almátrixok összegyőjtésekor ugyanezen kommunikációs mőveletsort az ellenkezı irányban is meg kellene ismételnünk. Az almátrixok szétosztását megoldhatjuk még az almátrixok kisebb tömbökbe másolásával majd azok elküldésével, de ezen módszer hátránya az extra memóriaterület felhasználáson kívül, hogy a másolásra a processzornak plusz idıt kell fordítania, rontva ezzel a párhuzamos program hatékonyságát. Ezenkívül a különbözı adattípusok problémája továbbra sincs megoldva. II.5.1. Hogyan továbbítja az MPI az adattípusokat? Ha mindenképpen egy üzenetben szeretnénk elküldeni az adatokat, akkor hajolhatunk arra, hogy a többségtıl eltérı adatok típusát átkonvertáljuk a többivel megegyezı típusúra, de mivel a konvertálás általában több processzoridıbe kerül, mint a másolás, ezért ez sem hatékony megoldás. Ha a konvertálási idıt úgy próbáljuk megspórolni, hogy az azonos adattípus méretekre alapozva pusztán felülírjuk a küldıbuffer adattípusát egy másik adattípussal, mondván, hogy a bitmintából majd a másik processz oldalán visszaállítjuk a helyes értéket, súlyos hibát vétünk! Ugyanis ezen módszer tesztelésekor valószínőleg helyesen fut majd le a programunk, de amikor ezt több processzoros környezetben futtatjuk, akkor már minden bizonnyal hibás mőködésre vezet; mikor viszont a hiba már csak nehezen vehetı észre. A hiba forrása, hogy az MPI nem csak bitmintákat, hanem értékeket is továbbít. Amikor olyan processzorokkal dolgozunk, melyek számábrázolása adattípusonként megegyezik, akkor az MPI optimalizálja az üzenetátvitel megvalósítását azáltal, hogy egyszerően csak a bitmintákat továbbítja. Ha viszont eltérı számábrázolást használó processzorokból áll az architektúra, amin a párhuzamos programunk fut, akkor az MPI a küldött változó névleges adattípusának megfelelı értékét megtartva, azt küldés elıtt egy standard, köztes számábrázolási formátumra alakítva továbbítja, majd a fogadó oldalon, az ottani architektúra számábrázolásának megfelelıen alakítja vissza. Ezáltal biztosított, hogy a tetszıleges számábrázolású számítógépek akadály nélkül összekapcsolhatóak legyenek. Így lehetséges, hogy az üzenetek tartalmát akkor is gond nélkül továbbítsuk, amikor az a két processz oldalán más-másképpen ábrázolódik. 46

47 II.5.2. Adatok csomagolt átvitele Ha különbözı típusú vagy tömbben nem egymás mellett elhelyezkedı adatokat szeretnénk egyetlen bufferbe csomagolva a processzek között átvinni, akkor ezt elızetes konverziók nélkül az MPI_Pack, az MPI_Unpack és MPI_Pack_size függvényekkel készíthetjük elı, és az eddig megismert kommunikációs függvények bármelyikével vihetjük át. Ezen függvények használatának elınye, hogy nincs szükség a nagyobb processzoridıt igénylı konverziókra, csupán az átviendı adatok megfelelı módon való bufferbe csomagolására, illetve onnan kicsomagolására. A csomagolás illetve kicsomagolás valójában adott címre való másolást és a címmutató léptetését jelenti. Az átvitelre használt buffer adattípusa bármilyen az MPI_Send által értelmezett típus lehet. Mivel a csomagolt adattípus (MPI_PACKED) mérete byte-okban mérendı, ezért érdemes char tömböt választani. Egy másik megfontolás lehet, hogy a buffer elején lévı adatok adattípusának, vagy a legtöbb küldendı adat adattípusának megfelelı buffert választunk. Mindennek csak a memóriaterület lefoglalása szempontjából van jelentısége, hiszen akár többféle adattípust is másolhatunk az így lefoglalt tömbünkbe, ami a becsomagolás után egy osztatlan MPI_PACKED adattípusú változóvá válik. A legszemléletesebben úgy képzelhetı el ez az átvitel, mint egy kívülrıl átlátszatlan FIFO sor átvitele. Az átviendı adatainakat az MPI_Pack-kel csomagoljuk be a forrás processz oldalán, és az MPI_Unpack-kel csomagoljuk ki a célprocessz oldalán. int MPI_Pack ( void* inbuf, int incount, MPI_Datatype datatype, void* outbuf, int outsize, int* position, MPI_Comm comm ); // Az átviteli bufferbe csomagolandó // tömb // Az átviteli bufferbe csomagolandó // tömb elemeinek a száma // Az átviteli bufferbe csomagolandó // tömb adattípusa // Az átviteli buffer // Az átviteli buffer mérete byte-ban // Az átviteli bufferben a következı // szabad hely címe // Kommunikátor, melybe a küldı // és a fogadó processzek tartoznak int MPI_Unpack ( void* inbuf, // Az átviteli buffer int insize, // Az átviteli buffer mérete byte-ban int* position, // Az átviteli buffer címmutatója void* outbuf, // Az átviteli bufferbıl kicsomagolandó // tömb int outcount, // Az átviteli bufferbıl kicsomagolandó // tömb elemeinek a száma MPI_Datatype datatype, // Az átviteli bufferbıl kicsomagolandó // tömb adattípusa MPI_Comm comm ); // Kommunikátor, melybe a küldı // és a fogadó processzek tartoznak 47

48 Az MPI_Pack_size függvénnyel határozhatjuk meg az átviteli buffer már feltöltött, byte-okban számolt méretét, pontosabban az átviteli bufferben a következı szabad hely címét. int MPI_Pack_size ( int incount, MPI_Datatype datatype, MPI_Comm comm, int* size ); // Az átviteli bufferbe // csomagolandó tömb // elemszáma // Az átviteli bufferbe // csomagolandó // tömb adattípusa // Kommunikátor, melybe // a küldı és a fogadó // processzek tartoznak // A tömb becsomagolása után // a következı szabad cím Tekintsünk egy példaprogramot különbözı adattípusú változók becsomagolására, átvitelére és kicsomagolására! 18. melléklet: main5_2a.c Tekintsünk egy példaprogramot egy mátrix almátrixának elküldésre és fogadására! 19. melléklet: main5_2b.c II.5.3. Új adattípus (struktúra) létrehozása Az MPI a csomagolt adatátvitelnél egy sokkal hatékonyabb átvitelt is biztosít a származtatott adattípusok formájában. Származtatott adattípusoknak az alapértelmezett MPI adattípusokból öszzeépített adattípusokat, struktúrákat nevezzük. Alapértelmezett adattípusok MPI adattípus C megfelelıje MPI adattípus C megfelelıje MPI_CHAR signed char MPI_UNSIGNED_CHAR unsigned char MPI_SHORT signed short int MPI_UNSIGNED_SHORT unsigned short int MPI_INT signed int MPI_UNSIGNED unsigned int MPI_LONG signed long int MPI_UNSIGNED_LONG unsigned long int MPI_FLOAT float MPI_BYTE - MPI_DOUBLE double MPI_PACKED - MPI_LONG_DOUBLE long double 48

49 A származtatott adattípusok használatának elınye a csomagolt adatátvitelhez képest, hogy nincs szükség plusz memóriaterületre, sem adatok másolására, ami processzoridı többlettel járna. Továbbá elıny, hogy lehet közvetlenül hozzáférni a létrehozott struktúra tagjaihoz, anélkül, hogy a be- illetve kicsomagolás procedúráján végigmennénk. A C nyelv struktúráihoz hasonlóan az MPI struktúrákat is csak egyszer kell definiálni, és onnantól kezdve az átvitelhez csak a kommunikációs függvényeket kell használni. Másrészrıl, csak akkor érdemes MPI struktúrát létrehozni, ha azt késıbb többször használni szándékozunk. A következıkben új adattípusok, struktúrák létrehozására szolgáló függvényekkel ismerkedünk meg. Az új struktúra létrehozása minden esetben két fı lépésbıl áll: A struktúra elkészítésébıl és a véglegesítésébıl. II Az új adattípus (struktúra) elıkészítése Szomszédos, azonos típusú adatok párokba, hármasokba, illetve kisebb csoportokba összefogására az MPI_Type_contiguous függvényt használjuk. Leginkább pontok koordinátáinak kezelésére alkalmas. int MPI_Type_contiguous ( int count, // Adategységek száma MPI_Datatype oldtype, // Adategységek típusa MPI_Datatype* newtype ); // Új adattípus Tekintsünk egy példaprogramot az MPI_Type_contiguous használatára! 20. melléklet: main5_3_1a.c Az MPI_Type_vector mátrixokból almátrixok kinyerésére szolgál. Paraméterként megadjuk, hogy a count darab blocklength hosszúságú oldtype típusú blokkok között stride darab oldtype típusú távolság legyen. int MPI_Type_vector ( int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype* newtype ); // Blokkok száma // Egy blokk hosszúsága // a késıbb megadott // adattípusban // A blokkok kezdıcímei közötti // egységek száma // Blokk egységének adattípusa // Új adattípus Tekintsünk egy példaprogramot az MPI_Type_contiguous használatára! 21. melléklet: main5_3_1b.c 49

50 Még az MPI_Type_vector-nál is nagyobb szabadságot ad nekünk az új adattípusok létre hozásában az MPI_Type_indexed függvény, mert a blokkok hosszát és távolságát is blokkonként adhatjuk meg. Továbbá lehetıségünk van egy tömbrészletet egy üzeneten belül többször elküldeni, ugyanis minden blokk kezdıcímét a struktúra kezdıcímétıl mérve kell megadni. int MPI_Type_indexed ( int count, int* array_of_blocklengths, int* array_of_displacements, MPI_Datatype oldtype, MPI_Datatype *newtype ); // Blokkok száma // Blokkok hosszai // Blokkok kezdıcímei // a struktúra // kezdıcíméhez // képest a felhasznált // adattípusban // Blokkok egységének // adattípusa // Új adattípus Tekintsünk egy példaprogramot az MPI_Type_indexed használatára! 22. melléklet: main5_3_1c.c Az MPI_Type_struct az MPI_Type_indexed különbözı adattípusokra való kiterjesztése a legáltalánosabban használt függvény új adattípusok elıkészítésére. Paraméterként megadjuk, hogy count darab blokk tartozzon egy struktúrába, melyeknek hosszai az array_of_blocklengths tömbben, kezdıcímei az array_of_displacements tömbben, adattípusai pedig az array_of_types tömbben találhatóak. A blokkok kezdıcímeit a struktúra kezdıcíméhez képest kell megadni. Ezeket a kezdıcímeket tehát a struktúra tagjainak címeinek lekérdeésével, majd ezekbıl a struktúra kezdıcímének kivonásával kapjuk meg. int MPI_Type_struct ( int count, int* array_of_blocklengths, MPI_Aint* array_of_displacements, MPI_Datatype* array_of_types, MPI_Datatype* newtype ); // Blokkok száma // Blokkok hosszai // Blokkok kezdıcímei // a struktúra // kezdıcíméhez // képest byte-ban // Blokkok adattípusa // Új adattípus Tekintsünk egy példaprogramot az MPI_Type_struct használatára! 23. melléklet: main5_3_1d.c 50

51 A címek számítására az MPI_Address függvényt ajánlott használni, mely paraméterként visszaadja az adott változó címét. A & címoperátor használata egyszerőbbnek tőnik, de erre a célra kevésbé biztonságos. Ugyanis a &variable valójában egy pointer és nem egy cím. A C nyelv pedig nem követeli meg, hogy egy pointer értéke a mutatott változó abszolút címe legyen; ami általában azért teljesül. Mivel a pointerek értékének képzése nagyban függ az adott architektúrától, ezért ha biztonságosan mőködı kódra törekszünk, akkor használjuk az MPI_Address-t. int MPI_Address ( void* location, // Változó MPI_Aint* address ); // Változó címe II Az új adattípus (struktúra) véglegesítése Ahhoz, hogy használhassuk az újonnan létrehozott adattípusunkat, véglegesítenünk kell az MPI_Type_commit függvénnyel. Az adattípust csak elsı használata elıtt kell véglegesítenünk, és ezt követıen, mint az alapértelmezett adattípusokat használhatjuk. int MPI_Type_commit ( MPI_Datatype* datatype ); // Új adattípus Ha fel akarjuk szabadítani az adott származtatott adattípusunkat, akkor azt az MPI_Type_free függvénnyel tehetjük. Ha egy származtatott adattípust csak azért hoztunk létre, hogy egy másik származtatott adattípus létrehozásában felhasználjuk, akkor ezt követıen az új adattípus sérülése nélkül felszabadíthatjuk. Legkésıbb a programunk végén a származtatott adattípusokat érdemes felszabadítani. int MPI_Type_free ( MPI_Datatype* datatype ); // Felszabadítandó adattípus Ellenırzı kérdések: 1.) Milyen jellegő feladatok kapcsán lehet szükség összetett, származtatott adattípusok használatára? 2.) Hogyan továbbítja az MPI az adattípusokat? Emiatt milyen hibát nem szabad elkövetni? Ugyanakkor milyen elınyei vannak ennek az eljárásnak? 3.) Hogyan történik az adatok csomagolt átvitele? Mikor érdemes ezt a módszert választani? 4.) Milyen két fı lépése van az új adattípus létrehozásának? Mikor érdemes ezt a módszert választani? Feladatok: 1.) Próbáljuk ki a main5_2a.c példaprogramot! 2.) Próbáljuk ki a main5_2b.c példaprogramot! 3.) Próbáljuk ki a main5_3_1a.c példaprogramot! 4.) Próbáljuk ki a main5_3_1b.c példaprogramot! 5.) Próbáljuk ki a main5_3_1c.c példaprogramot! 6.) Próbáljuk ki a main5_3_1d.c példaprogramot! 7.) Írjunk egy programot, melyben egy struktúratömböt átküldünk az egyik processztıl a másiknak! Fogalmazzuk meg, hogy mi alapján döntöttünk a csomagolt átvitel vagy az új adattípus létrehozása és használata mellett! 51

52 II.6. Cartesian topológiák áttekintése Egy kép, vagy egy mátrix feldolgozásánál, ezeket érdemes részekre bontani, és párhuzamosan feldolgozni. Az adathalmazt a származtatott adattípusok kapcsán megismert függvények alkalmazásával többféleképpen darabolhatjuk kisebb részekre: akár sávokra, akár kisebb téglalapokra. Minden részt külön processzhez rendelünk, emiatt elınyös, ha a processzek azonosítói között valamilyen konvenciót tudunk kialakítani és követni, hogy átláthatóbbá és nem utolsó sorban tömörebbé, kifejezıbbé tegyük a kódunkat. Ezen konvenció virtuális topológiában nyilvánul meg, melynek egyik MPI által támogatott fajtája a cartesian topológia. A topológia processzek egymáshoz viszonyított kapcsolata, amit azonosítóik sorrendbe, rendszerbe foglalásával adunk meg. A processz azonosítók mindig kommunikátorban értelmezettek. Tehát, ha egy processz több kommunikátoba is tartozik, akkor minden kommunikátorban más és más az azonosítója, ami alapján hivatkozni lehet rá. Tehát egy új topológiát egy új kommunikátor létrehozásával készíthetünk. II.6.1. Cartesian topológia létrehozása Az MPI_Cart_create függvény egy cartesian topológiát definiáló kommunikátor létrehozására szolgál. int MPI_Cart_create ( MPI_Comm old_comm, int ndims, int* dim_size, int* periods, int reorder, MPI_Comm* new_comm ); // Felhasználni kívánt // kommunikátor // Az új topológia // dimenzióinak száma // Az új topolgia // dimenzióinak méretei // Az új topológia az adott // dimenzióban periodikus (1), // vagy nem-periodikus (0) // A processzek azonosítójának // új kommunikátorbeli // átnevezésének/átrendezésének // engedélyezése (1), // vagy tiltása (0) // Új kommunikátor Például, ha a processzeket egy négyzetháló rácspontjaihoz szeretnénk hozzárendelni, akkor kétdimenziós topológiát kell létrehozunk. A sorok és oszlopok számát a dim_size tömbben adjuk meg. Az így keletkezı processz-azonosítók kétdimenziós esetben egy számpárból fognak állni, amik koordinátaként is felfoghatók. A cartesian topológia esetében az, hogy a topológia valamelyik dimenziójának irányában periodikus, azt jelenti, hogy az adott dimenzió szerinti elsı és utolsó processz szomszédos egymással. Másként fogalmazva, ha egy cartesian topológia egy dimenziójának irányában periodikus, akkor bármely szám, melynek az adott dimenzió méretével vett modulója megegyezik egy processz azonosítójának megfelelı koordinátájával, akkor az az adott processzt jelöli ki. Ha egy papírra rajzolt négyzethálóval szeretnénk szemléltetni egy egydimenzió irányában periodikus, kétdimenziós topológiát, akkor a papírt az említett dimenzió irányában hengerré kéne hajtanunk. Ha pedig mindkét dimenzió irányában periodikus a kétdimenziós topológia, akkor a négyzethálós parírunk tórusszá alakul. A kétdimenziós topológia periodicitásának variációi a következıképpen befolyásolják a processzek azonosítóit (12. ábra). 52

53 12. ábra A processzek új azonosító koordinátái mögött, zárójelben az eredeti, szekvenciális azonosítójukat tüntettük fel. A -1 -es azonosító azt jelenti, hogy az azonosítóhoz nem tartozik prcessz; amit másképp az MPI_PROC_NULL azonosítóval jelölünk. Valójában, mivel a kommunikációs függvények csak egyváltozós processzazonosítókat tudnak értelmezni, ezért a cartesian topológián belül is szekvenciálisak a processz-azonosítók, viszont mindegyikükhöz tartozik egy ndims tagú koordináta. A reorder paraméter értékétıl függıen a létrejövı cartesian topológián belül átnevezıdhetnek a szekvenciális processz-azonosítók az MPI_COMM_WORLD-beli szekvenciális processz-azonosítókhoz képest. Ennek engedésekor az MPI a cartesian topológiához legjobban illeszkedıen nevezi át az adott architektúrán futó processzeket. Így lehetıvé válik, hogy a processzorok közelségét is a hatékonyság malmára hajtsuk. Az MPI_Cart_create egy kollektív kommunikációs függvény, amit ebbıl következıen a felhasználandó kommunikátor összes processzének meg kell hívnia. Ha több pocessz áll rendelkezésre, mint amennyire a cartesien topológia létrehozásához szükség van, akkor a felesleges processzek MPI_PROC_NULL azonosítót kapnak. Processzhiány esetén pedig az MPI_Cart_create függvény hibakóddal tér vissza. II.6.2. A szekvenciális és a koordináta processz-azonosítók közötti konverzió A cartesian topológia a többkoordinátás azonosítók bevezetésével lehetıséget teremt a processzek struktúrált kezelésére, viszont a kommunikációs függvények csak egyetlen változót tudnak processz-azonosítójént értelmezni. Emiatt szükség van a processzek cartesian topológiabeli koordináta azonosítói és a szekvenciális azonosítói közötti konverzióra. Erre az átalakításra szolgálnak az MPI_CART_COORDS és az MPI_CART_RANK függvények. Az MPI_Cart_coords függvénnyel a szekvenciális processz-azonosító és a topológia legnagyobb dimenziószámának ismeretében meghatározhatók a processz topológiabeli koordináta azonosítói. 53

Párhuzamos programozási platformok

Párhuzamos programozási platformok Párhuzamos programozási platformok Parallel számítógép részei Hardver Több processzor Több memória Kapcsolatot biztosító hálózat Rendszer szoftver Párhuzamos operációs rendszer Konkurenciát biztosító programozási

Részletesebben

Csoportos üzenetszórás optimalizálása klaszter rendszerekben

Csoportos üzenetszórás optimalizálása klaszter rendszerekben Csoportos üzenetszórás optimalizálása klaszter rendszerekben Készítette: Juhász Sándor Csikvári András Budapesti Műszaki és Gazdaságtudományi Egyetem Villamosmérnöki és Informatikai Kar Automatizálási

Részletesebben

Irányítástechnika 1. 9. Elıadás. PLC-k programozása

Irányítástechnika 1. 9. Elıadás. PLC-k programozása Irányítástechnika 1 9. Elıadás PLC-k programozása Irodalom - Helmich József: Irányítástechnika I, 2005 - Zalotay Péter: PLC tanfolyam - Jancskárné Anweiler Ildikó: PLC programozás az IEC 1131-3 szabvány

Részletesebben

QuickSend. E-Mail, és SMS küldés program. Felhasználói kézikönyv. Program dokumentáció 2008 JMGM Magyarország Informatikai Kft.

QuickSend. E-Mail, és SMS küldés program. Felhasználói kézikönyv. Program dokumentáció 2008 JMGM Magyarország Informatikai Kft. E-Mail, és SMS küldés program Felhasználói kézikönyv Program dokumentáció 2008 JMGM Magyarország Informatikai Kft. -1- (30)264-92-05 Tartalomjegyzék A programról általában... 3 Hardware software igény...

Részletesebben

Bevezetés az MPI programozásba példákon keresztül Várady, Géza Zaválnij, Bogdán

Bevezetés az MPI programozásba példákon keresztül Várady, Géza Zaválnij, Bogdán Várady, Géza Zaválnij, Bogdán írta Várady, Géza és Zaválnij, Bogdán Publication date 2015 Szerzői jog 2015 Várady Géza, Zaválnij Bogdán Tartalom Bevezetés az MPI programozásba... 1 1. 1 Bevezetés... 1

Részletesebben

KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Projektmenedzsment. Készítette: Dr. Sediviné Balassa Ildikó

KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Projektmenedzsment. Készítette: Dr. Sediviné Balassa Ildikó Leonardo da Vinci Kísérleti projekt által továbbfejlesztett Szakmai program KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Projektmenedzsment Készítette: Dr. Sediviné Balassa

Részletesebben

2009.03.16. Ezeket a kiemelkedı sebességő számítógépeket nevezzük szuperszámítógépeknek.

2009.03.16. Ezeket a kiemelkedı sebességő számítógépeket nevezzük szuperszámítógépeknek. A számítási kapacitás hiánya a világ egyik fontos problémája. Számos olyan tudományos és mőszaki probléma létezik, melyek megoldásához a szokásos számítógépek, PC-k, munkaállomások, de még a szerverek

Részletesebben

OOP. Alapelvek Elek Tibor

OOP. Alapelvek Elek Tibor OOP Alapelvek Elek Tibor OOP szemlélet Az OOP szemlélete szerint: a valóságot objektumok halmazaként tekintjük. Ezen objektumok egymással kapcsolatban vannak és együttműködnek. Program készítés: Absztrakciós

Részletesebben

Adatstruktúrák, algoritmusok, objektumok

Adatstruktúrák, algoritmusok, objektumok Adatstruktúrák, algoritmusok, objektumok 2. Az objektumorientált programozási paradigma 1 A szoftverkrízis Kihívások a szoftverfejlesztés módszereivel szemben 1. A szoftveres megoldások szerepe folyamatosan

Részletesebben

Programozás alapjai Bevezetés

Programozás alapjai Bevezetés Programozás alapjai Bevezetés Miskolci Egyetem Általános Informatikai Tanszék Programozás alapjai Bevezetés SWF1 / 1 Tartalom A gépi kódú programozás és hátrányai A magas szintÿ programozási nyelv fogalma

Részletesebben

KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Kommunikáció és viselkedéskultúra. Készítette: Dr.

KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Kommunikáció és viselkedéskultúra. Készítette: Dr. Leonardo da Vinci Kísérleti projekt által továbbfejlesztett Szakmai program KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Kommunikáció és viselkedéskultúra Készítette: Dr.

Részletesebben

Adatbáziskezelés alapjai. jegyzet

Adatbáziskezelés alapjai. jegyzet Juhász Adrienn Adatbáziskezelés alapja 1 Adatbáziskezelés alapjai jegyzet Készítette: Juhász Adrienn Juhász Adrienn Adatbáziskezelés alapja 2 Fogalmak: Adatbázis: logikailag összefüggı információ vagy

Részletesebben

KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Adatbáziskezelés III. (elmélet+gyakorlat) Készítette: Kupcsikné Fitus Ilona

KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Adatbáziskezelés III. (elmélet+gyakorlat) Készítette: Kupcsikné Fitus Ilona Leonardo da Vinci Kísérleti projekt által továbbfejlesztett Szakmai program KÉPZÉS NEVE: Informatikai statisztikus és gazdasági tervezı TANTÁRGY CÍME: Adatbáziskezelés III. (elmélet+gyakorlat) Készítette:

Részletesebben

Informatika. 3. Az informatika felhasználási területei és gazdasági hatásai

Informatika. 3. Az informatika felhasználási területei és gazdasági hatásai Informatika 1. Hírek, információk, adatok. Kommunikáció. Definiálja a következő fogalmakat: Információ Hír Adat Kommunikáció Ismertesse a kommunikáció modelljét. 2. A számítástechnika története az ENIAC-ig

Részletesebben

A tartalomelemzés szőkebb értelemben olyan szisztematikus kvalitatív eljárás, amely segítségével bármely szöveget értelmezni tudunk, és

A tartalomelemzés szőkebb értelemben olyan szisztematikus kvalitatív eljárás, amely segítségével bármely szöveget értelmezni tudunk, és Tartalomelemzés A tartalomelemzés szőkebb értelemben olyan szisztematikus kvalitatív eljárás, amely segítségével bármely szöveget értelmezni tudunk, és végeredményben a szöveg írójáról vonhatunk le következtetéseket.

Részletesebben

Kommunikáció. 3. előadás

Kommunikáció. 3. előadás Kommunikáció 3. előadás Kommunikáció A és B folyamatnak meg kell egyeznie a bitek jelentésében Szabályok protokollok ISO OSI Többrétegű protokollok előnyei Kapcsolat-orientált / kapcsolat nélküli Protokollrétegek

Részletesebben

Szövegek C++ -ban, a string osztály

Szövegek C++ -ban, a string osztály Szövegek C++ -ban, a string osztály A string osztály a Szabványos C++ könyvtár (Standard Template Library) része és bár az objektum-orientált programozásról, az osztályokról, csak később esik szó, a string

Részletesebben

Java I. A Java programozási nyelv

Java I. A Java programozási nyelv Java I. A Java programozási nyelv története,, alapvetı jellemzıi Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2007. 02. 12. Java I.: Történet, jellemzık, JDK JAVA1 / 1 Egy kis történelem

Részletesebben

A WINETTOU Távközlési Szolgáltató Korlátolt Felelısségő Társaság. Internet szolgáltatásra vonatkozó Általános Szerzıdéses Feltételek

A WINETTOU Távközlési Szolgáltató Korlátolt Felelısségő Társaság. Internet szolgáltatásra vonatkozó Általános Szerzıdéses Feltételek A WINETTOU Távközlési Szolgáltató Korlátolt Felelısségő Társaság Internet szolgáltatásra vonatkozó Általános Szerzıdéses Feltételek IV. számú módosításának kivonata 2010. március 15. Általános szerzıdési

Részletesebben

Rekurzió. Dr. Iványi Péter

Rekurzió. Dr. Iványi Péter Rekurzió Dr. Iványi Péter 1 Függvényhívás void f3(int a3) { printf( %d,a3); } void f2(int a2) { f3(a2); a2 = (a2+1); } void f1() { int a1 = 1; int b1; b1 = f2(a1); } 2 Függvényhívás void f3(int a3) { printf(

Részletesebben

SZAKDOLGOZAT ÓBUDAI EGYETEM. Neumann János Informatikai kar Alba Regia Egyetemi Központ

SZAKDOLGOZAT ÓBUDAI EGYETEM. Neumann János Informatikai kar Alba Regia Egyetemi Központ ÓBUDAI EGYETEM Neumann János Informatikai kar Alba Regia Egyetemi Központ SZAKDOLGOZAT OE-NIK Hallgató neve: Berencsi Gergő Zsolt 2010. Törzskönyvi száma: T 000123/FI38878/S-N Tartalomjegyzék Tartalmi

Részletesebben

Iman 3.0 szoftverdokumentáció

Iman 3.0 szoftverdokumentáció Melléklet: Az iman3 program előzetes leírása. Iman 3.0 szoftverdokumentáció Tartalomjegyzék 1. Az Iman rendszer...2 1.1. Modulok...2 1.2. Modulok részletes leírása...2 1.2.1. Iman.exe...2 1.2.2. Interpreter.dll...3

Részletesebben

Új generációs hálózatok. Bakonyi Péter c.docens

Új generációs hálózatok. Bakonyi Péter c.docens Új generációs hálózatok Bakonyi Péter c.docens IKT trendek A konvergencia következményei Korábban: egy hálózat egy szolgálat Konvergencia: végberendezések konvergenciája, szolgálatok konvergenciája (szolgáltatási

Részletesebben

SZEGHALOM VÁROS ÖNKORMÁNYZATA POLGÁRMESTERI HIVATALÁNAK SZERVEZETFEJLESZTÉSE MINİSÉGIRÁNYÍTÁS AZ ÖNKORMÁNYZATOKNÁL 1. MINİSÉGÜGY AZ ÖNKORMÁNYZATOKNÁL

SZEGHALOM VÁROS ÖNKORMÁNYZATA POLGÁRMESTERI HIVATALÁNAK SZERVEZETFEJLESZTÉSE MINİSÉGIRÁNYÍTÁS AZ ÖNKORMÁNYZATOKNÁL 1. MINİSÉGÜGY AZ ÖNKORMÁNYZATOKNÁL V I AD ORO KÖZIGAZGATÁSFEJLESZTÉSI TANÁCSADÓ ÉS SZOLGÁLTATÓ KFT. 8230 BALATONFÜRED, VAJDA J. U. 33. +36 (30) 555-9096 A R O P.PALYAZAT@YAHOO.COM SZEGHALOM VÁROS ÖNKORMÁNYZATA POLGÁRMESTERI HIVATALÁNAK

Részletesebben

Hálózatok I. A tárgy célkitűzése

Hálózatok I. A tárgy célkitűzése Hálózatok I. A tárgy célkitűzése A tárgy keretében a hallgatók megismerkednek a számítógép-hálózatok felépítésének és működésének alapelveivel. Alapvető ismereteket szereznek a TCP/IP protokollcsalád megvalósítási

Részletesebben

A számítógép-hálózat egy olyan speciális rendszer, amely a számítógépek egymás közötti kommunikációját biztosítja.

A számítógép-hálózat egy olyan speciális rendszer, amely a számítógépek egymás közötti kommunikációját biztosítja. A számítógép-hálózat egy olyan speciális rendszer, amely a számítógépek egymás közötti kommunikációját biztosítja. A hálózat kettő vagy több egymással összekapcsolt számítógép, amelyek között adatforgalom

Részletesebben

Már megismert fogalmak áttekintése

Már megismert fogalmak áttekintése Interfészek szenasi.sandor@nik.bmf.hu PPT 2007/2008 tavasz http://nik.bmf.hu/ppt 1 Témakörök Polimorfizmus áttekintése Interfészek Interfészek kiterjesztése Eseménykezelési módszerek 2 Már megismert fogalmak

Részletesebben

Irányítástechnika 1. 8. Elıadás. PLC rendszerek konfigurálása

Irányítástechnika 1. 8. Elıadás. PLC rendszerek konfigurálása Irányítástechnika 1 8. Elıadás PLC rendszerek konfigurálása Irodalom - Helmich József: Irányítástechnika I, 2005 - Zalotay Péter: PLC tanfolyam - Klöckner-Möller Hungária: Hardverleírás és tervezési segédlet,

Részletesebben

Szolgáltatási szint és performancia menedzsment a PerformanceVisor alkalmazással. HOUG konferencia, 2007 április 19.

Szolgáltatási szint és performancia menedzsment a PerformanceVisor alkalmazással. HOUG konferencia, 2007 április 19. Szolgáltatási szint és performancia menedzsment a PerformanceVisor alkalmazással Szabó Balázs HOUG konferencia, 2007 április 19. Mirıl lesz szó NETvisor Kft bemutatása Szolgáltatási szint alapjai Performancia

Részletesebben

A LOGSYS GUI. Fehér Béla Raikovich Tamás, Laczkó Péter BME MIT FPGA laboratórium

A LOGSYS GUI. Fehér Béla Raikovich Tamás, Laczkó Péter BME MIT FPGA laboratórium BUDAPESTI MŐSZAKI ÉS GAZDASÁGTUDOMÁNYI EGYETEM VILLAMOSMÉRNÖKI ÉS INFORMATIKAI KAR MÉRÉSTECHNIKA ÉS INFORMÁCIÓS RENDSZEREK TANSZÉK A LOGSYS GUI Fehér Béla Raikovich Tamás, Laczkó Péter BME MIT atórium

Részletesebben

egy szisztolikus példa

egy szisztolikus példa Automatikus párhuzamosítás egy szisztolikus példa Áttekintés Bevezetés Példa konkrét szisztolikus algoritmus Automatikus párhuzamosítási módszer ötlet Áttekintés Bevezetés Példa konkrét szisztolikus algoritmus

Részletesebben

C programozási nyelv Pointerek, tömbök, pointer aritmetika

C programozási nyelv Pointerek, tömbök, pointer aritmetika C programozási nyelv Pointerek, tömbök, pointer aritmetika Dr. Schuster György 2011. június 16. C programozási nyelv Pointerek, tömbök, pointer aritmetika 2011. június 16. 1 / 15 Pointerek (mutatók) Pointerek

Részletesebben

Feladataink, kötelességeink, önkéntes és szabadidős tevékenységeink elvégzése, a közösségi életformák gyakorlása döntések sorozatából tevődik össze.

Feladataink, kötelességeink, önkéntes és szabadidős tevékenységeink elvégzése, a közösségi életformák gyakorlása döntések sorozatából tevődik össze. INFORMATIKA Az informatika tantárgy ismeretkörei, fejlesztési területei hozzájárulnak ahhoz, hogy a tanuló az információs társadalom aktív tagjává válhasson. Az informatikai eszközök használata olyan eszköztudást

Részletesebben

2009.04.29. 2009. április 24. INFO Savaria 2009 2. 2009. április 24. INFO Savaria 2009 4. 2009. április 24. INFO Savaria 2009 3

2009.04.29. 2009. április 24. INFO Savaria 2009 2. 2009. április 24. INFO Savaria 2009 4. 2009. április 24. INFO Savaria 2009 3 Négy adatbázis-kezelı rendszer összehasonlítása webes környezetben Sterbinszky Nóra snorav@gmail.com Áttekintés Növekvı igény hatékony adatbázis- kezelıkre a világhálón Hogyan mérhetı ezek teljesítménye

Részletesebben

Hálózatok. Alapismeretek. A hálózatok célja, építőelemei, alapfogalmak

Hálózatok. Alapismeretek. A hálózatok célja, építőelemei, alapfogalmak Hálózatok Alapismeretek A hálózatok célja, építőelemei, alapfogalmak A hálózatok célja A korai időkben terminálokat akartak használni a szabad gépidők lekötésére, erre jó lehetőség volt a megbízható és

Részletesebben

Balázs Ildikó* ELEKTRONIKUS KOMMUNIKÁCIÓ JÖVİNK KULCSAI

Balázs Ildikó* ELEKTRONIKUS KOMMUNIKÁCIÓ JÖVİNK KULCSAI Balázs Ildikó* ELEKTRONIKUS KOMMUNIKÁCIÓ JÖVİNK KULCSAI AZ INFORMATIKA TÉRNYERÉSE A HÉTKÖZNAPI ÉLETBEN, AZ ÜZLETI FOLYAMATOKBAN A számítástechnika, a digitális számítógépek története minden más korábbi

Részletesebben

Útmutató az IP és Routing mérésekben használt Cisco routerek alapszint konfigurációjához i

Útmutató az IP és Routing mérésekben használt Cisco routerek alapszint konfigurációjához i Útmutató az IP és Routing mérésekben használt Cisco routerek alapszint konfigurációjához i 1. Bevezetés (készítette: Fodor Kristóf fodork@tmit.bme.hu) A routerek a hozzájuk csatolt hálózati szegmensek

Részletesebben

InFo-Tech emelt díjas SMS szolgáltatás. kommunikációs protokollja. Ver.: 2.1

InFo-Tech emelt díjas SMS szolgáltatás. kommunikációs protokollja. Ver.: 2.1 InFo-Tech emelt díjas SMS szolgáltatás kommunikációs protokollja Ver.: 2.1 InFo-Tech SMS protokoll Az emelt díjas SMS szolgáltatással kapcsolatos beállításokat az adminisztrációs felületen végezheti el.

Részletesebben

KIRA. KIRA rendszer. Telepítési útmutató v1

KIRA. KIRA rendszer. Telepítési útmutató v1 KIRA rendszer Telepítési útmutató v1 1. Bevezetés A dokumentáció, illetve a dokumentáció mellékleteként megtalálható állományok segítségével készíthető fel a kliens oldali számítógép a KIRA rendszer működtetésére.

Részletesebben

Párhuzamos és Elosztott Rendszerek

Párhuzamos és Elosztott Rendszerek MISKOLCI EGYETEM GÉPÉSZMÉRNÖKI ÉS INFORMATIKAI KAR Párhuzamos és Elosztott Rendszerek KÉSZÍTETTE: DR. MILEFF PÉTER Miskolci Egyetem Általános Informatikai Tanszék 2009 1 Szuperszámítógépektıl napjainkig

Részletesebben

Számítástechnika nyugdíjasoknak. 2011. Február 16.

Számítástechnika nyugdíjasoknak. 2011. Február 16. Számítástechnika nyugdíjasoknak 2011. Február 16. A mai előadás témája Az internet Az Internet a hálózatok hálózata, avagy egy mindent és mindenkit összekötı világmérető informatikai szuper sztráda. Szerepe

Részletesebben

1. tétel. A kommunikáció információelméleti modellje. Analóg és digitális mennyiségek. Az információ fogalma, egységei. Informatika érettségi (diák)

1. tétel. A kommunikáció információelméleti modellje. Analóg és digitális mennyiségek. Az információ fogalma, egységei. Informatika érettségi (diák) 1. tétel A kommunikáció információelméleti modellje. Analóg és digitális mennyiségek. Az információ fogalma, egységei Ismertesse a kommunikáció általános modelljét! Mutassa be egy példán a kommunikációs

Részletesebben

Programozás I. gyakorlat

Programozás I. gyakorlat Programozás I. gyakorlat 1. gyakorlat Alapok Eszközök Szövegszerkesztő: Szintaktikai kiemelés Egyszerre több fájl szerkesztése pl.: gedit, mcedit, joe, vi, Notepad++ stb. Fordító: Szöveges file-ban tárolt

Részletesebben

Operációs rendszerek Folyamatok 1.1

Operációs rendszerek Folyamatok 1.1 Operációs rendszerek p. Operációs rendszerek Folyamatok 1.1 Pere László (pipas@linux.pte.hu) PÉCSI TUDOMÁNYEGYETEM TERMÉSZETTUDOMÁNYI KAR INFORMATIKA ÉS ÁLTALÁNOS TECHNIKA TANSZÉK A rendszermag Rendszermag

Részletesebben

Java II. I A Java programozási nyelv alapelemei

Java II. I A Java programozási nyelv alapelemei Java2 / 1 Java II. I A Java programozási nyelv alapelemei Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2009. 02. 09. Java II.: Alapelemek JAVA2 / 1 A Java formalizmusa A C, illetve

Részletesebben

MÉRNÖK-SZÓTÁR. számítógépes program rendszer. magyar-angol-német-orosz és más nyelvek. Mérnökök által összeállított szakmai szótárak, szakembereknek!

MÉRNÖK-SZÓTÁR. számítógépes program rendszer. magyar-angol-német-orosz és más nyelvek. Mérnökök által összeállított szakmai szótárak, szakembereknek! MÉRNÖK-SZÓTÁR számítógépes program rendszer - Többnyelvő szakszótárak - Építıipari szakszótár - Gépipari szakszótár - Vasúti szakszótár - Nyelvi választék: magyar-angol-német-orosz és más nyelvek - Általános

Részletesebben

Szakdolgozat. A Microsoft Access módszertana. Témavezetı: Radványi Tibor Készítette: Erényi Péter, 2006 IV. évfolyam, számítástechnika szak

Szakdolgozat. A Microsoft Access módszertana. Témavezetı: Radványi Tibor Készítette: Erényi Péter, 2006 IV. évfolyam, számítástechnika szak Szakdolgozat A Microsoft Access módszertana Témavezetı: Radványi Tibor Készítette: Erényi Péter, 2006 IV. évfolyam, számítástechnika szak TARTALOMJEGYZÉK TARTALOMJEGYZÉK... 2 ELİSZÓ... 5 AZ ADATBÁZIS-KEZELÉS-

Részletesebben

A KÖZÉPSZINTŰ ÉRETTSÉGI VIZSGA INFORMATIKA TÉMAKÖREI: 1. Információs társadalom

A KÖZÉPSZINTŰ ÉRETTSÉGI VIZSGA INFORMATIKA TÉMAKÖREI: 1. Információs társadalom A KÖZÉPSZINTŰ ÉRETTSÉGI VIZSGA INFORMATIKA TÉMAKÖREI: 1. Információs társadalom 1.1. A kommunikáció 1.1.1. A kommunikáció általános modellje 1.1.2. Információs és kommunikációs technológiák és rendszerek

Részletesebben

Készítette: Trosztel Mátyás Konzulens: Hajós Gergely

Készítette: Trosztel Mátyás Konzulens: Hajós Gergely Készítette: Trosztel Mátyás Konzulens: Hajós Gergely Monte Carlo Markov Chain MCMC során egy megfelelően konstruált Markov-lánc segítségével mintákat generálunk. Ezek eloszlása követi a céleloszlást. A

Részletesebben

VÍZÓRA NYÍLVÁNTARTÓ RENDSZER

VÍZÓRA NYÍLVÁNTARTÓ RENDSZER Debreceni Egyetem Informatikai Kar VÍZÓRA NYÍLVÁNTARTÓ RENDSZER Dr. Kuki Attila Egyetemi Adjunktus Informatikai Rendszerek és Hálózatok Tanszék GYÖKÉR RÓBERT Mérnök Informatikus levelezı Debrecen 2009.

Részletesebben

Matematikai alapok és valószínőségszámítás. Középértékek és szóródási mutatók

Matematikai alapok és valószínőségszámítás. Középértékek és szóródási mutatók Matematikai alapok és valószínőségszámítás Középértékek és szóródási mutatók Középértékek A leíró statisztikák talán leggyakrabban használt csoportját a középértékek jelentik. Legkönnyebben mint az adathalmaz

Részletesebben

Hálózati adminisztráció Linux (Ubuntu 9.04) 9. gyakorlat

Hálózati adminisztráció Linux (Ubuntu 9.04) 9. gyakorlat Hálózati adminisztráció Linux (Ubuntu 9.04) 9. gyakorlat Johanyák Zsolt Csaba 1 1. DNS szerver telepítése és beállítása Az alábbi beállításokat a szerver virtuális gépen kell végrehajtani. A DNS kiszolgáló

Részletesebben

Az Innováció és az ember avagy: Miért (nem) szeretnek a felhasználók kattintani?

Az Innováció és az ember avagy: Miért (nem) szeretnek a felhasználók kattintani? Az Innováció és az ember avagy: Miért (nem) szeretnek a felhasználók kattintani? Esszé az Innováció és kommunikáció tantárgyhoz Készítette: Polgár Péter Balázs, 2007. január 16. A 21. század elejére még

Részletesebben

Windows Server 2008 Standard telepítése lépésenként VirtualBox virtuális gépbe

Windows Server 2008 Standard telepítése lépésenként VirtualBox virtuális gépbe Windows Server 2008 Standard telepítése lépésenként VirtualBox virtuális gépbe Rádi Viktor 1. Bevezetés 1.1. Célok Ez a bemutató a hallgatókat hivatott segíteni a VirtualBox használatának elsajátításában

Részletesebben

6. A szervezet. Az egyik legfontosabb vezetıi feladat. A szervezetek kialakítása, irányítása, mőködésük ellenırzése, hatékonyságuk növelése,

6. A szervezet. Az egyik legfontosabb vezetıi feladat. A szervezetek kialakítása, irányítása, mőködésük ellenırzése, hatékonyságuk növelése, 6. A szervezet Az egyik legfontosabb vezetıi feladat A szervezetek kialakítása, irányítása, mőködésük ellenırzése, hatékonyságuk növelése, 1 Formális és informális szervezetek A formális szervezet formákban

Részletesebben

Alkalmazások fejlesztése A D O K U M E N T Á C I Ó F E L É P Í T É S E

Alkalmazások fejlesztése A D O K U M E N T Á C I Ó F E L É P Í T É S E Alkalmazások fejlesztése A D O K U M E N T Á C I Ó F E L É P Í T É S E Követelmény A beadandó dokumentációját a Keszthelyi Zsolt honlapján található pdf alapján kell elkészíteni http://people.inf.elte.hu/keszthelyi/alkalmazasok_fejlesztese

Részletesebben

Operációsrendszerek. 3. elıadás. Állományszervezés, felhasználói felületek

Operációsrendszerek. 3. elıadás. Állományszervezés, felhasználói felületek Operációsrendszerek 3. elıadás Állományszervezés, felhasználói felületek Bevezetés Állományszervezés Fizikai Logikai Stratégiák Felhasználói felületek Parancsmódú GUI X-Windows Állományszervezés Az állományszervezés:

Részletesebben

Tevékenység: Követelmények:

Tevékenység: Követelmények: 3.1. Szíjhajtások Tevékenység: Olvassa el a jegyzet 146-162 oldalain található tananyagát! Tanulmányozza át a segédlet 10. és 10.1. fejezeteiben lévı kidolgozott feladatait! A tananyag tanulmányozása közben

Részletesebben

Telepítési útmutató DoktorInfo B300 jelentéshez

Telepítési útmutató DoktorInfo B300 jelentéshez Telepítési útmutató DoktorInfo B300 jelentéshez Letöltés A program telepítıjét a DoktorInfo CRM rendszerébıl lehet letölteni. Ehhez nem kell mást tenni, mint a http://crm.doktorinfo.com címen megadni a

Részletesebben

Tisztán kivehetı tendencia: kommunikációs hálózatok egyre bonyolultabbakká válnak Hálózat bonyolultsága

Tisztán kivehetı tendencia: kommunikációs hálózatok egyre bonyolultabbakká válnak Hálózat bonyolultsága @ Budapest University of Technology and Economics Nagy hálózatok evolúciója Gulyás András, Heszberger Zalán High Speed Networks Laboratory Internet trendek Tisztán kivehetı tendencia: kommunikációs hálózatok

Részletesebben

Kecskeméti Fıiskola GAMF Kar Informatika Tanszék. Johanyák Zsolt Csaba

Kecskeméti Fıiskola GAMF Kar Informatika Tanszék. Johanyák Zsolt Csaba Kecskeméti Fıiskola GAMF Kar Informatika Tanszék Johanyák Zsolt Csaba 003 Tartalomjegyzék. Bevezetés.... A megbízhatóság fogalmai..... A termék idıtıl függı képességei...... Használhatóság /Üzemkészség/

Részletesebben

Java programozási nyelv

Java programozási nyelv Java programozási nyelv 2. rész Vezérlő szerkezetek Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2005. szeptember A Java programozási nyelv Soós Sándor 1/23 Tartalomjegyzék

Részletesebben

I. ADATLAP - A program általános tartalma. 2.1 Általános képzés 2.2 Nyelvi képzés 2.3 Szakmai képzés X 2.4. Egyéb

I. ADATLAP - A program általános tartalma. 2.1 Általános képzés 2.2 Nyelvi képzés 2.3 Szakmai képzés X 2.4. Egyéb I. ADATLAP - A program általános tartalma 1. A program megnevezése 1.1. Válságmenedzsment OKJ-s program esetén 1.2. OKJ száma is - 2. A program besorolása Csak egy terület jelölhetı meg! 2.1 Általános

Részletesebben

MÉRY Android Alkalmazás

MÉRY Android Alkalmazás MÉRY Android Alkalmazás Felhasználói kézikönyv Di-Care Zrt. Utolsó módosítás: 2014.06.12 Oldal: 1 / 7 Tartalomjegyzék 1. Bevezetés 3 1.1. MÉRY Android alkalmazás 3 1.2. A MÉRY Android alkalmazás funkciói

Részletesebben

Kommunikáció az EuroProt-IED multifunkcionális készülékekkel

Kommunikáció az EuroProt-IED multifunkcionális készülékekkel Kommunikáció az EuroProt-IED multifunkcionális készülékekkel A Protecta intelligens EuroProt készülékei a védelem-technika és a mikroprocesszoros technológia fejlődésével párhuzamosan követik a kommunikációs

Részletesebben

SZOFTVERES SZEMLÉLTETÉS A MESTERSÉGES INTELLIGENCIA OKTATÁSÁBAN _ Jeszenszky Péter Debreceni Egyetem, Informatikai Kar jeszenszky.peter@inf.unideb.

SZOFTVERES SZEMLÉLTETÉS A MESTERSÉGES INTELLIGENCIA OKTATÁSÁBAN _ Jeszenszky Péter Debreceni Egyetem, Informatikai Kar jeszenszky.peter@inf.unideb. SZOFTVERES SZEMLÉLTETÉS A MESTERSÉGES INTELLIGENCIA OKTATÁSÁBAN _ Jeszenszky Péter Debreceni Egyetem, Informatikai Kar jeszenszky.peter@inf.unideb.hu Mesterséges intelligencia oktatás a DE Informatikai

Részletesebben

PÉCSI TUDOMÁNYEGYETEM KÖZGAZDASÁGTUDOMÁNYI KAR REGIONÁLIS POLITIKA ÉS GAZDASÁGTAN DOKTORI ISKOLA

PÉCSI TUDOMÁNYEGYETEM KÖZGAZDASÁGTUDOMÁNYI KAR REGIONÁLIS POLITIKA ÉS GAZDASÁGTAN DOKTORI ISKOLA PÉCSI TUDOMÁNYEGYETEM KÖZGAZDASÁGTUDOMÁNYI KAR REGIONÁLIS POLITIKA ÉS GAZDASÁGTAN DOKTORI ISKOLA Iskolavezetı: Dr. Buday-Sántha Attila A TERÜLETI TURIZMUSFEJLESZTÉS LEHETİSÉGEI A SZÉKELYFÖLDÖN A doktori

Részletesebben

Tisztelettel köszöntöm a RITEK Zrt. Regionális Információtechnológiai Központ bemutatóján. www.ritek.hu

Tisztelettel köszöntöm a RITEK Zrt. Regionális Információtechnológiai Központ bemutatóján. www.ritek.hu Tisztelettel köszöntöm a RITEK Zrt. Regionális Információtechnológiai Központ bemutatóján. www.ritek.hu BEVEZETŐ az ASP-szolgáltatásról Az ASP-szolgáltatás (Application Service Providing) előnyei A megrendelő

Részletesebben

A kommunikáció szerepe a sportpedagógiában

A kommunikáció szerepe a sportpedagógiában Készítette: Dátum: 2008. 06. 06. A kommunikáció szerepe a sportpedagógiában A kommunikáció fogalma: A szó eredete szerint: communis (mn.) közös, általános communitas (fn.) közösség; communico (ige) közöl,

Részletesebben

C programozási nyelv

C programozási nyelv C programozási nyelv Előfeldolgozó utasítások Dr Schuster György 2011 május 3 Dr Schuster György () C programozási nyelv Előfeldolgozó utasítások 2011 május 3 1 / 15 A fordítás menete Dr Schuster György

Részletesebben

ÁLTALÁNOS SZERZİDÉSI FELTÉTELEK

ÁLTALÁNOS SZERZİDÉSI FELTÉTELEK B melléklet (TKSZ) ÁLTALÁNOS SZERZİDÉSI FELTÉTELEK külföldi, konvertibilis pénznemben nyilvántartott fizetési számlák és lekötött betétszámlák vezetéséhez természetes személyek részére Jelen Általános

Részletesebben

Programozás II. 2. Dr. Iványi Péter

Programozás II. 2. Dr. Iványi Péter Programozás II. 2. Dr. Iványi Péter 1 C++ Bjarne Stroustrup, Bell Laboratórium Első implementáció, 1983 Kezdetben csak precompiler volt C++ konstrukciót C-re fordította A kiterjesztés alapján ismerte fel:.cpp.cc.c

Részletesebben

Szaniszló Gábor, ABB Kft MEE szakmai nap elıadás, 2010.05.27. Az IEC61850-es szabvány gyakorlati alkalmazása. ABB Group June 1, 2010 Slide 1

Szaniszló Gábor, ABB Kft MEE szakmai nap elıadás, 2010.05.27. Az IEC61850-es szabvány gyakorlati alkalmazása. ABB Group June 1, 2010 Slide 1 Szaniszló Gábor, ABB Kft MEE szakmai nap elıadás, 2010.05.27. Az IEC61850-es szabvány gyakorlati alkalmazása June 1, 2010 Slide 1 Az ABB IEC61850 kompatibilis készülék palettája Szerverek - Konverteres

Részletesebben

Adatszerkezetek Tömb, sor, verem. Dr. Iványi Péter

Adatszerkezetek Tömb, sor, verem. Dr. Iványi Péter Adatszerkezetek Tömb, sor, verem Dr. Iványi Péter 1 Adat Adat minden, amit a számítógépünkben tárolunk és a külvilágból jön Az adatnak két fontos tulajdonsága van: Értéke Típusa 2 Adat típusa Az adatot

Részletesebben

MIKROFYN GÉPVEZÉRLÉSEK. 2D megoldások:

MIKROFYN GÉPVEZÉRLÉSEK. 2D megoldások: MIKROFYN GÉPVEZÉRLÉSEK Néhány szó a gyártóról: Az 1987-es kezdés óta a Mikrofyn A/S a világ öt legnagyobb precíziós lézer és gépvezérlés gyártója közé lépett. A profitot visszaforgatta az új termékek fejlesztésébe

Részletesebben

Nagy adattömbökkel végzett FORRÓ TI BOR tudományos számítások lehetőségei. kisszámítógépes rendszerekben. Kutató Intézet

Nagy adattömbökkel végzett FORRÓ TI BOR tudományos számítások lehetőségei. kisszámítógépes rendszerekben. Kutató Intézet Nagy adattömbökkel végzett FORRÓ TI BOR tudományos számítások lehetőségei Kutató Intézet kisszámítógépes rendszerekben Tudományos számításokban gyakran nagy mennyiségű aritmetikai művelet elvégzésére van

Részletesebben

Programozási alapismeretek 1. előadás

Programozási alapismeretek 1. előadás Programozási alapismeretek 1. előadás Tartalom A problémamegoldás lépései programkészítés folyamata A specifikáció Az algoritmus Algoritmikus nyelvek struktogram A kódolás a fejlesztői környezet 2/33 A

Részletesebben

Egy PIC-BASIC program fordítása, betöltése

Egy PIC-BASIC program fordítása, betöltése Egy PIC-BASIC program fordítása, betöltése A következıkben egy gyakorlati példán keresztül próbálom leírni, hogyan használhatjuk a PIC BASIC PRO 3 fordítóprogramot, tölthetjük be az elkészült program kódot

Részletesebben

Tartalom DCOM. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés

Tartalom DCOM. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés Tartalom D Szoftvertechnológia elıadás Architektúra D vs CORBA Példá 2 1987 Dynamic Data Exchange (DDE) Windows 2.0-ban Windows alkalmazások közötti adatcsere Ma is használatos (pl. vágólap) NetDDE NetBIOS

Részletesebben

Tantárgyi honlapok alkalmazása a legalapvet bb kérdés mennyiségi változásról min ségi változásról) 9.1. Tantárgyi honlapok lehet ségei és korlátai

Tantárgyi honlapok alkalmazása a legalapvet bb kérdés mennyiségi változásról min ségi változásról) 9.1. Tantárgyi honlapok lehet ségei és korlátai 9. Vig Zoltán Tantárgyi honlapok alkalmazása Az internettel támogatott oktatásnak léteznek és terjednek az egész képzést felölelı, integráló megoldásai, de sok esetben ilyen rendszer megvalósítására nincs

Részletesebben

Kft. ÁLTALÁNOS SZERZİDÉSI FELTÉTELEI INTERNET HOZZÁFÉRÉSI SZOLGÁLTATÁS IGÉNYBEVÉTELÉRE

Kft. ÁLTALÁNOS SZERZİDÉSI FELTÉTELEI INTERNET HOZZÁFÉRÉSI SZOLGÁLTATÁS IGÉNYBEVÉTELÉRE 1.oldal A Kft. ÁLTALÁNOS SZERZİDÉSI FELTÉTELEI INTERNET HOZZÁFÉRÉSI SZOLGÁLTATÁS IGÉNYBEVÉTELÉRE Létrehozva: 2004. február 05. Utolsó módosítás: 2010. március 1. Hatályba lépés: 2010. április 1-tıl 2.oldal

Részletesebben

Útmutató a MATARKA adatbázisból való adatátvételhez

Útmutató a MATARKA adatbázisból való adatátvételhez Útmutató a MATARKA adatbázisból való adatátvételhez A MATARKA - Magyar folyóiratok tartalomjegyzékeinek kereshetı adatbázisa a következı címrıl érhetı el: http://www.matarka.hu/ A publikációs lista kinyerése

Részletesebben

Ingatlanfinanszírozás és befektetés

Ingatlanfinanszírozás és befektetés Nyugat-Magyarországi Egyetem Geoinformatikai Kar Ingatlanmenedzser 8000 Székesfehérvár, Pirosalma u. 1-3. Szakirányú Továbbképzési Szak Ingatlanfinanszírozás és befektetés 5. Befektetések értékelése, ingatlanbefektetések

Részletesebben

Cloud Computing a gyakorlatban. Szabó Gyula (GDF) Benczúr András (ELTE) Molnár Bálint (ELTE)

Cloud Computing a gyakorlatban. Szabó Gyula (GDF) Benczúr András (ELTE) Molnár Bálint (ELTE) Cloud Computing a gyakorlatban Szabó Gyula (GDF) Benczúr András (ELTE) Molnár Bálint (ELTE) Az el adás felépítése CLOUD ALKALMAZÁSI FELMÉRÉSEK CLOUD COMPUTING DEFINICIÓK CLOUD SZOLGÁLTATÁSI ÉS ÜZEMEL-

Részletesebben

Image Processor BarCode Service. Felhasználói és üzemeltetői kézikönyv

Image Processor BarCode Service. Felhasználói és üzemeltetői kézikönyv Image Processor BarCode Service Áttekintés CIP-BarCode alkalmazás a Canon Image Processor programcsomag egyik tagja. A program feladata, hogy sokoldalú eszközt biztosítson képállományok dokumentumkezelési

Részletesebben

Vállalati információs rendszerek I, MIN5B6IN, 5 kredit, K. 4. A meghirdetés ideje (mintatanterv szerint vagy keresztfélében):

Vállalati információs rendszerek I, MIN5B6IN, 5 kredit, K. 4. A meghirdetés ideje (mintatanterv szerint vagy keresztfélében): Követelményrendszer 1. Tantárgynév, kód, kredit, választhatóság: Vállalati információs rendszerek I, MIN5B6IN, 5 kredit, K 2. Felelős tanszék: Informatika Szakcsoport 3. Szak, szakirány, tagozat: Műszaki

Részletesebben

Szakdolgozat. Uzonyi László

Szakdolgozat. Uzonyi László Szakdolgozat Uzonyi László Debrecen 2007 Debreceni Egyetem Informatika Kar Gépjármőkövetı rendszer fejlesztése Témavezetı: Kollár Lajos számítástechnikai munkatárs Készítette: Uzonyi László programozó

Részletesebben

Szilipet programok telepítése Hálózatos (kliens/szerver) telepítés Windows 7 operációs rendszer alatt

Szilipet programok telepítése Hálózatos (kliens/szerver) telepítés Windows 7 operációs rendszer alatt Szilipet programok telepítése Hálózatos (kliens/szerver) telepítés Windows 7 operációs rendszer alatt segédlet A Szilipet programok az adatok tárolásához Firebird adatbázis szervert használnak. Hálózatos

Részletesebben

LCD kezelési útmutató 4.1 verzióhoz

LCD kezelési útmutató 4.1 verzióhoz LCD kezelési útmutató 4.1 verzióhoz 1. Fıképernyı Az LCD modul egy 4 soros és soronként 20 karakteres képernyıvel rendelkezik. A számbillentyőzeten megtalálhatóak 0-9-ig a számok. A * és # gombok funkció

Részletesebben

Digitális írástudás kompetenciák: IT alpismeretek

Digitális írástudás kompetenciák: IT alpismeretek Digitális írástudás kompetenciák: IT alpismeretek PL-5107 A továbbképzés célja: A program az alapvető számítógépes fogalmakban való jártasságot és a számítógépek alkalmazási területeinek ismeretét nyújtja

Részletesebben

Object Orgy PROJEKTTERV 1 (9) Adattípusok menedzselése Palatinus Endre 2010-09-27 1.0

Object Orgy PROJEKTTERV 1 (9) Adattípusok menedzselése Palatinus Endre 2010-09-27 1.0 Object Orgy PROJEKTTERV 1 (9) Projektterv 1 Összefoglaló 2 Verziók Ez az projekt projektterve, ahol kitérünk a megrendelt szoftver elvárt szolgáltatásaira, és a tárgy keretein belül a projekt során felhasználandó

Részletesebben

Bevezetés az SAP világába. 5. Kommunikációs és integrációs technológiák

Bevezetés az SAP világába. 5. Kommunikációs és integrációs technológiák Bevezetés az SAP világába Zolnai László zolnai@elte.hu http://zolnai.web.elte.hu/bev_sap.html 5. Kommunikációs és integrációs technológiák 1 Rendszerek közötti kapcsolatok SAP és nem-sap rendszerek Vállalaton

Részletesebben

Programozás I. 5. Előadás: Függvények

Programozás I. 5. Előadás: Függvények Programozás I 5. Előadás: Függvények Függvény Egy alprogram Egy C program általában több kisméretű, könnyen értelmezhető függvényből áll Egy függvény megtalálható minden C programban: ez a main függvény

Részletesebben

1. elıadás. Információelmélet Információ technológia Információ menedzsment

1. elıadás. Információelmélet Információ technológia Információ menedzsment http://vigzoltan.hu 1. elıadás A számítógépes információ rendszerk tudománya, amely tartalmazza az alábbiakat: Elméleti összefüggések Szemlélet Módszertant a tervezéshez, fejlesztéshez üzemeltetéshez Tartalmazza

Részletesebben

Hibabehatárolási útmutató [ß]

Hibabehatárolási útmutató [ß] Hibabehatárolási útmutató [ß] Amennyiben a KábelNET szolgáltatás igénybevétele során bármilyen rendellenességet tapasztal kérjük, végezze el az alábbi ellenırzı lépéseket mielıtt a HelpDesk ügyfélszolgálatunkat

Részletesebben

Programozás C++ -ban 2007/7

Programozás C++ -ban 2007/7 Programozás C++ -ban 2007/7 1. Másoló konstruktor Az egyik legnehezebben érthető fogalom C++ -ban a másoló konstruktor, vagy angolul "copy-constructor". Ez a konstruktor fontos szerepet játszik az argumentum

Részletesebben

Kézikönyv. EDI beállítások (SetUp)

Kézikönyv. EDI beállítások (SetUp) Kézikönyv EDI beállítások (SetUp) Tartalomjegyzék Nincsenek tartalomjegyzék-bejegyzések. 2 1 Előfeltételek Az EDI (Electronic Data Interchange) és Automotive modulokkal való munka előfeltétele az EDI és

Részletesebben

Broadcast alkalmazás készítése

Broadcast alkalmazás készítése Broadcast alkalmazás készítése Feladatunk egy olyan alkalmazás készítése, amely a TelosB mote bekapcsolásakor broadcast-olva elküldi a mote saját belsı azonosítóját (jelen alkalmazás esetén ez a TOS_NODE_ID),

Részletesebben