Buradan - Emre Sururi Taşcı / Emre Sururi Tasci

Transkript

Buradan - Emre Sururi Taşcı / Emre Sururi Tasci
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri
Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu Kümede C++ Dilinde Yazılmış
Paralel Programları Yazıp Çalıştırma Rehberi
Emre Sururi Taşcı
ODTÜ Fizik Bölümü
Ankara, Aralık 2005 – Ocak 2006 – Nisan 2006
Belge Sürümü: 1.2
Belgenin en son sürümünü http://144.122.31.143/mpich2/ adresinden indirebilirsiniz.
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
1. Hızlı Giriş
Bu rehberden sadece kurulumlarla ilgili olan bölümleri okuyup uygulamanız, deneme
amaçlı olarak ilk örnek programı çalıştırmanız, kurulumun hemen ardından çalıştığını
denediğiniz sisteminizde faydalı bir işlem yapmak isterseniz de ikinci örnek programı
kullanmanız, rehberin amaçladığı hedefleri gerçekleştirmesine yetecek ve dahi
artacaktır (Eğer programlama ortamı olarak Visual Studio kullanmaktaysanız, “Visual
Studio 2005 kullanılarak MPICH2 destekli C++ kodunun yazımına hazırlık” kısmına da bir
göz atmanızı öneririm).
2
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
2. İçindekiler
1. Hızlı Giriş ............................................................................................................................... 2
2. İçindekiler............................................................................................................................... 3
3. Şekil Listesi ............................................................................................................................ 4
4. Rehber Çerçevesi.................................................................................................................... 5
5. Giriş........................................................................................................................................ 6
6. Paralel Programlama Hakkında.............................................................................................. 8
7. Paralel Programlamada Öneriler ............................................................................................ 9
8. MPICH2’nin Windows Makinelerde Kurulumu.................................................................. 11
9. MPICH2’nin Linux Makinelerde Kurulumu........................................................................ 16
10. Visual Studio 2005 kullanılarak MPICH2 destekli C++ kodunun yazımına hazırlık........ 17
11. Örnek Program 1: Paralel Programlama Yöntemi Kullanan Deneme Programı................ 25
12. Örnek Program 2: Paralel Programlama Vasıtasıyla İntegral Hesaplama ......................... 29
12.1 Yamuk Kuralı........................................................................................................... 29
12.2 Seri Program Çözümü .............................................................................................. 30
12.3 Paralel Program Çözümü ......................................................................................... 31
12.4 Paralel Programlamada Mesajlaşma Yöntemlerinden Bazıları................................ 32
12.4.1
MPI_Send() / MPI_Recv() ............................................................................... 33
12.4.2
MPI_Bcast() ..................................................................................................... 34
12.4.3
Mesajlarda Veri Gönderme Yöntemleri ........................................................... 34
12.4.3.1
count parametresinin kullanımı............................................................. 34
12.4.3.2
MPI_Type_struct() vasıtasıyla, bir yapı tanımlama ................................. 35
12.4.3.3
MPI_Pack()/MPI_Unpack() ile gönderim................................................ 37
12.5 Paralel Programlama yardımıyla İntegral Hesaplayan Program .............................. 38
13. Performans takibi ve Jumpshot programı ve 3. örnek program ......................................... 40
14. Emre Sururi Taşcı ve bilgisayarlar hakkında ..................................................................... 43
15. EK A: Paralel Programlamada Karşılaşabileceğiniz Terimler........................................... 44
16. EK B: Linux Makinelerde SAMBA sunucusu kurulumu ve kullanımı ............................. 47
17. EK C: Linux Makinelerde gcc derleyicisinin kurulumu ve kullanımı ............................... 47
18. EK D: Windows Makinelerde IPX/SPX/NetBIOS Kurallarının yüklenmesi .................... 47
19. EK E: smpd ve mpiexec ile kullanabileceğiniz örnek seçenekler.................................. 48
20. Kaynakça ve Tavsiye Edilen Kaynaklar: ........................................................................... 51
21. Windows için Visual Studio’ya alternatif derleyiciler:...................................................... 53
21.1 C ............................................................................................................................... 53
21.1.1
Bloodshed Dev-C++ (MingW / GCC) ............................................................. 53
21.2 C++........................................................................................................................... 54
21.3 Fortran / Fortran90 ................................................................................................... 54
22. Yapılacaklar: ...................................................................................................................... 55
23. Dizin ................................................................................................................................... 56
24. Dosya Ekleri ve Açıklamaları: ........................................................................................... 58
3
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
3. Şekil Listesi
Şekil 1: Allreduce komutunun temsili şeması.......................................................................... 10
Şekil 2: MPICH yüklenmesi sırasında şifre seçimi.................................................................. 12
Şekil 3: Ayar ekranının getirilmesi .......................................................................................... 12
Şekil 4: Kayıt bilgileri .............................................................................................................. 13
Şekil 5: MPICH2 ayarları......................................................................................................... 14
Şekil 6: wmpiexec kılıfı ........................................................................................................... 15
Şekil 7: Yeni bir proje oluşturun. ............................................................................................. 17
Şekil 8: Uygulamanın özellikleri.............................................................................................. 18
Şekil 9: Projeye C++ kaynak dosyası ekleyin.......................................................................... 19
Şekil 10: Projenin özelliklerini açın (ALT-F7) ........................................................................ 19
Şekil 11: Etkilenecek kurulumlar olarak tümünü belirleyin. ................................................... 20
Şekil 12: Tüm kurulumlarda kullanılacak 'INCLUDE' dosyalarının bulunduğu klasörlerin
yerini belirtin. ................................................................................................................... 20
Şekil 13: Tüm kurulumlarda kullanılacak LIBRARY dosyalarının bulunduğu klasörlerin
yerini belirtin. ................................................................................................................... 21
Şekil 14: 'Debug' kurulumu için standard compilation ve library ayarlarının belirtilmesi. ..... 22
Şekil 15: 'Release' kurulumu için standard compilation ve library ayarlarının belirtilmesi..... 23
Şekil 16: Kodun girilmesi ve kurulumun 'Release' olarak işaretlenmesi. ................................ 23
Şekil 17: mpi_code programının olası çıktısı........................................................................... 26
Şekil 18: Belirli integralin grafiksel tanımı.............................................................................. 29
Şekil 19: Belirli integralin değerine yakınsayan yamuklar. ..................................................... 29
Şekil 20: i. yamuğun değerleri. ................................................................................................ 30
Şekil 21: İşlem aralığının adım sayısına ve işlemci adedine göre ayarlanması. ...................... 31
Şekil 22: Jumpshot programının şekillendirdiği performans grafiği. ...................................... 42
Şekil 23: IPX Kurallarının kontrolü. ........................................................................................ 47
Şekil 24: Dev-C++'da proje oluşturulması ............................................................................... 53
Şekil 25: Ornek 3'un C kodu .................................................................................................... 53
Şekil 26: Proje özelliklerinde ek parametre belirtilmesi. ......................................................... 54
4
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
4. Rehber Çerçevesi
Bu rehberde Windows, Linux ve “Windows veya Linux” işletim sistemleri yüklü
bilgisayarlardan oluşan bir kümenin nasıl kurulabileceği ve bu küme üzerinde paralel
programların çalıştırılabilmesi için neler yapılması gerektiğinin anlatılması hedeflenmektedir.
Rehberin yazarının kendisi, bu işlere yeni başlamış biri olarak, kurulumda karşılaştığı yanlış
yönelimlerden, hatalardan ve diğer sıkıntılardan ayıklanmış bir şekilde –bilgileri de tazeyken–
mümkün mertebe kurulumu gerçekleştirmeyi tarif etmektedir. Giriş kısmı epey gereksizdir –
burada kendisinin kümeyi oluştururken nelerle karşılaştığını tarif eder ki, zaten bu rehberin
amacı bir başkasının bu sıkıntılarla karşılaşmamasıdır, o yüzden gönül rahatlığıyla atlanabilir;
“Paralel Programlama Hakkında” kısmı da amacını fersah fersah aşan bir bölüm olmuştur: bu
bölümü okuyacak olursanız eğer, o satırların yazarının da bu işe yeni başladığını, bu yüzden
bu konudaki bilgisinin de kıt olduğunu lütfen aklınızdan çıkarmayın – keza, “Paralel
Programlamada Öneriler” başlıklı bölümde de size tavsiyelerde bulunan zatın –bu tavsiyeleri
çeşitli kaynaklardan derlediğini göz önünde bulundursak bile– aslında konuya –bilgisayar
oyunculuğu diliyle söylersek– Noob (ya da Newbie) olması ve bunu itiraf etmesi,
söylediklerini kendisinin de en sinir olduğu “ahkâm kesme” olarak görmemeniz için tek
dileğidir. Tekrarlamak gerekirse: Bu rehberden sadece kurulumlarla ilgili olan bölümleri
okuyup uygulamanız, deneme amaçlı olarak ilk örnek programı çalıştırmanız,
kurulumun hemen ardından çalıştığını denediğiniz sisteminizde faydalı bir işlem
yapmak isterseniz de ikinci örnek programı kullanmanız, rehberin amaçladığı hedefleri
gerçekleştirmesine yetecek ve dahi artacaktır (Eğer programlama ortamı olarak Visual
Studio kullanmaktaysanız, “Visual Studio 2005 kullanılarak MPICH2 destekli C++
kodunun yazımına hazırlık” kısmına da bir göz atmanızı öneririm). En son kısım olan
“Emre Sururi Taşcı ve Bilgisayarlar Hakkında” ise olur da, yazarı merak ederseniz diye
konulmuştur; hiçbir önem teşkil etmemektedir. Ek olarak bulacağınız “Paralel
Programlamada Karşılaşabileceğiniz Terimler”de sıralanan terimlerin büyük bir ihtimalle
çoğunu biliyorsunuzdur ama yine de, derli toplu gözünüzün önünde dursun diye konulmuştur.
Diğer eklerde de yardımcı olarak kullanabileceğiniz çeşitli sunucuların ve protokollerin nasıl
yüklenebileceği yer almaktadır.
Metinde –şüphesiz olarak– bulacağınız yanlışları ve önerilerinizi [email protected]
e-posta adresime bildirirseniz müteşekkir kalırım (konu kısmına “MPICH2 Rehberi” diye
yazarsanız, postanızı kazara SPAM-filtreme takılmaktan kati suretle kurtarabilirsiniz).
Rehberdekileri uygularken bir sorunla karşılaşırsanız, yine bana bildirebilirsiniz: böylelikle
sorununuzun çözümünü araştırıp, yeni bir şeyler öğrenebilirim. 8)
Bu rehberi hazırlamamda en büyük payı olan, beni moleküler benzetim (simülasyon)
konusuna yönlendirip, “çocukluğumun kahramanı” bilgisayarları daha da yoğun ve etkin bir
şekilde kullanabilmemi sağlayan değerli hocam Prof. Dr. Şakir Erkoç’a teşekkür ederim.
Saygılarımla,
Emre Sururi Taşcı,
ODTÜ Fizik Bölümü
Ankara, Aralık 2005 – Ocak 2006 – Nisan 2006.
5
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
5. Giriş
Doktora konumun gereği olarak, sık sık moleküler dinamik simülasyonu programları
çalıştırmaktayım. Tek bilgisayar üzerinde çalıştırdığımız programlarımız, incelediğimiz
yapının karmaşıklığına bağlı olarak bazen bir haftanın üzerinde hesap yapmak zorunda
kalabiliyor. Hesap laboratuarımızdaki bilgisayarların işletim sistemi olarak bir kısmında
Windows, bir kısmında ise Linux sistemleri yüklü. Bir süredir programlarımızı paralel
çalışabilecek şekilde ayarlamaya çalışıyorduk ve bu yönde birkaç denememiz de oldu fakat
Linux’tan kelimenin tam anlamıyla hiçbir şey anlamayan biri olarak bu geçiş konusuna pek
faydam dokunmuyordu. Birkaç hafta önce yapılan ve benim de dinleyici olarak katıldığım
toplantılardan birinde bu paralel işlem meselesi konuşuldu, konunun geleceğinden bahsedildi.
Sanırım toplantıda pasif biri olmak zorunda kalmam beni hırslandırdı ve hemen toplantının
akşamında kendimce bir paralel işlem için kullanılabilecek bir protokol algoritması yazdım.
Biraz da cahil cesareti ile giriştiğim bu eylemin uygulanabilirliğini sağlamak amacıyla sisteme
paralel işlemleri çalıştırabilecek programları yüklemem elzem oldu. Doğrusunu söylemek
gerekirse, kullandığım derleyici olan Visual Studio 2005 .NET, OpenMP desteği sağlıyordu
ama ya onlar koymamışlar, ya ben bulamadım, onların OpenMP’si tek makinede çoklu
işlemcileri hedefliyordu. Kaldı ki, eğer durum böyle değilse bile, artık çok geçti.. 8)
Bu süreçte yararlandığım kitaplardan bende oluşan izlenimleri özetlemek gerekirse:
• Etkin olarak kullanılan iki arabirim PVM ve MPI idi.
• PVM kullanıcıya kolaylık sağlasa da, MPI’ın ağırlığı her geçen gün daha da artıyordu.
• MPI için geliştirilen uygulamalar (implementations) arasında da iki tanesi göze
çarpıyordu: LAM ve MPICH.
Tercihimi MPI’dan yana kullandım (tasarladığım protokol algoritması bu aşamada
globallik, uygulanabilirlik ve güvenlik açısından çoktan rafa kalkmıştı). MPICH’in 2. sürümü
çıkmıştı ve çok övgü alıyordu, ayrıca kolaylıkla Windows sistemlere kuruluyordu.
Heyecanla MPICH2’yi indirip makineme kurdum (bu rehberdeki 7. bölüm).
Kurduktan kısa bir süre sonra, benim için paralel işlemin “Hello World”ü olan şu basit
komutu çalıştırabiliyordum:
mpiexec –hosts 2 192.168.0.1 192.168.0.42 hostname
Dünyalar benim olmuştu! Tabii, bilgisayarlarla uğraşan biri için asla tatmin diye bir
şey söz konusu olamaz. Önce basit bir program yazdım C++ ile. Sistemimde Cygwin yüklü
ama zamanında sırf xfig çalışsın diye kurduğumdan, gcc ve diğer derleyicileri koymamışım.
Zaten Windowsçu, yani biraz tembel bir kullanıcı olduğumdan ötürü dert etmedim: Visual
Studio bana tam aradığım özellikleri (başlıca olarak kelime tamamlama ve nesneye bağlı
özelliklerle metodları otomatik olarak seçimime sunması) sunuyordu. Sonuçta çalışması
gereken, dünyanın en basit programını yazdım. Her bir düğüm, kendi derecesini yazdırıyordu.
Programı derledim – ve çalışmadı!
Sebep: bütün o library’ler, bağımlılıklar, vesaire vesaire idi. MPICH2’nin kılavuz
dosyalarında açıklamalar vardı ama sanki biraz bölük pörçüktü. Neyse ki, önce MPICH2 ile
gelen örneklerden birini derleyip çalıştırdım, o çalışınca da, içindeki kodu boşaltıp kendi
kodumu yazdım, bu sefer çalıştı. Sonrasında detaylı bilgiyi MPICH’in ilk sürümünün
kılavuzunda buldum ve Visual Studio 2005’i göz önünde bulundurarak bir özet çıkarttım (bu
rehberdeki 10. bölüm).
6
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Yazdığım deneme programları artık bütün Windows makinelerde çalışıyordu, hayat
toz pembeydi: yani, artık bir sonraki aşamaya geçmenin zamanı gelmişti. Bu ‘virüsü’ Linux
makinelere nasıl bulaştırabilirdim – dahası, bu ‘virüsü’ Linux makinelere bulaştırabilir
miydim?..
Bir programcının düsturu %99 doğrulukla ‘Önce vur, soruları sonra sorarsın’
cümlesiyle özetlenebilir ama bir kere işi düzgün yapmaya karar vermiştim. Önce MPICH2’yi
geliştiren Argonne Ulusal Laboratuvarları Grubu’na bir e-posta yazdım: “Windows ve Linux
makineler bir arada çalıştırılabilir mi?” içerikli. Sonra, geliştirici etiğine uyup, e-postayı
göndermeden önce ayıp olmasın diye MPICH’in forumlarını taradım. Herkes nasıl da Linux
makinelerle Sun sistemlerini çalıştırdığından bahsediyordu; yine de birkaç mesajda Linux ve
Windows sistemlerin kardeşçe bir arada çalışabileceklerinin ipucunu yakaladım (bu bölüme
sonradan düştüğüm not: MPICH2’nin kullanım kılavuzunda SMPD ile ilgili bölümde zaten
söylüyorlarmış – daha dikkatli okumak lazım). O gün, Linux’dan anlayan arkadaşım O. Barış
Malcıoğlu izinliydi ve bu sayede gene cahil cesaretimle Linux bilgisayarlara giriştim. Bu sefer
MPICH2’nin kılavuzu epey bir bilgi veriyordu (Dummy’s guide to the installation of
MPICH2 on Linux şeklinde de özetlenebilir aslında) ve mucizevi bir şekilde Linux’la bütün
alışverişi “ls, ls –a, ls –l, top” olarak özetlenebilecek bir şahıs (bendeniz) sisteme MPICH2’yi
kurabildi (kurulum dökümanından çevirip aktardığım yükleme talimatlarını 9. bölümde
bulabilirsiniz). Zaten bu üstün(!) başarımdan aldığım cesaretle bu rehberi yazmaktayım: Eğer
ben bile Windows ve Linux’lardan oluşan bir küme (cluster) kurabiliyorsam, sizler
haydi haydi kurabilirsiniz.
Benim için mutlu son, yine de hemen o gün gelmedi. Doğrusu o günün akşamında
bütün bilgisayarlarda ‘hostname’ komutunu çalıştırabiliyordum ama, MPI_Send() komutu ile
bir bilgi gönderdiğim vakit, eğer sistem karma ise program takılıp kalıyor, ancak kümem saf
Windows ise veya bir tek Linux bilgisayar üzerinde çoklu düğümden ibaretse çalışıyordu.
Ertesi gün, Barış’ın da yardımıyla, sizin de muhtemelen tahmin ettiğiniz gibi, bu sorunun
Linux’taki firewall ayarlarından kaynaklandığını bulacaktık.
7
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
6. Paralel Programlama Hakkında
Bundan yıllar önce, “paralel programlama” terimini ilk defa duyduğumda, bunun benim işime
nasıl yarayacağını düşünmüş ve -itiraf etmek gerekirse- kendimi bembeyaz bir sayfaya bakar
bulmuştum. Başlangıç olarak elimde hiçbir tanım ya da yöntem yoktu. Kendimi örnek alarak
söylemek isterim ki, paralel programlamanın işinize yaramayacağını düşünüyorsanız, büyük
bir ihtimalle yanılıyorsunuz (işlerinizde kullanmak için bilgisayar programı yazdığınızı ve
akademik sektörde çalıştığınızı varsayarak). O zamanlar bu konuda kendisine danıştığım bir
arkadaşımın bana önerdiği uygulama örneği, herhalde konuyla hiç bilgisi olmayan o zamanki
ben gibi kişilere epey aydınlatıcı gelecektir:
1 ile 100 arasındaki bir sayıdan oluşan bir şifreyi tahmin etmek istiyorsunuz.
Elinizdeki bilgisayar saniyede 1 tahmin yapıp, deneyebiliyor. Bu durumda şifreyi
tahmin etmeniz 100 saniye kadar bir süre alabilir. Şimdi 100 tane bilgisayarınız
olduğunu düşünün. 1 saniye içinde şifreniz elinizde.
İyi güzel de, benim yaptığım işin şifre kırmakla bir ilgisi yok ki! Ben sabahtan akşama
yüzlerce atomdan oluşan sistemlerle uğraşıyorum. Ayrıca atomlarla yaptığım işlemlerin bir
sonraki aşamasına geçmek için bir önceki aşamanın durumunu kullanıyorum, yani bir
bilgisayar, diyelim ki 1. saniyedeki sistemi hesaplarken, diğeri 2. saniyedeki işlemi
hesaplayamaz.
Eğer yukarıdaki önermede size ters gelen bir şey varsa, doğru yoldasınız demektir.
Evet, paralel algoritmalar –en azından benim bildiğim kadarı ile- tekrarlı (recursive) işlemleri
halledememektedirler fakat, bizatihi olarak sistemin mevcut durumunu hesaplarken paralel
işlemlerden faydalanabilirsiniz. Örneğimizde, 1000 atomdan oluşan bir sistemi incelediğimizi
ve elimizin altında 100 tane birbirinin aynı (bu ‘birbirinin aynı’ olma durumunu ‘yük
dengeleme’ (load balancing) olarak adlandırılan, paralel işlemlerde hayli önemli bir problemi
göz ardı etmek için kullanmaktayım – bu problemin çözülmesine dair basit bir öneriyi 7.
bölümde bulabilirsiniz) bilgisayar olduğunu varsayalım. Basit olması için, iki atom arasındaki
etkileşimin de sadece aralarındaki mesafeye bağlı olduğunu varsayalım ve etkileşimlerin
toplanabilir olduğunu da (yani, 3 atomdan oluşan bir sistemdeki etkileşmenin, atomların
ikişerli olarak kendi aralarındaki etkileşimlerinin toplamına eşit olduğunu). Bu durumda,
atomların konumları ortak bir yerde tutulur, ve atomlar bilgisayarlara onar onar dağıtılır. Her
bilgisayar elindeki bu 10 atomun her birini alır ve ortak yerde tutulan atom konumlarını
kullanarak diğer atomlarla olan etkileşimlerini hesaplar. Sonuçta, 1 bilgisayarda yaptığımızda
beklememiz gereken zamanın kabaca 1/100’u kadar bir zamanda çözüm elimizdedir. Yeni
veriler işlenir ve bir sonraki aşamada da aynı yöntem kullanılır.
Atomlar ve etkileşimleri, yaptığınız işe en az şifre çözmek kadar uzak olabilir ama çok
büyük bir ihtimalle paralel programcılık hayatınızı –hem de epey– kolaylaştıracaktır. İlk
aklıma gelen: eğer işinizde matris işlemleri yapıyorsanız, paralel programcılık sizin içindir!
8
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
7. Paralel Programlamada Öneriler
•
•
•
•
•
MPI uygulamalarında Giriş/Çıkış için kullanılan prosedürler üzerinde mutabakata
varılmamıştır. Bu nedenle, veri giriş/çıkışını bir düğüm üzerinden yapmanız, olası
karmaşayı engelleyecektir.
Bir paralel programda, işlem süresi açısından en pahalıya patlayacak kısım
mesajlaşma kısmıdır. Esasen, gerek süper bilgisayarlarda olsun, gerekse ağ üzerine
yerleştirilmiş bilgisayarlarda, işin en önemli kısmı, “En çok veri en hızlı bir biçimde
nasıl iletilebilir?” sorusudur. Eğer elinizde 1000 atom ve 10 bilgisayar varsa, atomları
bilgisayarlara tek tek dağıtmayın, bloklar halinde dağıtın. MPI’ın mesaj göndermek
amacını taşıyan çeşitli komutları vardır (MPI_Send, MPI_Bcast, MPI_Pack/Unpack,
vs..). İşinizi spesifik bir komutla halledebiliyorsanız, genel bir komut kullanmaktan
kaçının. Örneğin aynı cins elemanlardan oluşan bir diziyi MPI_Send(...) komutuyla,
tampon (buffer) kullanarak hafızada artarda sıralanıyor oluşundan faydalanıp
göndermeniz, bu diziyi MPI_Pack(...) ile önce paketleyip, sonra gönderip akabinde
paketten çıkartmanızdan çok daha az trafik ve zaman alacaktır.
Yük dengeleme, işlemlerinizde düşünmeniz gereken en can alıcı unsurlardan biridir.
Diyelim ki dokuzu çok hızlı, biri ise yavaş bilgisayarlardan oluşan bir kümeniz var.
İşin başında, işlemek istediğiniz 1000 atomu bu bilgisayarlara eşit olarak dağıttınız.
Sonuçta, 9 hızlı bilgisayar 900 atomu işleyip bitirir fakat bir sonraki adıma geçmek
için 10. yavaş bilgisayarın elindeki atomları işlemesini bekler. Bu tür bir kösteğin
önüne geçmenin bir yolu, asıl işleme geçmeden önce benzer, fakat çok daha küçük
çapta bir sistemle bilgisayarlarınızı değerlendirmeye (benchmark) tabii tutmaktır. Bu
değerlendirmenin sonunda, her bir bilgisayardan alacağınız işlem zamanına bakarak,
nispeten adil bir yük dengelemesi yapabilirsiniz (spesifik olarak, iyi bir moleküler
dinamik değerlendirmesini http://www.ud.infn.it/~ercolessi/mdbnch.html adresinden
indirebilirsiniz). Başka bir örnek olarak: eğer sisteminize bir fonksiyonun x=0 ile
10E50 arasındaki integralini aldırmak istiyorsanız, öncelikle her bilgisayara
(fonksiyonun çok değişken olmadığını kabul ederek) x=0 ile 1 arasındaki integralini
aldırır, çıkan sonuca göre integral alınacak bölgeleri bilgisayarlara basit integraldeki
performansları doğrultusunda dağıtırsınız. Bunun yanı sıra, işlemler sırasında her bir
bilgisayarda bir performans günlüğü oluşturursanız, sonradan çalıştıracağınız olası bir
benzer işlem öncesinde, yaptığınız basit değerlendirme işleminden çok daha etkin
veriye sahip olursunuz.
Her zaman için sisteminizde oluşabilecek aksaklıkları göz önünde bulundurun ve
hazırlıklı olun. Bilgisayarlar her zaman için devre dışı kalabilir. Bir düğüm devre dışı
kaldığında, sisteminiz bu yokluğu telafi edebilmelidir.
Programınızın giriş/çıkışı düzgün ve anlaşılır bir biçimde olmalıdır. Kullanıcı
arayüzünü (user interface) yazarken, programınızın farklı platformlarda
çalıştırılabileceğini göz önünde bulundurun. Belki programınızı yazarken ana
düğümün Windows makine olacağını varsaydınız ve süslü bir grafiksel kullanıcı
arayüzü (GUI) yazdınız. Programınızın Windows’da çalışan kısmı, verilerini doğrudan
bu arayüzden alıp, Linux makinelere geçirdi ve her şey çok güzel çalışıyor – ama
sadece sizin için! Onun yerine, kodladığınız arayüz bu değerleri bir giriş dosyasına,
kolaylıkla okunabilir standart bir biçimde yazsaydı ve asıl program değerleri bu
dosyadan okuyabilseydi, kolaylıkla benzer arayüzler diğer platformlarda da
hazırlanabilirdi. Benzer bir uygulama çıktı prosedürü için de geçerlidir. Yazdığınız
program, hesapladığı verileri doğrudan arayüze göndermek yerine bir dosyaya yazsa
ve arayüz bu dosyayı okuyup kullanıcıya sunsa, hayat çok daha güzelleşir,
programınız çok daha fazla kişi tarafından kullanılabilirdi. XML formatı, bu ara
9
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
•
işlemler için oldukça uygun bir veri-paylaşım standardıdır ve uygulaması da hayli
kolaydır. Benzer amaçla (ve dahi doğrudan nesne transfeleri için) CORBA da
kullanabilse de, kullanımı XML kadar kolay değildir.
Eğer çok çok özel bir nedeniniz yoksa, düğümlerdeki verilerin bilgisini güncellerken
kendi metotlarınız yerine, mevcut ise MPI’ın metotlarını kullanın. Aşağıdaki şekil,
Allreduce komutunun eşdeğer diyagramını içerir: yalnızca bir satırlık bir Allreduce
demek yerine tek tek bütün veri gönderim ve alımını MPI_Send ve MPI_Receive ile
de yapabilirsiniz tabii ki, hatta çok çok optimize bir yaklaşımla, işlemcilerin arasındaki
kablo uzunluğunu da hesaba katıp, belki daha hızlı (ve tamamıyla sisteme bağımlı) bir
çözüme dahi kavuşabilirsiniz – ama değer mi? Benzer şekilde, bir veri transferinin
hem MPI_Send ve MPI_Receive ile (tabloda 1. Versiyon), hem de MPI_Bcast ile
(tabloda 2. Versiyon) yapılmasının kıyası aşağıdaki tabloda verilmiştir (Şema ve Tablo
için kaynak: Paralel Programming with MPI).
Şekil 1: Allreduce komutunun temsili şeması
Tablo 1: Yayın için geçen süreler (milisaniye cinsinden).
nCUBE2
İşlemler
2
8
32
•
•
Paragon
SP2
1. Versiyon
2. Versiyon
1. Versiyon
2. Versiyon
1. Versiyon
2. Versiyon
0.59
4.7
19.0
0.69
1.9
3.0
0.21
0.84
3.2
0.43
0.93
1.3
0.15
0.55
2.0
0.16
0.35
0.57
Programınızı çalıştırmadan önce, sisteminizdeki bilgisayarların özelliklerini göz
önünde bulundurun: iki işlemcili bir bilgisayara tek bir düğüm atamak, yalnızca bir
işlemcinin çalışmasına neden olacaktır.
Eğer akademik bir ortamdaysanız, mesai bitiminde kapatılan bilgisayarlardan
faydalanmanın yollarını arayın. Bilgisayar laboratuarlarındaki bilgisayarlar çoğunlukla
tek tip olup, hızlı ve bir ya da iki anahtar (switch) üzerinden en uygun şekilde
bağlıdırlar: bu da paralel programlarınız için yüksek verimli bir ortam manasına gelir.
10
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
8. MPICH2’nin Windows Makinelerde Kurulumu
(Brent S. Paul’un yazdığı alternatif kurulum talimatlarına (İngilizce) http://wwwunix.mcs.anl.gov/mpi/mpich/downloads/windows-mpich2-tips.doc
adresinden
erişebilirsiniz. O dökümanda ayrıca Fortran programlarını da nasıl çalıştırabileceğiniz
de yer almakta.)
Gerekenler:
• MPICH2’nin Windows için yükleme pakedi
(http://www-unix.mcs.anl.gov/mpi/mpich2/)
• Microsoft .NET Framework v.1.1
(http://www.microsoft.com/downloads/details.aspx?FamilyID=262d25e3-f589-48428157-034d1e7cf3a3&displaylang=en)
“Bunlar da olsa iyi olur”:
• Kodunuzu derleyebileceğiniz bir ortam (Ücretsiz olarak Cygwin üzerinde gcc; Visual
Studio; herhangi bir başka C++ derleyici) – yalnız, unutmayın ki, Cygwin üzerinde
derleyeceğiniz kodu diğer Windows makinelerde çalıştırabilmek için, o makinelere de
Cygwin yüklemeniz gerekir ki, bu da pek pratik bir çözüm olmaz. Borland C++
derleyicisini
ücretsiz
dağıtıma
açmıştı
(http://www.borland.com/products/downloads/download_cbuilder.html). Bir alternatif
de Mingw olabilir (hele de Bloodshed Dev-C++ ile birlikte yüklenmişse http://www.bloodshed.net/devcpp.html). Windows için bedava C++ derleyicileri için
http://www.thefreecountry.com/compilers/cpp.shtml adresine bir göz atınız. Eğer bu
derleyicilerle MPI kodunu düzgün çalıştırmayı başarabilirseniz, lütfen tarifini bana
yollayın ki, alternatif (ve ücretsiz) yolları buraya alabilelim, Visual Studio’nun
tahakkümünden de bir nebze kurtulalım. ;) [Güncelleme: Dev-C++ kullanarak
MPICH’in C kodunu derlemeyi becerdim ama ne kadar uğraştıysam da, MPICH’in
C++ kullanılan kısımlarını halledemedim. 21.1.1. bölümde açıklamaları bulabilirsiniz]
Kurulum:
• Kurulum dosyasını (örneğin: mpich2-1.0.3-1-win32-ia32.msi) çalıştırın. Adımları
ilerleyin.
• Sizden istendiği zaman tercih ettiğiniz kullanıcı şifrenizi girin (bu şifre, paralel
çalışacak diğer bilgisayarlarda da aynı olarak belirtilmelidir).
11
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 2: MPICH yüklenmesi sırasında şifre seçimi
•
•
Bundan sonraki aşamada, size programın yükleneceği yer sorulacaktır. Yüklenecek
yer olarak varsayılan yer olan “C:\Program Files\MPICH2” klasörünü seçmenizi
tavsiye ederim.
Program yüklendikten sonra, ‘Başlat’ menüsünden ‘MPICH2’ grubundan
‘wmpiconfig’ kısayolunu çalıştırın.
Şekil 3: Ayar ekranının getirilmesi
•
Ayar ekranı ilk açıldığı zaman sizden bir kullanıcı adı ve şifre girmenizi isteyecektir.
Bu bilgiler, diğer bilgisayarlara bağlanırken kullanılacağından, diğer bilgisayarlarda
da aynı kullanıcının aynı şifresi olması gerekmektedir. Bu ekranı Şekil 3’te de görülen
“wmpiregister” kısayolundan da getirebilir, ya da komut ekranından “mpiexec –
register” yazarak da kayıt programını çalıştırabilirsiniz.
12
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 4: Kayıt bilgileri
•
Ayar ekranından diğer bilgisayarların üzerinde yüklü olan MPICH dağıtımının
özelliklerini görebilir ve isterseniz ayarları değiştirebilirsiniz. Burada dikkat etmeniz
gereken nokta, sadece kullanıcı adı ve şifreleri sizinkiyle aynı olan bilgisayarlara
erişebileceğinizdir. Bir de, “Host” kısmına bilgisayar adı yerine doğrudan IP
numarasını yazmanızı tavsiye ederim.
13
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 5: MPICH2 ayarları
•
•
•
Eğer bu ayar programını kullanamadıysanız, sorun değil, burada yapabileceğiniz her
şeyi mpiexec ve smpd komutlarının parametreleri vasıtasıyla halledebilirsiniz
(parametreler hakkında daha fazla bilgiyi 19. bölümde bulabilirsiniz).
Kurulumla ilgili olarak gerekli olmayan ama işinizi kolaylaştıracak iki tavsiyem var:
Öncelikle, mpiexec.exe dosyasının bulunduğu klasörü (varsayılan olarak “C:\Program
Files\MPICH2\bin” klasörü) PATH sistem değişkenine (“Bilgisayarım->Özellikler>Gelişmiş->Ortam Değişkenleri->PATH”, ya da bir batch dosyasına “SET
PATH=%PATH%;C:\Progra~1\MPICH2\bin;”
satırı
ekleyip,
bu
dosyayı
“C:\WINDOWS\system32\cmd.exe /K” komutuna parametre olarak verip çalıştırın)
eklemeniz. Bir de, çalıştıracağınız MPI programlarını bulundurduğunuz klasörü kendi
adınıza paylaştırdığınız bir klasörde tutmanız.
Yükleminizi bir komut penceresinden (ya da Şekil 3’teki wmpiexec yardımıyla),
MPICH2\bin klasöründen
mpiexec –localonly –n 4 hostname
(veya Şekil 6 içinde görüldüğü gibi) çalıştırarak deneyebilirsiniz. Bilgisayarınızda
çalışıyorsa, diğer bilgisayarlarla da çalışmalıdır. Eğer birlikte çalışmazsa, sorun büyük
ihtimalle firewall ayarlarınızdan ya da o bilgisayarlarda kullanıcı adı / şifrenizin geçerli
olmamasından kaynaklanmaktadır.
14
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 6: wmpiexec kılıfı
15
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
9. MPICH2’nin Linux Makinelerde Kurulumu
(Bu bölüm, aşağı yukarı http://www-unix.mcs.anl.gov/mpi/mpich/downloads/mpich2doc-install.pdf
ve
http://www-unix.mcs.anl.gov/mpi/mpich/downloads/mpich2-docREADME.txt dökümanlarının çevirisidir)
Gerekenler:
• MPICH2’nin kaynak kodu (http://www-unix.mcs.anl.gov/mpi/mpich2/)
• C derleyicisi
• Python 2.2 ve sonrası
• Ayrıca kullanacağınız programlara göre, doğal olarak, C++ veya Fortran derleyicisi
“Bunlar da olsa iyi olur”:
• Samba ağ sunucusu
• gcc derleyicisi
Kurulum:
• Kaynak kodun olduğu tar dosyasını açıp, en üst klasöre gidin:
tar xfz mpich2.tar.gz
cd mpich2-1.0.3
sisteminizde yüklü tar z parametresini kabul etmiyorsa bunları yapın:
gunzip mpich2.tar.gz
tar xf mpich2.tar
cd mpich2-1.0.3
•
Kurulum klasörünü seçin (varsayılan: /usr/local/bin):
mkdir /home/you/mpich2-install
•
MPICH2’yi yüklenecek klasörün yerini belirterek ayarlayın:
./configure -prefix=/home/you/mpich2-install --with-pm=smpd --withpmi=smpd |& tee configure.log
(eğer bu komut çalışmazsa (sh ve türevleri için) “|&tee configure.log” yerine “2>1 | tee
configure.log” kullanın). “with” seçenekleri smpd’yi yükler. Sadece Linux makinelerden
oluşan bir kümede program çalıştıracaksanız, smpd yerine mpd’yi kullanabilirsiniz, bu
durumda “with” seçeneklerini yazmayın.
•
MPICH2’yi kurun:
make |& tee make.log
•
MPICH2 komutlarını yükleyin:
make install |& tee install.log
•
Kurulum klasörünün bin klasörünü path değerine ekleyin:
csh ve tcsh için:
bash ve sh için:
•
setenv PATH /home/you/mpich2-install/bin:$PATH
export PATH=/home/you/mpich2-install/bin:$PATH
Bu noktada, her şeyin düzgün olup olmadığını kontrol için:
which mpiexec
which mpirun
komutlarını girin. Tümü de kurulum klasörünün bin klasörüne işaret etmeliler.
16
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
10. Visual Studio 2005 kullanılarak MPICH2 destekli C++ kodunun
yazımına hazırlık
Aşağıda anlatılanlar, C++ kodu için gerekli olan ayarlamalardır. MPICH2 kullanan bir kodu
yazmaya başlamadan önce, programın çalıştırılacağı diğer bilgisayarlarda MPICH2’nin
desteklenmesi açısından ‘Microsoft .NET Framework 1.1’ ve eğer programınızda .NET
tanımlamalarından kullanmış iseniz ‘Microsoft .NET Framework 2.0’ın kurulu olmasına
dikkat ediniz. Eğer bu kurulumların gerekip gerekmediğinden emin değilseniz, ve
programınız bu çerçevelere ihtiyaç duyuyorsa, sizden zaten ilgili dosyaları yüklemeyi talep
edecektir.
Öncelikle yeni bir proje oluşturmayı seçip, ayarları aşağıdaki adımlar doğrultusunda
yapın. MPICH2’nin, varsayılan kurulum klasörü olan ‘C:\Program Files\MPICH2’de
bulunduğu kabul edilmiştir.
Şekil 7: Yeni bir proje oluşturun.
17
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 8: Uygulamanın özellikleri
18
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 9: Projeye C++ kaynak dosyası ekleyin.
Şekil 10: Projenin özelliklerini açın (ALT-F7)
19
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 11: Etkilenecek kurulumlar olarak tümünü belirleyin.
Şekil 12: Tüm kurulumlarda kullanılacak 'INCLUDE' dosyalarının bulunduğu klasörlerin yerini belirtin.
20
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 13: Tüm kurulumlarda kullanılacak LIBRARY dosyalarının bulunduğu klasörlerin yerini belirtin.
21
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 14: 'Debug' kurulumu için standard compilation ve library ayarlarının belirtilmesi.
22
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 15: 'Release' kurulumu için standard compilation ve library ayarlarının belirtilmesi.
Şekil 16: Kodun girilmesi ve kurulumun 'Release' olarak işaretlenmesi.
23
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 11’de bir kısmını gördüğünüz koda ve açıklamasına bu rehberin 11. bölümünde
ulaşabilirsiniz. Kodu ayrıca http://144.122.31.143/mpich2/mpi_code.cpp adresinden de
indirebilirsiniz.
24
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
11. Örnek Program 1: Paralel Programlama Yöntemi Kullanan Deneme
Programı
Bu kod, 3 aşamalı basit bir deneme kodudur. Kaynağını pdf dosyasının eklerinde
bulabileceğiniz gibi, son halini ve derlenmiş hallerini de http://144.122.31.143/mpich2/
adresinden indirebilirsiniz.
#include "mpi.h"
#include <iostream>
using namespace std;
//Emre Sururi Tasci tarafindan, MPICH2'nin sistemde dogru calisip calismadigini kontrol maksadi ile
//Aralik 2005 tarihinde yazilmistir.
//"include" kisminda "mpi.h" dosyasinin "iostream"den once cagrildigina dikkat edin.
//bu sekilde, #redefinition hatalarinin onune geciyoruz. mpi.h'in SEEK_SET, SEEK_CUR ve
//SEEK_END tanimlamalari stdio.h ve diger io library'leri ile cakismakta. Eger "mpi.h"i
//son library olarak tanimlamak isterseniz, tanimdan once
//#undef SEEK_SET
//#undef SEEK_CUR
//#undef SEEK_END
//komutlarini girmeniz gerekir.
int main(int argc, char **argv)
{
int numprocs,myid;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
char mesaj[100];
MPI::Init(argc,argv);
numprocs = MPI::COMM_WORLD.Get_size();
myid
= MPI::COMM_WORLD.Get_rank();
MPI::Get_processor_name(processor_name,namelen);
//1. Asama Baslangic
if(myid==0)
cout <<"\nToplam Islemci Adedi: "<<numprocs<<"\nOnce herkes kendi basina bildirimde bulunacak:\n"<<endl;
//herkes kendi basina calisiyor..
cout <<"\n"<<"Islemci #: "<<myid<<" | Bilgisayar Adi: "<<processor_name<<endl;
//1. Asama Bitis
//2. Asama Baslangic
//node'lar root'a bilgilerini gonderiyorlar, server yayinliyor..
if(myid!=0)
{
MPI::COMM_WORLD.Send(&myid,1,MPI_INT,0,1);
sprintf(mesaj,"%s",processor_name);
MPI::COMM_WORLD.Send(mesaj,strlen(mesaj),MPI_CHAR,0,2);
}
else
{
int rank=0;
char processor_adi[100]="";
alindi!\n"<<endl;
}
cout <<"\n\nSimdi diger bilgisayarlarin yaptigi yayinla gelen bilgiler:\n"<<endl;
for(int i=1;i<numprocs;i++)
{
sprintf(processor_adi,"
");
MPI::COMM_WORLD.Recv(&rank,1,MPI_FLOAT,i,1);
MPI::COMM_WORLD.Recv(processor_adi,100,MPI_CHAR,i,2);
cout<<"Bildirilen: Islemci numarasi "<<rank<<" olan "<<processor_adi<<" adli bilgisayardan mesaj
}
MPI::COMM_WORLD.Barrier();
//2. Asama Bitis
//3. Asama Baslangic
//Broadcast denemesi:
int dummy = myid;
if(myid!=0)
{
MPI::COMM_WORLD.Send(&dummy,1,MPI_INT,0,3);
}
else
{
int d_rank;
for(int i=1;i<numprocs;i++)
{
d_rank=0;
MPI::COMM_WORLD.Recv(&d_rank,1,MPI_INT,i,3);
cout<<"Bildirilen --> Islemci numarasi "<<i<<" olan bilgisayardan \""<<d_rank<<"\" mesaji
alindi!"<<endl;
}
dummy=292;
cout<<"\n--------------------\nBroadcast'te ilgili deger root tarafindan '292' olarak yayinlaniyor..\n-------------------"<<endl;
}
25
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
MPI::COMM_WORLD.Barrier();
MPI::COMM_WORLD.Bcast(&dummy,1,MPI_INT,0);
if(myid!=0)
{
MPI::COMM_WORLD.Send(&dummy,1,MPI_INT,0,4);
}
else
{
int d_rank;
for(int i=1;i<numprocs;i++)
{
d_rank=0;
MPI::COMM_WORLD.Recv(&d_rank,1,MPI_INT,i,4);
cout<<"Bildirilen --> Islemci numarasi "<<i<<" olan bilgisayardan \""<<d_rank<<"\" mesaji
alindi!"<<endl;
}
cout<<"\n--------------------\n"<<endl;
}
//3. Asama Bitis
MPI::Finalize();
}
return 0;
Programın olası çıktısı şu şekilde olacaktır:
Şekil 17: mpi_code programının olası çıktısı.
Komut satırına dikkat edilirse, 2 bilgisayar üzerinde, ikişer işlem yürütülmüştür. birinci
bilgisayar (lepitopi – 192.168.0.42) 0. ve 2. düğüm olarak, ikinci bilgisayar (EDA –
192.168.0.1) ise 1. ve 3. düğüm olarak atanmışlardır. Programın kontrolü ve çıkışı 0. düğüm
tarafından yapılmaktadır. EDA adlı bilgisayar, programı lepitopi’nin paylaştırdığı “apps”
klasöründen almıştır.
Program, basitçe, 1. aşamada her düğüme (node) kendi başına adlarını ve derecelerini (rank)
yazdırtıyor. I/O meselesi MPI’da bir karara varılmadığından, buradaki bildirim sıralaması
26
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
dağınık olacaktır. Bir tavsiye olarak, I/O işlemlerini program boyunca tek bir düğüme
atarsanız (yukarıdaki örnekte 0. derecedeki düğüm), olası pek çok karışıklığın önüne
geçebilirsiniz.
2. aşamada 0. düğüm dinlemeye geçerken, diğer düğümler derecelerini ve isimlerini bu
düğüme gönderiyorlar. Bütün düğümlerden bilgiler gelince de, 0. düğüm bu bilgileri ekrana
yazdırıyor.
3. aşamanın 1. kısmında dummy adlı bir değişkene her düğüm kendi derecesini atıyor ve bu
değeri 0. düğüme gönderiyor. 0. düğüm gelen bu değerleri ekrana yazdırıyor, sonrasında ise
‘Broadcast’ vasıtasıyla, tüm düğümlere kendi dummy değişkeninin değerini (292) gönderiyor.
Bu işlemden sonra diğer düğümler, yine dummy değişkeninin kendilerindeki değerini 0.
düğüme gönderiyorlar ve 0. düğüm bu değerleri basıyor.
Programı derleyip çalıştırdıktan sonra eğer 1. aşama başarıyla gerçeklenip, 2. aşamada
takılma yaşanırsa, büyük bir ihtimalle firewall ayarlarınızda sorun var demektir. Bu durumda,
emin olmak için öncelikle programı her bir bilgisayarda tek başına çalıştırın (mpiexec
seçenekleri ile ilgili bilgiyi 19. bölümde bulabilirsiniz):
mpiexec –localonly –n 4 mpi_code.exe
Eğer Linux işletim sistemli bilgisayarlar da mevcut ise, kodu onların sisteminde bir gcc
enveloper’ı olan mpicxx ile derleyebilirsiniz:
mpicxx mpi_code.cpp –o mpi_code
Eğer program başarılı bir şekilde tek tek bilgisayarlarda çalıştıysa, bu sefer sadece Windows
ve sadece Linux işletim sistemleri yüklü bilgisayarları bir arada çalıştırmayı deneyin:
Örnek olarak sistemimizde 4 bilgisayar olduğunu, bunların IP numaralarının
192.168.0.1 – 192.168.0.4 bloğunda olduğunu ve ilk iki bilgisayarda Windows, son iki
bilgisayarda da Linux kurulu olduğunu varsayalım. Öncelikle dikkat etmemiz gereken,
‘mpiexec’ komutunu çalıştırdığımızda, her bilgisayarın ilgili programa erişebilmesidir.
Bunu, ilgili programı bütün bilgisayarlara kaydetmekle sağlayabileceğimiz gibi, Linux
bilgisayarlarda Samba sunucusunun ve Windows makinelerinde de IPX/SPX/NetBIOS
protokolünün yüklü olduğunu düşünerek, programı (Linux’da ve Windows’da
derlenmiş sürümlerini) bir bilgisayardaki paylaştırılmış bir klasöre yükleyerek de
çalıştırabiliriz:
mpiexec –hosts 4 192.168.0.1 192.168.0.2 192.168.0.3
192.168.0.4 \\192.168.0.1\shared\mpi_code
bu noktada –arch parametresi ile program adının işletim sistemine göre seçtirilmesi
söz konusu olabilir. Genelde ben, Linux ve Windows makinelere ayrı ayrı iş
gönderiyorum:
mpiexec –hosts 2 192.168.0.1 192.168.0.2
\\192.168.0.1\shared\mpi_code.exe:-hosts 2 192.168.0.3
192.168.0.4 /home/sururi/mpi_code
27
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
bu tür bir komutta Windows makineler programı doğrudan ilk bilgisayarda ararken,
Linux makineler kendileri üzerindeki /home/sururi klasörüne bakacaklardır. Bu
sayede, dilerseniz, farklı makinelerde farklı programları da çalıştırabilirsiniz.
Bulduğum pratik çözüm, samba server’ı kullanarak Windows makinedeki paylaşım
klasörünü ‘smbmount’ komutu vasıtasıyla Linux makinelere yüklemek oldu (Samba
hakkında bilgi için 19. bölüme bakın). Ayrıca, yukarıdaki kodları denediyseniz fark
etmişsinizdir: mpiexec, Windows makinelere bağlanmak için şifre sormakta. Her
seferinde bu şifre meselesiyle uğraşmamak için devreye “–pwdfile” seçeneği
girmekte. Diyelim ki, 192.168.0.1 makinesinde şifresi “sifre1” olan bir “kullanici1”
kullanıcısı var. Bu durumda, bir dosya oluşturup ilk satırına kullanıcı adını ve ikinci
satırına da şifreyi yazarak, ‘mpiexec’ komutuyla birlikte kullanabilirsiniz. Benzer
şekilde, her seferinde IP numaralarını girmek zor geliyorsa, bir dosyaya IP
numaralarını her satıra bir adet gelecek şekilde yazıp “–machinefile” seçeneği ile
çağırabilirsiniz.
Örnek olarak dosyalar ve içerikleri şu şekilde olsun:
pwdf
kullanici1
sifre1
hosts-w
192.168.0.1
192.168.0.2
hosts-l
192.168.0.3
192.168.0.4
hosts-tum
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
Sadece Windows makinelerde program çalıştırmak için:
mpiexec
–machinefile
hosts-w
–pwdfile
\\192.168.0.1\shared\mpi_code
pwdf
–n
4
ya da tüm makinelerde program çalıştırmak için:
mpiexec –machinefile hosts-tum –pwdfile pwdf –n 4 –path
“\\192.168.0.1\shared;c:\progra~1\mpich2\apps;/home/sururi
” mpi_code
buradaki –path seçeneği, program için aranılacak yeri belirtir. Alternatif konumları ‘;’
işareti ile birbirlerinden ayırabilirsiniz.
28
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
12. Örnek Program
Hesaplama
2:
Paralel
Programlama
Vasıtasıyla
İntegral
Bu bölümde yer alan program, PPMPI kitabının 4. bölümünde incelenen örneğin neredeyse
aynısı olup, sadece C’den C++’a çevrilmiştir. Kitapta çok iyi açıklandığından ötürü, çoğu
yerde doğrudan çeviri yapmakla yetindim. Bir önceki bölümdeki programdan farklı olarak, bu
program vasıtasıyla bilimsel bir problemi, paralel programlamaya nasıl uyarlayabileceğimizi
ve bunu yaparken kullanabileceğimiz pratik yolları da ele alacağız.
12.1 Yamuk Kuralı
Pozitif tanımlı bir f(x) fonksiyonunun a ve b gibi (b>a) iki değer arasındaki integrali,
fonksiyonun grafiği ile x-ekseni arasında tanımlanan bölgenin toplam alanı olarak
tanımlanabilir (Şekil 18).
Şekil 18: Belirli integralin grafiksel tanımı.
Bu integrali sayısal olarak hesaplamak istersek, kullanabileceğimiz yaklaşımlardan biri de a
ile b değerleri arasını, kolaylık olsun diye, n eşit parçaya böldüğümüzü düşünmektir (Şekil
19).
Şekil 19: Belirli integralin değerine yakınsayan yamuklar.
Bu durumda, bu n parçadan her birinin taban uzunluğunu h olarak tanımlarsak:
h = (b − a ) / n
(12.1)
olacaktır. En soldaki yamuğun tabanı [a,a+h] arasında, benzer şekilde gidecek olursak, i.
yamuğun tabanı [a+(i-1)h, a+ih] aralığında olacaktır (i=1,..,n). Gösterimi sadeleştirmek
amacıyla, bundan böyle i=0,...,n olmak üzere a+ih değerini xi olarak gösterelim. Böylelikle, i.
yamuğun sol kenarı f(xi-1), sağ kenarı ise f(xi) olacaktır. Alanının ise:
29
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
1
h ⎡ f ( xi −1 ) + f ( xi ) ⎤⎦
2 ⎣
olduğu kolaylıkla hesaplanabilir (Şekil 20).
(12.2)
Şekil 20: i. yamuğun değerleri.
İntegralin değerine yakınsayan alan, bütün yamukların alanlarının toplamıdır:
1
1
1
h ⎡⎣ f ( x0 ) + f ( x1 ) ⎤⎦ + h ⎡⎣ f ( x1 ) + f ( x2 ) ⎤⎦ + ... + h ⎡⎣ f ( xn −1 ) + f ( xn ) ⎤⎦
2
2
2
h
= ⎡⎣ f ( x0 ) + 2 f ( x1 ) + 2 f ( x2 ) + ... + f ( xn ) ⎤⎦
2
= ⎡⎣ f ( x0 ) 2 + f ( xn ) 2 + f ( x1 ) + f ( x2 ) + ... + f ( xn −1 ) ⎤⎦ h.
(12.3)
12.2 Seri Program Çözümü
Bir fonksiyonun integralini bu metotla hesaplayan seri bir programı aşağıdaki şekilde
yazabiliriz: (kodu http://144.122.31.143/mpich2/ adresinden indirebilir, ya da pdf dosyasının
eklerinde bulabilirsiniz)
#include <stdio.h>
#include <iostream>
using namespace std;
long double f(double &x);
void main(void)
{
int n;
double a,b;
float l_a,l_b;
double x;
printf("a,b ve n degerlerini girin:\n");
scanf_s("%g %g %d",&l_a,&l_b,&n);
a=l_a;b=l_b;
double h = (b-a) / n;
double integral = 0;
integral = (f(a)+f(b))/2.0;
for(x=a+h;x<b;x+=h)
{
//printf("x=%f --> f(x)=%f --> integral = %f\n",x,f(x),integral*h);
integral += f(x);
}
integral *= h;
printf("a=%f | b=%f | n=%d | h=%f\n",a,b,n,h);
printf("integral = %f\n\n",integral);
}
long double f(double &x)
{
long double f = x*x;
return f;
}
30
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Program çalıştırıldığında, a, b ve n değerlerinin girilmesini istiyor. f(x) fonksiyonu ise
programın içine gömülü durumda. n değeri ne kadar büyük olursa, sonucun gerçek değere
yakınlığı da o kadar fazla olacaktır.
12.3 Paralel Program Çözümü
Bu problemi paralel programlamaya nasıl uyarlayabiliriz? İntegral işlemi, sınırları
doğrultusunda bölümlere ayrılabildiğinden, [a,b] aralığını işlemci sayısı kadar bölgeye
ayırabiliriz. Fakat böyle bir durumda hassasiyet derecemiz olan n değerini atlamış olacağız.
Şekil 21 üzerinde, [a,b] = [3,7], n = 10 durumunun, 4 adet işlemciye dağılımı gösterilmiştir.
İlk akla gelen dağılım, her işlemciye 1 değerindeki bir aralığı atamak olacaktır (Şekilde, üst
kısımda “base0” olarak gösterilen aralıklar).
Şekil 21: İşlem aralığının adım sayısına ve işlemci adedine göre ayarlanması.
Bu şekilde bir dağılımla, her işlemcinin hesaba katacağı değerler:
p0: [3,4) = 3; 3.4; 3.8 |p1: [4,5) = 4; 4.2; 4.6 |p2: [5,6) = 5; 5.4; 5.8 |p3: [6,7] = 6; 6.2; 6.6; 7
31
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
olacaktır. Burada uyumsuzluk nerededir? Aralık sayısı olarak bize n = 10 verilmişti. Bu
durumda adım aralığımızı
b−a
=h
(12.4)
n
olacak şekilde bir h değeriyle belirtelim. Verili değerler yerlerine konursa, örneğimizdeki
adım aralığımız 0.4 olarak bulunur. Yani dikkate alınacak değerler:
3; 3.4; 3.8; 4.2; 4.6; 5; 5.4; 5.8; 6.2; 6.6; 7
olmalıdır.
Benim birazdan açıklayacağım dağıtma yönteminden çok daha etkin ve pratik
yöntemlerin varlığı aşikârdır ama aceleyle ancak bu kadarını bulabildim. Yöntem şöyle
işliyor: öncelikle, ilk haliyle, yani base0’la (p: işlemci adedi olmak üzere, base0 = (b-a)/p)
kaç adet h adım aralığının kesiştiğini hesaplıyorum. Bu sayıya k dersek:
⎧
⎛ base ⎞
( base / h ) ∉ ]
⎪⎪( int ) ⎜ h ⎟ + 1;
⎝
⎠
k =⎨
(12.5)
base
⎪
; ( base / h ) ∈ ]
⎪⎩
h
olacaktır ( ] : Tamsayılar kümesi). Sıradaki yapılacak iş, k kadar h’ın oluşturduğu aralığı yeni
işlem aralığı olarak tanımlamak (base2). Örneğimizdeki bu yeni aralık, Şekil 21 üzerinde, en
altta belirtilmiştir. Yalnız, fark ettiyseniz, bu türde bir dağıtımla en son işlemciye diğer
işlemcilerden daha kısa bir aralık düşüyor – bu da bu yöntemin kara lekesi.
O halde programımız çalıştırıldığında, düğümlerden biri kullanıcıdan a, b ve n
değerlerini girmesini isteyecek, bu değerleri diğer işlemcilere gönderecek. Sonrasında, her bir
işlemci bu değerleri ve kendi derecesini kullanarak çalışma aralığını hesaplayacak,
fonksiyonun bu aralıktaki integralini alacak ve bu değeri baştaki işlemciye gönderecek.
Baştaki işlemci de, diğer işlemlerden gelen bu değerleri toplayıp integrali hesaplamış olacak.
Bu rehber, paralel programlamanın nasıl yapıldığını anlatmaktan ziyade, neye
benzediğini açıklamaya çalışmayı hedeflese de, bu noktada, bir ilk giriş mahiyetinde, birtakım
mesaj gönderme yöntemlerini tanıtmaya çalışacağım.
12.4 Paralel Programlamada Mesajlaşma Yöntemlerinden Bazıları
Örneğimizde, baştaki işlemin 1 kullanıcıdan aldığı a, b ve n değerlerini diğer
işlemcilere geçirdiğinden bahsetmiştik. Bu mesaj gönderme işlemini iki farklı yöntemle
yapacağız: MPI_Send()/Recv() ile MPI_Bcast(). Dahası birden çok veri gönderirken de
seçebileceğimiz yöntemler vardır: verileri tek tek gönderebileceğimiz gibi eğer bir dizideki
gibi sıralı iseler, topluca da gönderebiliriz. Onları struct yapısına benzer bir şekilde tanımlı
bir veritürüne işleyerek de gönderebiliriz, MPI_Pack()/Unpack() vasıtası ile, paketleyip de
gönderebiliriz. Açıklamalarda elimin altında resmi olarak C dili için spesifikasyonlar olduğu
için onları yazacağım – C++ için olanlar ise pek farklı değil, sadece bir MPI::Comm_World
1
Bu noktada, şunu belirtmeden geçemeyeceğim: bazen işlemci, bazen işlem, bazen düğüm diye –ve çoğu kez de
yanlış– kullandığım bu terim process’dir, kimi zaman da thread’i kast etmekteyim. “Çeviride kaybolan” diğer
şeyler için bkz. 15. Bölüm: EK A: Paralel Programlamada Karşılaşabileceğiniz Terimler.
32
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
nesnesine metod olarak geliyorlar, başlarındaki ‘MPI_’ takısı da düşüyor. Örnekte de C++
versiyonlarını bulabilirsiniz. [Güncelleme: C++ karşılıklarını mavi ile verdim. Doğrudan
MPI::COMM_WORLD’un metodu olarak da kullanabilirsiniz, bir Intercomm ya da
Intracomm nesnesi tanımlayıp, onun metodu olarak da. Örnekteki kullanımları Intracomm
nesnesi olarak tanımlanan ‘Dunya’ uzerindendir. C ile C++ metodlarının karşılık tablosuna ve
diğer bilgilere hayli kapsamlı bir biçimde Extensions to the Message-Passing Interface
dökümanının A (MPI-2) ve B (MPI-1) eklerinden ulaşabilirsiniz.]
12.4.1
MPI_Send() / MPI_Recv()
int MPI_Send(
void*
int
MPI_Datatype
int
int
MPI_Comm
message
count
datatype
dest
tag
comm
/*in*/,
/*in*/,
/*in*/,
/*in*/,
/*in*/,
/*in*/)
void MPI::Comm::Send(const void* message, int count, const MPI::Datatype& datatype, int
dest, int tag)
int MPI_Recv(
void*
int
MPI_Datatype
int
int
MPI_Comm
MPI_Status*
message
count
datatype
source
tag
comm
status
/*out*/,
/*in*/,
/*in*/,
/*in*/,
/*in*/,
/*in*/
/*out*/)
void MPI::Comm::Recv(void* message, int count, const MPI::Datatype& datatype, int
source, int tag)
void MPI::Comm::Recv(void* message, int count, const MPI::Datatype& datatype, int
source, int tag, MPI::Status& status)
Burada, message, gönderilmek istenen mesajın (genel anlamda buffer’ın) adresini; datatype,
göndermekte olduğumuz mesajın tipini; count, hafızada message kısmında belirttiğimiz
adresten itibaren kaç datatype boyundaki alanı göndereceğimizi; dest, mesajın gideceği
işlemin derecesini; source, mesajın alınacağı işlemin derecesini; tag, opsiyonel olarak
kullanabileceğimiz bilgi işaretini; comm, hedeflenen alıcının bulunduğu grubu; status ise
mesajın alınıp alınmadığına, alındıysa iletişimle ilgili diğer birtakım bilgileri içerir.
Bir işlemin gönderdiği bir mesajın, gönderilen işlemciye ulaşabilmesi için gönderi
komutunun içinde belirtilen dest değerinin gönderilen işlemcinin derecesi olması, alım
komutunun içinde belirtilen source değerinin ise gönderen işlemcinin derecesi olması gerekir.
İstenirse, bir alıcı, spesifik bir kaynak (gönderici) belirtmeden, source değeri olarak öntanımlı
MPI_ANY_SOURCE sabitini yazarak, bu şekilde kendisine mesaj gönderen herhangi bir
33
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
kaynaktan mesajı alabilir. Gönderilen mesajın başarılı bir şekilde alınabilmesi için tag ve
comm değerlerinin de gönderi ve alım komutlarında aynı değerde olmaları gerekir. tag değeri,
pratik açıdan oldukça kullanışlıdır – gönderilen veriyi etiketlemekte kullanılır. Bunu bir
örnekle açıklamak gerekirse: farz edelim ki, elimizde producer-consumer (üretici-tüketici)
türünde çalışan bir program var: Yani, A işlemi birtakım verileri üretip, B işlemine
gönderiyor. B işleminin ise gelen bu verilerin bir kısmını ekrana, bir kısmını yazıcıya, bir
kısmını da dosyaya yazdırması lazım. İşte tag parametresi bu gibi durumlarda hayat kurtarıcı
oluyor. A işlemi ekrana yazdırılması istenen verileri gönderirken, onların tag’ini diyelim ki 0,
yazıcı için olanları 1, dosyaya kaydedilecekleri ise 2 olarak gönderiyor. B işlemi de bu
değerlere göre istenen işlemleri yapıyor. Bir veriyi gönderirken, gönderi komutunda bir tag
değeri belirtilmesi zorunlu olsa da, alım komutunda MPI_ANY_TAG olarak belirtilmesi,
gönderilen mesajlar hangi tag’e sahip olurlarsa olsunlar alınmasını sağlar.
12.4.2
MPI_Bcast()
MPI_Bcast(
void*
int
MPI_Datatype
int
MPI_Comm
message
count
datatype
root
comm
/*in/out*/,
/*in */,
/*in */,
/*in */,
/*in */)
void MPI::Comm::Bcast(void* message, int count, const MPI::Datatype& datatype, int root)
MPI_Send() ve MPI_Recv(), spesifik olarak bir alıcımız olduğunda kullanışlıdır. Ama çoğu
zaman bir bilgiden bütün işlemlerin haberdar olmasını isteriz (örneğimizdeki a, b ve n
değerleri gibi). Bu çeşit durumlarda, MPI_Bcast() komutunu kullanarak, bir vericideki
değerin/mesajın bütün işlemlere gönderilmesini sağlarız. root parametresi, gönderilecek
verinin değerinin hangi işlemdeki değeri olacağını belirler. Bu parametre dışındaki diğer
parametreler MPI_Send() ve MPI_Recv() komutlarında tanımlandıkları gibidir. Bu komut bir
senkronizasyon noktasıdır; yani bütün işlemler bu komutu aynı anda çalıştırırlar (en azından
teorik olarak). Bu sebepten ötürü, bu komutu bir iletişim grubu içinde sadece birkaç işlemin
çalıştırmasını sağlayamazsınız. Dikkat ettiyseniz, MPI_Bcast() komutunda, bir önceki
bölümde çok övdüğümüz tag komutunun yer almadığını görürsünüz. Bunun sebebi PPMPI
kitabının 5.3’üncü bölümünde açıklanmışsa da, ben pek anlayamadım, o yüzden bu konuda
yardımcı olamayacağım.
12.4.3
Mesajlarda Veri Gönderme Yöntemleri
Verileri nasıl gönderebileceğimiz hakkında az çok bilgi sahibi olduğumuza göre, gönderilecek
verileri göndermeye nasıl hazırlayabileceğimizden bahsetmek isterim. Temelde, verileri
çeşitlerine ve gönderilme sıklığına bağlı olarak 3 yolu kullanabiliriz.
12.4.3.1
count parametresinin kullanımı
Gerek MPI_Send()/Recv(), gerekse MPI_Bcast() komutlarında gördüğümüz count
parametresini, birbiriyle aynı cins ve sıralı (contigious) veriyi göndermede kullanabiliriz. C
dili, bize bir dizi oluşturduğumuzda, dizi elemanlarının hafızada peşi sıra olarak tutulacağını
garanti ettiğinden, gönderi komutunda, bu dizinin başladığı adresi vererek, sonrasında da kaç
34
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
adet elemanlık bir bloğu göndereceğimizi bildirebiliriz. Diyelim ki 100 adet float tipinde
sayıyı tuttuğumuz bir dizimiz var:
float dizi[100];
Bu dizinin ilk 30 elemanını bir seferde göndermek istiyoruz. Bunun için yapmamız gereken
şey, MPI_Send() ya da MPI_Bcast() derken, message olarak dizinin temsil edildiği adresi
(dizi), dataype olarak dizinin elemanlarının cinsini (float -> MPI_FLOAT) ve son olarak
count olarak da başlangıçtan itibaren göndermek istediğimiz eleman sayısını (30) yazmaktır:
float dizi[100];
MPI_Status status;
int my_rank;
//(...)Buraya yapilacak diger isler yazilabilir..
if(my_rank == 0)
{
//(...) Buraya yapilacak diger isler yazilabilir..
MPI_Send(dizi,30,MPI_FLOAT,1,0,MPI_COMM_WORLD);
}
else if(my_rank == 1)
{
MPI_Recv(dizi,30,MPI_FLOAT,0,0,MPI_COMM_WORLD,&status);
}
Yukarıdaki kod, işleyiş hakkında fikir vermek amacıyla yazılmıştır, derlediğinizde –kolaylıkla
tahmin edeceğiniz üzere– çalışmayacaktır. MPI’ın başlatılması, my_rank değişkenine
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank) fonksiyonu vasıtasıyla değer
atanması vs.. gerekmektedir. Ayrıca dikkat edilmesi gereken bir başka nokta ise dizinin
if(my_rank == 0) bloğunda başlatılması (initialize) gerektiğidir – bu uyarı olası bir derleme
hatasının önüne geçmek için değildir, fakat bu bloğun dışında yer alırsa, bütün işlemler aynı
başlatma prosedürünü gerçekleyeceklerinden dolayı, sonrasında tekrar işleme göndermenin
bir anlamı kalmayacağı aşikardır. Benzer şekilde, eğer MPI_Send() komutu yerine
MPI_Bcast() komutunu kullanacak olsaydık, kodumuzun iskeleti bu sefer aşağıdakine benzer
bir halde olacaktı:
float dizi[100];
MPI_Status status;
int my_rank;
//(...)
if(my_rank == 0)
{
//(...)Burada diziyi baslatirsiniz..
}
MPI_Bcast(dizi,30,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Bcast() komutunun bloğun dışına alındığına dikkat edin.
12.4.3.2
MPI_Type_struct() vasıtasıyla, bir yapı tanımlama
Bu metotta, göndereceğimiz verilerin türlerini ve hafızada tutuldukları adresleri kullanarak
oluşturduğumuz yapıyı göndeririz. Farz edelim ki, göndermek istediğimiz verilerin ilk ikisi
double ve üçüncüsü de int olsun:
double a,b;
int n;
bu değişkenlerin tutulduğu adresler de &a, &b ve &c olacaktır. a’nın adresini kendimize
referans (0) alıp, diğer değişkenlerin adreslerini de a’ya olan uzaklıkları olarak kullanalım. Bu
bilgileri, yani
1. değişkenlerin cinsini
2. değişkenlerin relatif adreslerini
iki ayrı dizide tutalım. Bir üçüncü dizi de, ilgili değişkenin ardışıklarının da dikkate alınıp
alınmayacağıdır ki, bu özellik zaten yukarıda değindiğimiz count parametresidir. Şu halde:
35
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
MPI::Datatype Paket;//hazirlanacak paket yapisi
MPI::Datatype cinsler[3];//gonderilecek verilerin cinslerinin tutulacağı dizi
int paket_icerigi[3];//her bir yapidaki paketteki degisken adedinin tutulacağı dizi.
MPI::Aint adres_farki[3];//degiskenlerin birbirlerine gore adresleri (Aint <-> Address INT)
MPI::Aint adres_baslangic;//ilk degiskenin adresi
MPI::Aint adres_gecici;//gecici adresin tutuldugu degisken
paket_icerigi[0] = paket_icerigi[1] = paket_icerigi[2] = 1;
cinsler[0] = cinsler[1] = MPI::DOUBLE;
cinsler[2] = MPI::INT;
adres_farki[0] = 0;
MPI_Address(&a,&adres_baslangic);
MPI_Address(&b,&adres_gecici);
adres_farki[1] = adres_gecici - adres_baslangic;
MPI_Address(&n,&adres_gecici);
adres_farki[2] = adres_gecici - adres_baslangic;
Paket = Paket.Create_struct(3,paket_icerigi,adres_farki,cinsler);
Paket.Commit();
Programı çözümlersek: 0. ile 6. satırlarda değerlerimizi tanımlıyoruz. 4. ve 6. satırlarda,
adreslerin tutulacağı değişken tipini, MPI’a özgü Aint cinsi ile belirttik. Bu sayede, adres,
int sınırları dışına çıksa da, saklanabilecek. Bir değişkenin adresini MPI_Address() komutu
vasıtasıyla Aint cinsine çevirmekteyiz. Göndermekte olduğumuz verilerin hiçbiri dizi
olmadığından ötürü, paket_icerigi olarak belirttiğimiz, count parametrelerini taşıyan
dizinin üç elemanını da 1 olarak bildiriyoruz. Değişkenlerin cinslerini de cinsler dizisinde
belirttikten sonra, b’nin ve n’in adreslerinin a’nın adresine göre uzaklıklarını da
adres_farki dizisinde topluyoruz. Bu aşamadan sonra, nihayet Paket olarak
tanımladığımız pakedi mevcut değişkenleri içerecek şekilde bir yapı olarak hazırlayabiliriz
(23. satır). 24. satırdaki Commit()fonksiyonu, oluşturduğumuz paketi göndermeye hazırlar.
İlk bakışta bu ara işlem gereksiz gibi görünse de, yeni oluşturduğumuz yapının da bir MPI
datatype olmasından yola çıkarak, paketlerden oluşan bir paketi gönderebilme imkanımız
olduğunu ve böyle bir durumda, her bir paketi tek tek göndermeye hazırlamak yerine, sadece
hepsini içeren paketi gönderime hazırlamanın yeterli olduğunu belirtmek isterim. Bu sebepten
ötürü, hazırladığımız her bir yapı, ille de doğrudan gönderilmek zorunda değildir.
Gönderileceği zaman, ister Send(), ister ise Bcast() ile olsun, ilk değişkenin adresini ve
datatype olarak da paketin kendisini belirtmek yetecektir:
Dunya.Bcast(&a,1,Paket,0);//Dunya’nin tanimi:
MPI::Intracomm Dunya = MPI::COMM_WORLD;
int MPI_Type_struct(
int
count
/*in
int
block_lengths[] /*in
MPI_Aint
displacements[] /*in
MPI_Datatype typelist[]
/*in
MPI_Datatype* new_mpi_t
/*out
*/,
*/,
*/,
*/,
*/)
static MPI::Datatype MPI::Datatype::Create struct(int count, const int array of blocklengths[],
const MPI::Aint array of displacements[], const MPI::Datatype array of types[])
burada count, toplam paket adedini; block_lengths, her bir paketteki veri adedini;
displacements, paketlerin birbirlerine göre olan adreslerini; typelist, paketlerin cinslerini
içerir. Hazırlanan yapı, new_mpi_t ile bildirilmiş yapının içeriğine gönderilir. Bu komut, en
genel haldir. Daha spesifik olarak üç kardeşi daha vardır: MPI_Type_contigous() (Bir dizinin
ardışık elemanlarını paketler), MPI_Type_vector() (Bir dizinin ardışık olmayan fakat düzenli
36
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
aralıklarla sıralanmış elemanlarını paketler) ve MPI_Type_indexed() (Bir dizinin ardışık da,
düzenli aralıklarla sıralanmış da olmayan elemanlarını paketler).
12.4.3.3
MPI_Pack()/MPI_Unpack() ile gönderim
Bu türden gönderimler, genellikle nadir olarak gönderilmesi gereken veriler için kullanılır.
İşlem türü açısından bir önceki maddede gördüğümüz yapı oluşturmaya benzer ama bir
kereliğe mahsur olduğundan, hazırlanışında type_struct kadar uğraşmak gerekmez.
Öncelikle boş bir yer (buffer) ayalanır, bu yere değişkenler eklenir ve bir yer tutucu
vasıtasıyla, bu yerde ne kadar ilerlediğimiz kayıtta tutulur. Örneğin yer olarak 100 karakterlik
bir alan belirlemiş olalım: Bir karakter 1 bayt yer kapladığından, kendimize 100 baytlık bir
bölge açtık. Ardından bu yerin başına (yer tutucu 0’ı göstermekte) 1 adet double sayı
ekleyelim. double değişkenler 8 bayt yer tuttuğundan, yer tutucu şimdi 8’i göstermektedir.
Ardından bir double ve bir de int (2 bayt) ekleyelim. Yer tutucu önce 16’ya, ardından da
18’e gidecektir. Bu yeri (buffer’ı) gönderdikten sonra Unpack() metodu ile bu sefer
değişkenleri geri alırız.
int MPI_Pack(
void*
int
MPI_Datatype
void*
int
int*
MPI_Comm
pack_data
count
datatype
buffer
buffer_size
position
comm
/* in */,
/* in */,
/* in */,
/* out */,
/* in */,
/* in/out */,
/* in */)
void Datatype::Pack(const void* pack_data, int in_count, void *buffer, int buffer_size, int&
position, const Comm &comm)
int MPI_Unpack(
void*
int
int*
void*
int
MPI_Datatype
MPI_Comm
buffer
buffer_size
position
unpack_data
count
datatype
comm
/* in */,
/* in */,
/* in/out */,
/* out */,
/* in */,
/* in */,
/* in */)
void Datatype::Unpack(const void* buffer, int buffer_size, void *unpack_data, int count, int&
position, const Comm& comm)
Bu komutta, pack_data, paketlenecek blok veriyi; unpack_data, paketten çıkacak veriyi;
count, paketlenecek blok verideki veri sayısını; datatype paketlenecek verinin cinsini; buffer,
paketlemenin yapılacağı yeri; buffer_size, bu yerin genişliğini; position, yer tutucunun
adresini ve comm da, bu paketlemeden etkilenecek sistemi belirtir. Örneğimizden bakacak
olursak:
0
1
char buffer[100];
int konum;
37
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
2
3
4
5
6
7
8
9
10
11
12
13
konum=0;
MPI::DOUBLE.Pack(&a,1,buffer,100,konum,MPI_COMM_WORLD);
MPI::DOUBLE.Pack(&b,1,buffer,100,konum,Dunya);
MPI::INT.Pack(&n,1,buffer,100,konum,Dunya);
Dunya.Bcast(buffer,100,MPI::PACKED,0);
konum=0;
MPI::DOUBLE.Unpack(buffer,100,&a,1,konum,Dunya);
MPI::DOUBLE.Unpack(buffer,100,&b,1,konum,Dunya);
MPI::INT.Unpack(buffer,100,&n,1,konum,Dunya);
12.5 Paralel Programlama yardımıyla İntegral Hesaplayan Program
Bu programı (da) pdf dosyasının ekinde ve http://144.122.31.143/mpich2/ adresinde
bulabilirsiniz (mpi_paralel.cpp)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "mpi.h"
#include <iostream>
using namespace std;
double f(double x)
{
double f = x*x;
return f;
}
int main(int argc, char **argv)
{
//MPI ile ilgili degiskenler
int numprocs,myid;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
double zaman_baslangic, zaman_bitis;//kronometremiz.
//"goto" kullandigimizdan oturu, 2_2 secenegindeki nesneleri onceden tanimlamak gerekti.
MPI::Datatype Paket;//hazirlanacak paket yapisi
MPI::Datatype cinsler[3];//gonderilecek verilerin cinsleri
//Global degiskenler
int n;
double a, b; //Integral sinirlari
double x;
double h; // Birim taban uzunlugu
double integral=0;//kismi integraller
double toplam;//toplam integral
//Lokal degiskenler;
double l_a, l_b;
//MPI baslatiliyor, ilgili degisken degerleri ataniyor
MPI::Init(argc,argv);
MPI::Comm::Recv(
MPI::Intracomm Dunya = MPI::COMM_WORLD;
numprocs = Dunya.Get_size();
myid
= Dunya.Get_rank();
MPI::Get_processor_name(processor_name,namelen);
//ilk dugum, kullanicidan degerleri girmesini istiyor
if(myid==0)
{
printf("Lutfen a,b ve n degerlerini giriniz:\n");
scanf("%lf %lf %d",&a,&b,&n);
}
zaman_baslangic = MPI::Wtime();//kronometreyi baslatiyoruz..
//goto secenek_1;
//goto secenek_2_0;
//goto secenek_2_1;
//goto secenek_2_2;
goto secenek_2_3;
secenek_1:
//1. Secenek:
//a, b ve n degerleri Send ile tek tek yollanir,
//Recv ile alinir.
//5 dugum, maks: 1.651458
if(myid==0)
{
for(int i=1;i<numprocs;i++)
{
Dunya.Send(&a,1,MPI_DOUBLE,i,0);
Dunya.Send(&b,1,MPI_DOUBLE,i,0);
Dunya.Send(&n,1,MPI_INT,i,0);
}
}
else
{
Dunya.Recv(&a,1,MPI_DOUBLE,0,0);
Dunya.Recv(&b,1,MPI_DOUBLE,0,0);
Dunya.Recv(&n,1,MPI_INT,0,0);
}
goto isle;
38
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
secenek_2_0:
//2.0. Secenek:
//a, b ve n degerleri BCast ile tek tek yollanir
//5 dugum, maks: 0.912301
Dunya.Bcast(&a,1,MPI_DOUBLE,0);
Dunya.Bcast(&b,1,MPI_DOUBLE,0);
Dunya.Bcast(&n,1,MPI_INT,0);
goto isle;
secenek_2_1:
//2.1. Secenek:
//a ve b degerlerinin ayni cins olusundan faydalanilip,
//degerler ardisik hale getirilip gonderilir. (Barizdir ki,
//bu yontemi kullanmaya karar versek, isin basinda bu iki
//degeri bir dizide saklardik)
//5 dugum, maks: 0.581578
double degerler[2];
if(myid==0)
{
degerler[0] = a;
degerler[1] = b;
}
Dunya.Bcast(degerler,2,MPI_DOUBLE,0);
a = degerler[0];
b = degerler[1];
Dunya.Bcast(&n,1,MPI_INT,0);//n, tamsayi oldugundan,
//onu double olan degerler dizisine dahil etmiyoruz. Su andaki ozel
//durumda tabii ki int->double donusumuyle dahil edebilirdik ama genel
//cozumler icin boyle bir imkanimiz yoktur. O yuzden onu ayrica gonderdik.
goto isle;
secenek_2_2:
//2.2. Secenek:
//Bu secenekte, MPI_Type_Struct() komutu ile, gondermek
//istedigimiz 3 veriyi iceren bir yapi olusturuyoruz.
//5 dugum, maks: 2.663919
int paket_icerigi[3];//her bir yapidaki paketteki degisken adedi.
MPI::Aint adres_farki[3];//degiskenlerin birbirlerine gore adresleri (Aint <-> Address INT)
MPI::Aint adres_baslangic;//ilk degiskenin adresi
MPI::Aint adres_gecici;//gecici adresin tutuldugu degisken
paket_icerigi[0] = paket_icerigi[1] = paket_icerigi[2] = 1;
cinsler[0] = cinsler[1] = MPI::DOUBLE;
cinsler[2] = MPI::INT;
adres_farki[0] = 0;
MPI_Address(&a,&adres_baslangic);
MPI_Address(&b,&adres_gecici);
adres_farki[1] = adres_gecici - adres_baslangic;
MPI_Address(&n,&adres_gecici);
adres_farki[2] = adres_gecici - adres_baslangic;
Paket = Paket.Create_struct(3,paket_icerigi,adres_farki,cinsler);
Paket.Commit();
Dunya.Bcast(&a,1,Paket,0);
goto isle;
secenek_2_3:
//2.3. Secenek:
//Bu secenekte ise degiskenlerimizi paketleyip,
//gonderdikten sonra da paketi acmak suretiyle
//bildirmis oluyoruz. Bunu yaparken MPI_Pack()
//ve MPI_Unpack() komutlarindan faydalaniyoruz.
//5 dugum, maks: 2.453644
char buffer[100];
int konum;
konum=0;
MPI::DOUBLE.Pack(&a,1,buffer,100,konum,MPI_COMM_WORLD);
MPI::DOUBLE.Pack(&b,1,buffer,100,konum,Dunya);
MPI::INT.Pack(&n,1,buffer,100,konum,Dunya);
Dunya.Bcast(buffer,100,MPI::PACKED,0);
konum=0;
MPI::DOUBLE.Unpack(buffer,100,&a,1,konum,Dunya);
MPI::DOUBLE.Unpack(buffer,100,&b,1,konum,Dunya);
MPI::INT.Unpack(buffer,100,&n,1,konum,Dunya);
goto isle;
isle:
zaman_bitis = MPI::Wtime();
printf("myid:%d | degerler gelene kadar gecen sure: %lf\n",myid,zaman_bitis-zaman_baslangic);
//artik her islem sinir kosullarindan ve hassasiyetten
//haberdar olduguna gore, herkes kendi sinirlarini
//hesaplayip, integrali alabilir.
h = (b-a)/n;
double base0 = (b-a)/numprocs;
double k_d;
39
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
182
int k_i;
183
int k;
184
k_i = static_cast<int>((b-a)/(numprocs*h));
185
k_d = base0 / h;
186
if(k_i == k_d) k = k_i;
187
else k = k_i+1;
188
189
l_a = a + k*h*myid;
190
l_b = a + k*h*(myid+1);
191
192
if(myid == (numprocs-1)){ l_b = b;integral+=b;}
193
if(myid == 0)integral+=f(a);
194
195
//Asil isleme baslamadan once butun dugumleri
196
//"start cizgisi"nde tutalim:
197
Dunya.Barrier();
198
//kronometreyi sifirlayalim:
199
zaman_baslangic = MPI::Wtime();
200
201
202
for(x=l_a;x<l_b;x+=h)integral+=f(x);
203
204
integral *= h;
205
206
zaman_bitis = MPI::Wtime();
207
printf("%s -- myid: %d | a:%lf --> b:%lf ==> integral = %11.8lf\n | Hesap Zamani =
%lfsn\n",processor_name, myid, l_a, l_b,integral,zaman_bitis-zaman_baslangic);
208
209
//hesaplanan integralleri 0. dugumde toplayalim:
210
Dunya.Reduce(&integral,&toplam,1,MPI::DOUBLE,MPI_SUM,0);
211
212
if(myid==0)
printf ("\n\nToplam Sonuc:\na: %lf | b:%lf | Toplam Integral: %11.8lf\n",a,b,toplam);
213
214
215
MPI::Finalize();
216
return 0;
217
}
“Açıklama gereği duyarsam, referans olarak kullanırım” maksadı ile az evvel 217 satırı tek
tek elimle numaralandırdım (makro kullanmadan!) ve bu hamallığımın sonucunda, açıkçası,
açıklanmayı gerektiren pek bir şey ne yazık ki bulamadım 8) ... Programın çalışma prensibini
12.3. bölümde anlatmaya çalıştım. 45. ve 46. satırlarda 0. düğüm, kullanıcıdan a,b ve n
değerlerini girmesini istiyor. 49. satırdaki MPI::Wtime() fonksiyonuna 13. bölümde
değineceğim. 51. satırdan 55.ye kadar, bu a,b ve n değerlerinin hangi yoldan diğer düğümlere
iletileceği belirtiliyor.
[ 57, 78] satırları, 12.4.1. bölümde anlatılan Send/Recv metotlarını,
[ 81, 90] satırları, 12.4.2. bölümde anlatılan Bcast metodunu,
[ 92,114] satırları, 12.4.3.1. bölümde anlatılan count parametresini,
[116,146] satırları, 12.4.3.2. bölümde anlatılan Type_struct metodunu,
[148,171] satırları da, 12.4.3.3. bölümde anlatılan Pack/Unpack metotlarını
kullanarak bu verileri düğümlere gönderiyor. 210. satırda kullanılan Reduce metodu,
‘Paylaşımcı İletişim’ (Collective Communication) olarak sınıflandırılan grubun bir elemanı
olup, bütün düğümlerde yer alan bir değişkeni bir işlem altında, tek bir düğümde toplamaya
yarar. Bizim örneğimizde, her düğümde mevcut olan integral değişkeninin değerini, 0.
düğümde, toplama işlemi yaparak, toplam değişkenine yazar. Paylaşımcı İletişim
metotlarından başlıcaları Reduce, Allreduce, Gather, Scatter, Allgather ve Reduce_scatter
olup, ilk fırsatta bu kılavuzda tanımlarına ve açıklamalarına kavuşacaklardır. 197. satırda
çağrılan Barrier metodu da, Paylaşımcı İletişim metotlarına dahil olup, bütün düğümler bu
noktaya gelene kadar buraya ulaşmış diğer düğümlerin durmasını sağlar.
13. Performans takibi ve Jumpshot programı ve 3. örnek program
Çalıştırdığınız programın hangi düğümde ne kadar hızlı çalıştığını, dahası düğümler arası
mesajlaşmanın ne kadar zamana mâl olduğunu bilmek, uzun vadede hayat kurtarır. Böyle
iddialı bir girişten sonra, bu bölümde sizlere performans artırıcı çeşitli optimizasyon
algoritmaları ve öğütler sunacağım zannına kapıldıysanız, tamamıyla yanıldığınızı gönül
rahatlığıyla belirtmek isterim – ama tavsiye olarak da, ilk bakmanız gereken yerin Parallel
Programming with MPI kitabının 9-12. bölümleri olduğunu bildiririm. Yazdığınız kodun
nerede ne kadar takıldığının çetelesini MPI::Wtime() fonksiyonu vasıtasıyla kolaylıkla
tutabilirsiniz. Wtime, onu çağıran düğümün o sıradaki zamanını double cinsinden verir. Bir
40
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
işlemin başında (ki, bu işlem, işlemciyi çalıştıran bir işlem olduğu gibi, mesajlaşma işlemi de
olabilir) ve sonunda çalıştıracağınız iki Wtime() fonksiyonunun değerlerini birbirinden
çıkartıp, arada geçen süreyi kaydedebilirsiniz.
Bu şekilde ufak tefek sistem yoklamaları yapabilirsiniz, ama asıl sürpriz, MPICH ile birlikte
gelen Jumpshot (ya da Upshot) programıdır. Bu program, MPICH’in –log opsiyonuyla
meydana getirdiğiniz log dosyasını grafiksel olarak size sunar. Bir örnekle, demek
istediklerimin çok daha net anlaşılabileceğini düşünüyorum:
Örneğimizde yer alacak kod, basit bir işlemi yapsın : düğümler, 1’den belirlenen bir sayıya
kadar olan tam sayıları toplasın, sonrasında da birkaç mesaj göndersinler. Basitçe:
#include "mpi.h"
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
//MPI ile ilgili değişkenler
int numprocs, myid;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI::Init(argc,argv);
MPI::Intracomm Dunya = MPI::COMM_WORLD;
numprocs = Dunya.Get_size();
myid
= Dunya.Get_rank();
MPI::Get_processor_name(processor_name,namelen);
int toplam = 0;
int n;
char mesaj[20]="Merhaba Dunya!";
if(myid==0)scanf("%d",&n);
Dunya.Barrier();
Dunya.Bcast(&n,1,MPI::INT,0);
for(int x=0;x<=n;x++)toplam+=x;
if(myid!=0)
{
Dunya.Send(mesaj,20,MPI::CHAR,0,0);
}
else
{
for(int i=1;i<numprocs;i++)
{
Dunya.Recv(mesaj,20,MPI::CHAR,i,MPI::ANY_TAG);
printf("%d numarali dugumden gelen mesaj: %s\n",i,mesaj);
}
}
}
MPI::Finalize();
return 0;
(Programın kodunu http://144.122.31.143/mpich2/ adresinde veya pdf dosyasının ekleri
arasında bulabilirsiniz)
Bu programı derleyip, çalıştırın, ama mpiexec’in çalıştırma parametrelerine ek olarak “–log”
seçeneğini de ekleyin (mpiexec –log –hosts 4 192.168.0.1 192.168.0.2
192.168.0.3 192.168.0.4 ornek3.exe gibi). Program çalışıp, bittiği zaman,
klasöründe “slog2” uzantılı bir dosya bulacaksınız. Bu dosyayı Jumpshot / Upshot yardımıyla
açın (program slog2 dosyasını clog2 dosyasına çevirecektir). Aşağıdaki resimdekinin benzeri
bir ekranla karşılaşacaksınız:
41
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 22: Jumpshot programının şekillendirdiği performans grafiği.
Resim yeterince açıklayıcı olmuştur diye tahmin ediyorum: Bu şekilde, hangi düğümün hangi
işlemi hangi zamanda yaptığının detaylı bir raporu elinizin altında olacaktır.
42
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
14. Emre Sururi Taşcı ve bilgisayarlar hakkında
İlk bilgisayarı olan C64’e, 1984 yılında, ilkokul 3. sınıfa giderken kavuştu. POKE 64380,0 ve
POKE 64381,1 komutları ve BASIC yetersiz gelmeye başladığında açlığını bir müddet
Simon’s BASIC ile bastırdı. Datasette’inden ötürü asla GEOS’un tadına bakamadı.
Ortaokulda Amiga 500’e terfi ettiyse de, oyun macerası her şeye ağır bastı. AMOS’la
tanışması fakat akabinde soğuması da bu döneme rastlar. Üniversiteye geldiğinde BASIC’i
epey iyi, FORTRAN’ı ise “Merhaba – Merhaba” seviyesinde bilmekteydi (Bu arada, artık bir
486DX2-66 ile PC’lerin dünyasına da nihayetinde adım atmıştı). Lisans döneminde PHP ile
epey sıcak temaslarda bulundu, ufaktan ufaktan C++’la da göz süzdü. Yüksek lisansa
geldiğinde BASIC sadece CV’sinde “bildiği bilgisayar dilleri” kısmına yazdığı bir kelimeden
ibaretti. Kendisine ani bir baskında bulunup, başına silah dayayıp bir BASIC programı
yazmasını istediğinizde büyük bir ihtimalle gözyaşlarına boğulacaktır – yine de, içinde bir
yerlerde, ona biraz zaman tanınırsa yazamayacağı BASIC programı olmadığını söyleyen bir
çocuk mevcuttur. Yüksek lisans döneminde, hocasının vaktiyle yazmış olduğu
(punchcard’lardan beri bilgisayarlarla uğraşagelen bir hocası olduğu için ne kadar övünse
azdır!) FORTRAN programlarını düzenlerken anlık FORTRAN aydınlanmaları (satori)
yaşadıysa da, bugünlerde kişisel işlerini PHP (+MySQL) ile halledip, başkalarının da
kullanımına açık bir şeyler yazacağı zamanlar ise Visual C++ .NET ile haşır neşir olmaktadır
(Birkaç makale çıkardığı bir çalışmasıyla ilgili hocalarından yazdığı programla ilgili soru
geldiğinde cevaplamak için önce Apache sunucusunu başlatıp, ardından ise Internet
Explorer’ı açmasının dinleyiciler üzerinde yarattığı şaşkınlığın utancını ve sıkıntısını halen
bazı geceler rüyalarında tekrar tekrar yaşamaktadır 8). Hele de .NET’in getirdiği Çöp
Toplayıcı (Garbage Collector) özelliğinden beridir ve VS 2005’le amaçlanan ortak katman
(layer) ve framework’lerle bir gün yazdığı cicili bicili GUI’li kodlarının Linux’ta da
çalışacağı günlerin hayaliyle yaşamaktadır. Çok sıkıştığı iki seferde hiç bilmediği Perl ve
Tcl’de betik (script) yazdığı iddiaları doğrudur, kendi gözlerimle gördüm. Geçtiğimiz aylarda
“bir arkadaş” tavsiyesiyle adını “Monty Python’s Flying Circus”tan alıyor diye bu yaşından
sonra Python öğrenmeye kalkmış, ikinci gününde vazgeçmiştir (temel sebep: Python’da
yazdığınız bir programı zahmetsizce dağıtırsanız, Windows kullanıcılarının büyük çoğunluğu
sizin zahmetsizce açık kodunu gönderdiğiniz bu programı çalıştırana kadar sistemlerine Linux
kurmayı tercih eder). Linux’tan mümkün olduğunca uzak durur, Windows aşığıdır, bir gün
Bill Gates’in kendisine komisyon ödeyeceğine inanır (buna rağmen “Anti-trust” ve “Pirates of
Silicon Valley” favori filmleri arasındadır). İlla ki Linux yüklü bir bilgisayarla alışverişe
girmesi gerekecekse, bunu dolaylı olarak ODBC, OleDB, LDAP vesaire bir arabirimle
“uzaktan daha güzelsin” düsturu uyarınca yapar. Bu düstur uyarınca, bu aralar XML
öğrenmeye de başlamıştır. Kıyamet alametleri arasında sayılan “Sururi’nin bilgisayarına
Linux kurması”, kendisi de pek inanmasa da, yakın bir zamanda bilgisayarına ciddi ciddi
kurmayı düşündüğü Pardus ile (hava atmak gibi olmasın, arkadaşlar yazdı ;) gerçeklenecektir.
Çoktandır ihmal ettiği Epigraf adında bir edebiyat sitesi (http://epigraf.fisek.com.tr) ve büyük
bir hevesle yazdığı ve işin ilginci hayli de yoğun kullandığı bir blog sitesi
(http://144.122.31.143/blogs/sururi) vardır.
43
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
15. EK A: Paralel Programlamada Karşılaşabileceğiniz Terimler
Benchmark (Değerlendirme) : Bir sistemin kapasitesini ve işleme gücünü ölçmek için
yapılan, sonucu kıyas yapabilmek için kullanılan yazılım.
Beowulf Cluster (Beowulf Kümesi) : Farklı bilgisayarlardan meydana gelen, üzerinde açık
kaynak kodların çalıştırıldığı küme. Not: Bu tanım doğrultusunda, Windows
makineleri içeren kümeler Beowulf Kümesi olarak adlandırılamazlar.
Buffer (Arabellek) : İşleme sokulacak verilerin hafızada geçici olarak bekletildiği yer.
Cluster (Küme) : Birden fazla işlemciden, hafızadan ya da başka donanımdan kurulan, bu
donanımların birlikte çalıştıkları ortam.
Communications Overhead (İletişim Gideri) : İşlemciler arasında mesajlaşmakla geçen
süre, bu süre zarfında işlemciler hesap yapamadıklarından ötürü, algoritmanın
hızlanım değerini düşürür. Bunun önüne geçebilmek için arpa boyunun (grain size)
mümkün olduğunca büyük olmasına çalışılır.
CORBA [Common Object Request Broker Architecture] : WBS'in işlemleri nesnelere
atamasının ardından, bu nesneleri bilgisayara dağıtmakla yükümlü standart paket.
Efficiency (Verim) : Bir paralel algoritmanın hızlanmasının, algoritmayı çalıştıran işlemci
sayısına oranıdır. Örnek: Bir işi seri algoritma 8 saniyede, 5 bilgisayar üzerinde
çalışan paralel algoritma 2 saniyede yapıyorsa, paralel algoritmanın hızlanması 8/2=4
olur. Buradan da verim 4/5=0.8 olarak bulunur..
Garbage Collector (Çöp Toplayıcı) : Hafızaya atanmış değişkenlerden artık ihtiyaç
duyulmayanları kontrol edip onları hafızadan silen, bu sayede bellek sızıntısı gibi
programcılık hatalarının önüne geçilmesini sağlayan prosedür.
Grain Size (Arpa Boyu) : İletişimler arasındaki zamanda yapılan işin göreli miktarı. Örnek:
100 adet atom bilgisi 10 işlemci arasında işlenmek üzere dağıtılıyor. Eğer işlemciler
bir atomu işleyip, ana bilgisayara bağlanıp, elindeki işlenmiş atom verisini teslim edip,
yeni atom verisini tek tek alıyorlarsa, bu yaptıkları işin arpa boyu, işlemcilerin bir
seferde 10 atom verisini alıp işledikleri duruma göre 1/10 olacaktır.
Graphical User Interface (Grafiksel Kullanıcı Arayüzü) : Kullanıcının parametre ve
verileri çeşitli formlar aracılığıyla, rahat ve anlaşılır bir biçimde girebilmesini sağlayan
arayüz.
Implementation (Uygulama) : Bir algoritma ya da programın özünün korunarak farklı
platform ve benzer amaçlar için hazırlanması.
Layer (Katman) : Programcı tarafından yazılan kodun, çalıştırıldığı platforma özel işleyip
derleyiciye gönderen kademe.
Linear Speedup (Çizgisel Hızlanma) : Paralel programlamada ulaşılmaya çalışılan hedeftir.
Verimin %100 olması, yani her işlemcinin çalışma zamanının seri işlemcinin çalışma
zamanının işlemci sayısına oranına eşit olmasıdır. Eşit yük dengeleme sağlanabilse
bile, iletişimde ideal olunamayacağından ötürü teorik bir hedeftir.
Load Balancing (Yük Dengeleme) : Birbirlerinden farklı hızlarda çalışan işlemcilerden
kurulu bir kümedeki bilgisayarlara eşit miktarda iş yükü verildiği takdirde, bir sonraki
aşamaya geçmek için hızlı bilgisayarlar işlerini tamamladıktan sonra boş (idle)
duracaklar, yavaş bilgisayarın işlemlerini bitirmesini bekleyeceklerdir. Bu da
verimsizliğe yol açacağından, yük dengeleme bilgisayarların işlem gücü ve
mesajlaşma hızı göz önüne alınarak yapılmalıdır.
MICO [Mico Is Corba] : Parasız olarak dağıtılan bir CORBA uygulaması (implementation).
MPD : MPICH2'nin Linux makinelerde kullandığı işlem yöneticisi. Python dilinde
yazılmıştır.
MPI [Message Passing Interface] : Çeşitli işlemlerin birbirleriyle mesaj alışverişinde
bulunmak için kullandıkları arayüz.
44
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
MPICH [Message Passing Interface Chameleon] : MPI'ın SMPD desteği ile Windows
platformunda da çalışmasını sağlayan, MPI-1 ve MPI-2 sürümlerine desteği olan
uygulaması.
MPMD [Multiple Program Multiple Data] : İşlemcilerin farklı veriler üzerinde farklı işlemler
yaptıkları model. Örnek: Bilgisayarların bir kısmı birçok resimden siyah-beyaz
resimleri ayıklarken, diğerlerinin ayıklanan resimleri işlemesi.
Node (Düğüm) : Bir kümede işlem yapmak üzere atanan her bir birim.
POSIX [Portable Operating System Interface] : C++ için hazırlanmış, UNIX için standart
library.
PRAM [Parallel Random Access Machine] : Paylaşılan ortak bir hafıza bölgesindeki verileri
alıp işleyen işlemcilerin oluşturduğu model.
PRAM'da kullanılan 4 Temel Okuma-Yazma Algoritması: :
EREW [Exclusive Read Exclusive Write] : İki ya da daha çok işlemcinin aynı anda
hafızadaki aynı yeri okumasına da, buraya aynı anda yazmalarına da engel olan
model.
CREW [Concurrent Read Exclusive Write] : İki ya da daha çok işlemcinin aynı anda
hafızadaki aynı yeri okumasına izin verip, buraya aynı anda yazmalarına engel
olan model.
ERCW [Exclusive Read Concurrent Write] : İki ya da daha çok işlemcinin aynı anda
hafızadaki aynı yeri okumasını engelleyip, buraya aynı anda yazmalarına izin
veren model.
CRCW [Concurrent Read Concurrent Write] : İki ya da daha çok işlemcinin aynı
anda hafızadaki aynı yeri okumasına da, buraya aynı anda yazmalarına da izin
veren model.
Process (İşlem) : Bir programın çalışmakta olan durumu (instance).
PVM [Parallel Virtual Machine] : Öncelikli olarak, birbirlerinden farklı özelliklerdeki
(yazılım, donanım, ağ) bilgisayarları birleştiren yazılım pakedi.
Rank (Derece) : Kümedeki düğümleri tanımlamakta kullanılan benzersiz (unique) etiket.
Recursive (Tekrarlı) : Değeri, kendisinden önceki hesaplamanın değerine bağımlı olan
hesap.
Script (Betik) : Birçok komutu bir arada tutup çalıştıran basit programcık.
SMB [SAMBA] : Microsoft'un ağ sisteminin Linux sistemler için geliştirilen ücretsiz
uygulaması .
SMPD : MPICH2'nin Windows makinelerde kullandığı işlem yöneticisi. C dilinde
yazılmıştır. Windows ve Linux makinelerden oluşan bir kümede de kullanılabilir.
Speedup (Hızlanma) : Aynı işi yapan seri bir algoritmayla paralel algoritmanın çalışma
zamanlarının birbirlerine oranı. Örnek: Bir işi seri algoritma 8 saniyede, 5 bilgisayar
üzerinde çalışan paralel algoritma 2 saniyede yapıyorsa, paralel algoritmanın
hızlanması 8/2=4 olur.
SPMD [Single Program Multiple Data] : İşlemcilerin farklı veriler üzerinde aynı işlemleri
yaptıkları model. Örnek: birçok resmi aralarında dağıtıp, aynı şekilde işleyen
bilgisayarlar.
Switch (Anahtar) : Bilgisayarların birbirleriyle iletişim kurmalarını kolaylaştıran, onları ağda
yönlendiren, gönderdikleri paketleri gönderilen bilgisayarlara ulaştıran donanım.
Thread (İş Parçacığı) : Bileşenlerine ayrılan bir işin her bir bileşen kısmı.
4 Temel Thread Modeli: : .
Delegation (boss-worker) (Yetkilendirme (patron-işçi)) : Merkezi bir thread
(patron) diğer thread'leri oluşturarak onlara görevler atar.
45
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Peer-to-peer (Eşler arası) : Bütün thread'ler eşit statüye sahiptirler. Bir thread başka
bir thread'i oluşturabilir ama herhangi bir işlem atayamaz.
Pipeline (Boruhattı) : Veriyi farklı çeşitlerde işlemek için üretim-hattı modeli
uygulanır. Birinci kısımdaki thread'lerin işlediği veri, ikinci kısımdaki
thread'lere yollanır, onlar da bu veriyi işleyip üçüncü kısma geçirirler, vs..
Producer-consumer (Üretici-tüketici) : Üretici thread'in ürettiği veri, tüketici thread
tarafından kullanılır. Bu iki kısım thread'in arasında birinin doldurduğu,
diğerinin boşalttığı blok hafıza vardır. Örnek: Internette arama yapmak için
kullanılan gezgin ve bu gezginin aranan veriyi gönderdiği arama motoru.
UML [Unified Modeling Language] : WBS'nin çalışmasını şematik olarak göstermekte
faydalanılan modelleme dili. Paralel programcılıkta UML'nin 7 diyagramından
faydalanılabilir (Etkinlik, Etkileşim, Durum / Eşdeğer Durum, Dizi, Dayanışma,
Yerleştirme ve Bileşen diyagramları) .
User Interface (Kullanıcı Arayüzü) : Bir yazılımın, kullanacağı parametreleri ve işleyeceği
verileri kullanıcıdan alan birimi.
von Neumann Makinesi : Yapılacak işin yönergelerini ve işin uygulanacağı ve sonucunda
üretilecek verilerin tek bir saklama ünitesinde tutulduğu bilgisayar mimarisi.
WBS [Work Breakdown Structure] : Yapılacak işin bileşenlerine ayrılması ve bu bileşenlerin
görevlerine uygun yazılımın geliştirilip, işlem ve mesajlaşma hiyerarşisinin
tanımlandığı yapı.
46
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
16. EK B: Linux Makinelerde SAMBA sunucusu kurulumu ve kullanımı
17. EK C: Linux Makinelerde gcc derleyicisinin kurulumu ve kullanımı
18. EK D: Windows
yüklenmesi
Makinelerde
IPX/SPX/NetBIOS
Kurallarının
1. Denetim Masası’ndan “Ağ Bağlantıları” (XP) veya “Ağ” (98) menüsünü açın.
2. (XP) Yerel Ağ Bağlantısı’nın özelliklerini görüntüleyin.
3. Burada yüklü öğeleri kontrol edin (Şekil 23). Eğer “NWLink IPX/SPX/NetBios Uyumlu
Aktarma İletişim Kuralları” yüklü değilse, “Yükle...” seçeneğini seçin, “İletişim Kuralı”
kısmını çift tıklayın, buradan da ilgili kuralları seçip yükleyin.
Şekil 23: IPX Kurallarının kontrolü.
47
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
19. EK E: smpd ve mpiexec ile kullanabileceğiniz örnek seçenekler
smpd ile kullanabileceğiniz bazı seçenekler:
-phrase <şifre> : smpd iletişiminde kullanılan şifreyi belirler.
Örnek:
smpd –phrase yeni_sifre
-get phrase : smpd’nin kullanmakta olduğu şifreyi görüntüler.
-restart [sunucu adı] : belirtilen sunucuda smpd servisini tekrar başlatır.
-shutdown [sunucu adı] : belirtilen sunucuda smpd servisini kapatır.
-status [sunucu adı] : belirtilen sunucudaki smpd servisinin durumunu bildirir.
-hosts : varsayılan olarak kullanılan sunucuları gösterir.
-sethosts <sunucu1> <sunucu2> <...> : varsayılan olarak kullanılacak sunucu listesini atar.
eğer listesindeki sunucu adedinden çok işlem çağırılırsa, çevrimsel olarak davranır.
Örnek:
smpd –sethosts 192.168.0.1 192.168.0.2
olarak belirttiğiniz bir smpd servisini
mpiexec –n 3 program_adi
olarak çağırdığınızda, 192.168.0.1 sunucusu 0. ve 2. düğüm, 192.168.0.2 sunucusu ise
1.düğüm olarak çalışır.
-help : seçeneklerle ilgili yardımı görüntüler.
mpiexec ile kullanabileceğiniz bazı seçenekler:
-machinefile <dosya_adı> : işlemi yürütecek olan bilgisayarları belirttiğiniz dosyadan alıp
okur. İlgili dosyada her satıra bir sunucu adı / IP adresi yazılmalıdır.
-host <sunucu_adı> : program sadece belirtilen sunucuda çalıştırılır.
-hosts <sunucu_adedi> <sunucu1> <sunucu2> <...> : programı belirttiğiniz sunuculara
dağıtır. Aynı sunucuyu birden fazla kere kullanabilirsiniz. İş dağıtımı çevrimsel olarak yapılır.
Örnek:
mpiexec –hosts 3 192.168.0.1 192.168.0.1 192.168.0.2 hostname
-hosts <sunucu_adedi> <sunucu1> <sunucu1’e atanacak düğüm adedi> <sunucu2>
<sunucu2’ye atanacak düğüm adedi> <...> <...> : bu ikinci tür kullanımda, hangi sunucuya
kaç adet düğüm atanacağını elle bildirebilirsiniz.
Örnek:
mpiexec –hosts 2 192.168.0.1 2 192.168.0.2 1
-log : programın performansını bir log dosyasına kaydeder (slog2 formatında).
48
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
-localonly : programı sadece komutu girdiğiniz bilgisayarda çalıştırır.
-n <düğüm_adedi> : programı belirttiğiniz adet kadar düğümde çalıştırır. Düğümleri
-machinefile seçeneği kullanmışsanız o dosyada kullanılanlar arasında, -hosts ile
belirttiyseniz, o sunucular arasında, -localhost seçeneğini belirttiyseniz de, o sunucuda
paylaştırır. –n seçeneği, –hosts ve –localonly seçenekleri bir arada kullanılamaz.
-path <yol1;yol2;...> : her bilgisayar, çalıştıracakları komutu belirtilen yollarda ararlar.
Örnek:
mpiexec –hosts 2 192.168.0.1 192.168.0.2 –path “c:\mpich-apps;/home/sururi” mp
bu örnekte, bilgisayarlardan Linux olanı “mp” dosyasını –eğer varsa- /home/sururi/
klasöründe, Windows olanı ise c:\mpich-apps\ klasöründe arayacaktır. Bu aşamada, Windows
bilgisayarda bir klasörü paylaştırmanızı, Linux bilgisayarlardan da smbmount (samba
sunucusu hakkında detaylı bilgiyi 16. bölümde bulabilirsiniz) kullanarak bu klasörü
yüklemenizi tavsiye ederim. Örneğin 192.168.0.1 IP’li Windows bilgisayarındaki
“C:\Program Files\Mpich2\apps” klasörünü “apps” olarak paylaştıralım. Sonrasında ise Linux
bilgisayarlar üzerinde bu klasörü /apps dizinine yükleyelim. Bu sayede
–path “\\192.168.0.1\apps;/apps”
gibi sadece iki yol içeren bir path seçeneği ile bütün bilgisayarlar dosyaya erişebilirler.
Burada dikkat etmeniz gereken şey, açıklamaları yaparken Windows ortamında komutu girdiğinizi
kabul ediyor oluşumdur – bu sebepten, Linux bilgisayarlarda yolları girerken “\” yerine “/” veya “\\”
kullanmalısınız. Pratik olan, bütün dizin yollarının “/” ile belirtilmesidir – Windows iki türlü ayracı
da (“\” veya “/”) kullanmanıza izin vermektedir.
-pwdfile <şifre_dosyası> : Windows bilgisayarlara bağlanırken kullanılacak “kullanıcı adı”
ve “şifre” bilgilerini bir dosyada tutup, bu seçenek vasıtasıyla doğrudan dosyadan
okutabilirsiniz. Bu seçeneği kullanmazsanız, programı çalıştırdığınızda sizden sadece şifreniz
istenecek, Windows makinelere mevcut kullanıcı adınız ile girilmeye çalışılacaktır. Şifre
dosyasında ilk satıra kullanıcı adınız, ikinci satıra ise şifrenizi yazılır.
-help : seçeneklerle ilgili yardımı görüntüler.
mpiexec ile bilgisayarlarda farklı programlar çalıştırmak:
Programların dinleme ve konuşma zamanlamasını iyi ayarlayabildiyseniz, farklı programları
bilgisayarlarda çalıştırmak mümkündür. Bu tür bir uygulama daha çok ‘boruhattı’ (pipeline)
ve “üretici-tüketici” (producer-consumer) tarzı modellerle çalışmaya yöneliktir. Örnek olarak
elimizde üçü Windows, ikisi de Linux yüklü 5 bilgisayarımız olsun. IP numaraları da ilk üçü
Windows olmak üzere, 192.168.0.1 – 192.168.0.5 bloğunda alınmış olsun. Windows
makinelerinden birinde ve Linux makinlerinden birinde “uretici” programını derlemiş olalım.
Aynı koddan derlediğimiz programın Windows sürümüne “uretici_w.exe”, Linux sürümüne
de “uretici_l” adını vermiş olalım. Benzer şekilde, kalan 3 bilgisayarda da “tuketici”
programını derlemiş olup, ona da Windows sürümleri için “tuketici_w.exe”, Linux sürümü
için de “tuketici_l” adını vermiş olalım. Daha iyi anlayabilmek için bu programların yaptığı
işleri şöyle düşünebiliriz:
uretici : rastlantısal sayılar üretiyor.
tuketici : bu rastlantısal sayıları alıp, parametre olarak kullanıp fraktallar çiziyor.
49
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Böyle bir örnekte, uretici ile tuketici’nin doğrudan haberleşmeleri aslında gerekmez :
uretici’ler verilerini bir dosyaya yazar, tuketici’ler de bu dosyadan alıp işleyebilirler. Ama
uygulamalar çok farklı bir ihtiyaca da yönelik olabilirdi. O nedenle, aralarındaki dinlemekonuşma prosedürlerinin iyi ayarlandığını ve programların eşzamanlı olarak çalışmalarının
gerektiğini varsayalım. Bu durumda:
1. Bilgisayar (192.168.0.1) uretici_w.exe programını,
2. Bilgisayar (192.168.0.2) tuketici_w.exe programını,
3. Bilgisayar (192.168.0.3) tuketici_w.exe programını,
4. Bilgisayar (192.168.0.4) uretici_l programını,
5. Bilgisayar (192.168.0.5) tuketici_l programını
çalıştıracak. İşleri biraz daha karıştırmak için, 2., 4. ve 5. bilgisayarlarda çift işlemci olduğunu
da varsayalım. Kolaylık olsun diye, Windows bilgisayarlara erişmek için gereken kullanıcı
bilgilerinin 1. bilgisayarda paylaştırılan //192.168.0.1/mpi/conf/sifreler.txt dosyasında
tutulduğunu biliyor olalım. Dahası yukarıda bahsettiğimiz smbmount metodu ile
//192.168.0.1/mpi klasörü Linux bilgisayarlarında /mpi dizini olarak yüklenmiş ve bütün
programlar da (“uretici_w.exe”, “uretici_l”, “tuketici_w.exe”, “tuketici_l”) buraya konulmuş
olsun. Bu durumda, ihtiyacımız olan mpiexec komutu:
mpiexec –n 1 –host 192.168.0.1 //192.168.0.1/mpi/uretici_w.exe : -n 2 –host 192.168.0.4
/mpi/uretici_l : –hosts 2 192.168.0.2 2 192.168.0.3 1 –pwdfile
//192.168.0.1/mpi/conf/sifreler.txt //192.168.0.1/mpi/tuketici_w.exe : -hosts 2 192.168.0.5
192.168.0.5 /mpi/tuketici_l
olacaktır. Kodu sadeleştirmenin bir yolu, Linux bilgisayarlarının her birinde yerel bir dizin
oluşturup, kullanacakları programları (192.168.0.4 için “uretici”, 192.168.0.5 için “tuketici”)
bu dizine yerleştirmektir (dosya adlarının sonlarındaki “_l” imlecinin çıkarıldığına dikkat
edin). Her birinde yapılan bu dizinlerin yerinin /home/sururi/mpi olduğunu varsayalım.
Windows bilgisayarlarda da, 192.168.0.1’deki program dosyalarının tutulduğu paylaştırılmış
klasöre gidip, “uretici_w.exe” ve “tuketici_w.exe” dosyalarının adlarını “uretici.exe” ve
“tuketici.exe” olarak değiştirelim. Artık, yukarıdaki aynı işi:
mpiexec –hosts 2 192.168.0.1 1 192.168.0.4 2 –path “//192.168.0.1/mpi;/home/sururi/mpi”
uretici : -hosts 3 192.168.0.2 2 192.168.0.3 1 192.168.0.5 2 –pwdfile
//192.168.0.1/mpi/conf/sifreler.txt –path “//192.168.0.1/mpi;/home/sururi/mpi” tuketici
olarak da yaptırabiliriz. Burada, dosya adlarının aynı olması, doğrudan Shell’de yazıp <enter>
tuşuna basmamızla aynı etkiyi yapmakta. Linux ve Windows dosyaları aynı yerde, biri
uzantısız fakat aynı adlı olsa idi, Windows’un yaptığı uzantısız dosya çağrısına cevap olarak
“.exe” uzantısı eklenip denenen program dosyası değil, mevcut olduğu için doğrudan
uzantısız Linux dosyası gönderilecekti.
Özetle, bilgisayarlarda farklı programları çağırmak için, ilgili işlemin seçeneklerini
programları birbirlerinden “:” ile ayırarak girebiliriz.
50
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
20. Kaynakça ve Tavsiye Edilen Kaynaklar:
1. Peter S. Pacheco. Parallel Programming with MPI, San Fransisco, USA: Morgan
Kaufmann Publishers, Inc. 1997.
Bu kitap, temel aldığım kitap oldu. ODTÜ Kütüphanesi’nde de bulabilirsiniz
(QA76.642 P3). Paralel programlamanın esasları, temel noktalar ve örnek programlar gayet
öğretici bir şekilde anlatılıyor. Bu rehberdeki paralel çalışan integral alma programı da
Pacheco’nun kitabından. Kitaptaki örnekler C++ dilinde değil de, C’de yazılmışlar ama nesne
tabanlı hale çevirmek çok kolay. Ayrıca yazar, kitabın 15. bölümde, farklı bir dil
(FORTRAN) için yazılmış olan ScaLAPACK ve C/C++ için yazılmış olan PETSc
kütüphanelerinden nasıl faydalanılabileceğini gayet detaylı olarak anlatmış, yine anlatmakla
yetinmeyip örnekler de vermiş. Aslında bu kadar faydalı bir kitabın içindekiler kısmını da
buraya almalıyım:
1. Introduction
2. An Overview of Parallel Computing
3. Greetings!
4. An Application: Numerical Integration
5. Collective Communication
6. Grouping Data for Communication
7. Communicators and Topologies
8. Dealing with I/O
9. Debugging Your Program
10. Design and Coding of Parallel Programs
11. Performance
12. More on Performance
13. Advanced Point-to-Point Communication
14. Parallel Algorithms
15. Parallel Libraries
16. Wrapping Up
2. Cameron Hughes, Tracey Hughes. Parallel and Distributed Programming using C++,
USA: Addison Wesley 2003.
Bu kitap da ODTÜ Kütüphanesi’nden temin edilebilir (QA76.642.H83). Genel olarak
paralel programlama ve ne şekilde çalıştığı konusunda bilgi verse de, uygulamaların MPI
değil de, PVM (ve CORBA) kullanması ne yazık ki bu kitabı bir ‘yan-bilgiler kaynağı’
durumuna sokuyor. Seviyesi, bir önceki kitaba göre daha ileri. Bir göz atmanızı öneririm. EK
A: Paralel Programlamada Karşılaşabileceğiniz Terimler’daki tanımların büyük çoğunluğunu
bu kaynaktan aldım.
3. Rumon. Parallel
algo.PDF.
Algorithms,
http://www.khwarzimic.org/cluster/docs/KSS/parallel-
‘Paralel Programlamayla Fox Algoritması’ ile ilgili araştırma yaparken bulduğum bu
döküman, Fox Algoritması’nı anlatmakla kalmıyor, paralel programlama hakkında da pek
çok kavramı açıklıyor.
51
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
4. MPICH2’nin resmi sitesi: http://www-unix.mcs.anl.gov/mpi/mpich2/index.htm.
5. Message Passing Interface Forum, Extensions to the Message-Passing Interface, 2003,
http://www.mpi-forum.org/docs/mpi-20-html/mpi2-report.html. Çeşitli MPI belgelerine
ve MPI Standartlarının açıklandığı belgelere de http://www.mpi-forum.org/docs/docs.html
adresinden ulaşabilirsiniz.
Bu referans, yazar kısmından da anlaşılabileceği üzere, MPI-2 ve MPI-1.2 ile gelen
eklentiler standardını içermekte. Bunun yanı sıra bütün MPI fonksiyonlarının tablolarını ve
C++ notasyonlarının tümünü içeren ekleri, C++’çılar için hazine niteliğinde.
52
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
21. Windows için Visual Studio’ya alternatif derleyiciler:
21.1 C
21.1.1
Bloodshed Dev-C++ (MingW / GCC)
Bloodshed Dev-C++, varsayılan olarak MingW/GCC derleyicisi ile gelir, siz de bu sürümünü
indirin (http://www.bloodshed.net/dev/devcpp.html adresinden, “with Mingw/GCC”
açıklaması olan sürüm). Programı kurduktan sonra (emin olmak maksadıyla, biraz evvel temiz
bir bilgisayara kurulum yaptım: kurulum türü olarak Full seçip arkanıza yaslanın, gerekli
yerlerde Next ve OK ikilisini seçin), Yeni bir proje açın , projenin yerini belirleyin.
Şekil 24: Dev-C++'da proje oluşturulması
Açılan main.cpp dosyasında hazır gelen satırları temizleyip kodunuzu yazıp kaydedin.
Şekil 25: Ornek 3'un C kodu
Project menüsünden, Project Options [Alt-P] seçeneğinden çıkacak pencerede Parameters
kulakçığındaki Linker penceresine -lmpi yazın (Şekil 26). Directories kulakçığından Library
Directories’e MPICH2’nin lib klasörünü (varsayılan C:\Program Files\MPICH2\lib), Include
Directories kısmına ise MPICH2’nin include (varsayılan C:\Program Files\MPICH2\include)
klasörünü ekleyin. Artık programımızı derleyebiliriz!
53
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
Şekil 26: Proje özelliklerinde ek parametre belirtilmesi.
Derlemek için, Execute menüsünden Compile seçeneğini seçin [CTRL-F9]. Bir hata
yoksa (ki bu ‘hata’lara ne yazık ki MPI’ın C++ dilindeki kullanımı da dahil), programınız
derlenmiş olacaktır. Tebrikler!
Ne yazık ki, bu derleyiciyi (Mingw/GCC) C++ yerine C başlığı altında açıklıyorum.
Visual Studio’nun rahatlıkla derlediği MPI’ın C++ dilindeki kullanımı (C++ Language
Bindings) bu şekilde derlenemedi. Denemeler sırasında mpi.lib’in yanı sıra, cxx.lib’i; mpi.h’ın
yerine mpicxx.h’ı kullanmam da fayda etmedi. Programınızın C++ dilinde olması sorun
oluşturmuyor, sorun, MPI için de C++ nesnelerini tercih ettiğinizde ortaya çıkıyor. Bir ara
deneyebilirsem Cygwin’de ve MSYS’de de deneyeceğim. Linux’da mpicxx zarflayıcısı
(enveloper) bizleri büyük bir dertten kurtarıyor fakat Windows’da böyle bir lüksten
mahrumuz.
21.2 C++
21.3 Fortran / Fortran90
54
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
22. Yapılacaklar:
Aralık ayında yazmaya başladığım bu rehbere nisan ayında hâlâ yazmaya devam ettiğimin
farkına varmam, beni dehşete düşürdüğü gibi, bu rehberin gün ışığı görebileceğine dair
umutlarım konusunda da fena halde karamsarlığa itti. O yüzden, kervan yolda düzülür düsturu
uyarınca, daha fazla geciktirmeden internet ortamına koymaya karar verdim. Buraya da,
“Yapılacaklar” başlıklı bir bölüm yerleştirdim ki, gerek ben, gerekse sizler vaktiniz
olduğunda, burada yer alan listeden kısımları seçip, tamamlayabilelim. Rehberi yazmaya
başladığım günden beri geçen zamanda bir takım değişiklikler / gelişmeler de olmadı değil: en
önemlisi, sonunda bir Linux dağıtımı (Pardus) bilgisayarımda kendine yer bulabildi, bütün
rehber boyunca anlattıklarımın %99’unun MPI-2 değil de, hali hazırda MPI-1’in özellikleri
olduğunu fark ettim, vs.. 8) Bu nedenlerden ötürü, işte—
Yapılacaklar Listesi:
• Rehberin İngilizce’ye tercümesi.
• “EK B: Linux Makinelerde SAMBA sunucusu kurulumu ve kullanımı” ve “EK C: Linux
Makinelerde gcc derleyicisinin kurulumu ve kullanımı” bölümlerinin yazımı.
• Paylaşımcı İletişim (Collective Communication) grubunun başlıca fonksiyonları olan
Reduce, Allreduce, Gather, Scatter, Allgather, Reduce_scatter,
Barrier fonksiyonlarının ayrıntılı ve örneklerle açıklamaları.
• MPI-2’nin aslında getirdiği yenilikler. 8)
• Windows için Visual Studio’ya alternatif MPICH kodu derleyicilerinin kullanımı.
55
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
23. Dizin
A
H
Hızlanma. bkz. Hızlanma
Aint, 36
Anahtar. bkz. Switch
Arabellek. bkz. Buffer
Arpa Boyu. bkz. Grain Size
I
I/O. bkz. Giriş/Çıkış
Implementation, 44
IPX/SPX/NetBIOS, 47
B
Barrier, 40
Benchmark, 44
Beowulf Cluster, 44
Beowulf Kümesi. bkz. Beowulf Cluster
Betik. bkz. Script
Bloodshed Dev-C++, 53
Boruhattı. bkz. Pipeline
Buffer, 44
İ
İletişim Gideri. bkz. Communications Overhead
İş Parçacığı. bkz. Thread
İşlem. bkz. Process
K
C
Katman. bkz. Layer
Kullanıcı Arayüzü. bkz. User Interface
Küme. bkz. Cluster
Cluster, 44
Commit, 36
Communications Overhead, 44
contigious, 34
CORBA, 44
count, 34
CRCW, 45
CREW, 45
L
LAM, 6
Layer, 44
Linear Speedup, 44
Load Balancing, 44
Ç
M
Çizgisel Hızlanma. bkz. Linear Speedup
Çöp Toplayıcı. bkz. Garbage Collector
MICO, 44
MPD, 44
MPI, 6, 44
MPI::Comm::Bcast, 34
MPI::Comm::Recv, 33
MPI::Comm::Send, 33
MPI::Datatype::Create struct, 36
MPI_ANY_SOURCE, 33
MPI_ANY_TAG, 34
MPI_Bcast, 34
MPI_Pack, 37
MPI_Recv, 33
MPI_Send, 33
MPI_Type_contigous, 36
MPI_Type_indexed, 37
MPI_Type_struct, 36
MPI_Type_vector, 36
MPI_Unpack, 37
MPICH, 6, 45
MPICH2’nin Linux Makinelerde Kurulumu, 16
MPICH2’nin Windows Makinelerde Kurulumu, 11
mpicxx, 27
mpiexec, 48
host, 48
hosts, 48
localonly, 48, 49
machinefile, 48
n, 49
path, 49
pwdfile, 49
D
Datatype::Pack, 37
Datatype::Unpack, 37
Değerlendirme. bkz. Benchmark
Delegation (boss-worker), 45
Derece. bkz. Rank
Düğüm. bkz. Node
E
Efficiency, 44
ERCW, 45
EREW, 45
Eşler arası. bkz. Peer-to-peer
G
Garbage Collector, 44
gcc, 47, 55
Giriş/Çıkış, 9
Grafiksel Kullanıcı Arayüzü. bkz. Graphical User
Interface
Grain Size, 44
Graphical User Interface, 44
56
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
sethosts, 48
shutdown, 48
status, 48
SMPD, 45
Speedup, 45
SPMD, 45
Switch, 45
mpiexec ile bilgisayarlarda farklı programlar
çalıştırmak, 49
MPMD, 45
N
Node, 45
T
O
Tekrarlı. bkz. Recursive
Thread, 45
OpenMP, 6
P
U
Paralel Programlama, 8
Paralel Programlama Vasıtasıyla İntegral Hesaplama, 29
Parallel Virtual Machine. bkz. PVM
Peer-to-peer, 46
Pipeline, 46
POSIX, 45
PRAM, 45
Process, 45
Producer-consumer, 46
PVM, 45
UML, 46
User Interface, 46
Uygulama. bkz. Implementation
Ü
Üretici-tüketici. bkz. Producer-consumer
V
Verim. bkz. Efficiency
Visual Studio 2005, 2, 5, 17
von Neumann Makinesi, 46
R
Rank, 45
Recursive, 45
Reduce, 40
W
WBS, 46
Work Breakdown Structure, 46
S
SAMBA, 45, 47, 55
Script, 45
SMB, 45
smpd, 48
get phrase, 48
help, 48
hosts, 48
phrase, 48
restart, 48
Y
Yetkilendirme (patron-işçi). bkz. Delegation (bossworker)
Yük dengeleme, 9
Yük Dengeleme. bkz. Load Balancing
57
MPICH2 Kullanarak Windows, Linux ve “Windows veya Linux” İşletim Sistemleri Yüklü Bilgisayarlardan Oluşan Küme Kurulumu ve Bu
Kümede C++ Dilinde Yazılmış Paralel Programları Yazıp Çalıştırma Rehberi / Emre Sururi Taşcı – ODTÜ Fizik Bölümü.
http://144.122.31.143/mpich2/
24. Dosya Ekleri ve Açıklamaları:
• ornek1.cxx
: MPICH’in Send, Recv, Bcast ve Barrier temel fonksiyonlarını
kullanan, deneme amaçlı paralel program kodu (11. Bölüm).
: Yamuk yöntemiyle integral hesaplayan seri program kodu
• integral_seri.cpp
(12.2. Bölüm).
• integral_paralel.cxx : Yamuk yöntemiyle integral hesaplayan paralel program kodu
(12.5. bölüm). Bu programda 12.4. bölümde anlatılan çeşitli mesajlaşma şekilleri ve
yöntemlerinin kullanımını görebilirsiniz.
• mpi_orn3.cxx
: Performans takibinde kullanmak üzere basitçe birkaç işlem
yapan paralel program kodu (13. Bölüm).
: Performans takibinde kullanmak üzere basitçe birkaç
• main.dev, main.cpp
işlem yapan paralel programın MPI ile ilgili kısımlarının C++ yerine C dilinde yazılmış
sürümünü içeren Dev-C++ projesi (21.1.1. bölüm).
Programların kodlarını ve Windows işletim sistemi
http://144.122.31.143/mpich2/ sayfasından indirebilirsiniz.
58
için
derlenmiş
hallerini

Benzer belgeler