Paralel çalışabilen sistemler artık hemen hemen her yerde karşımıza çıkmaktadır. Günümüzde çok çekirdekli bir işlemci kullanmayan bir dizüstü bilgisayar masaüstü veya sunucu bulmak oldukça zordur. Bununla birlikte çoğu bilgisayar mühendisleri paralel programlama hakkında çok az tecrübeye sahip veya az deneyimli bir şekilde mezun olmaktadır. Her ne kadar birçok üniversite son sınıflara doğru seçmeli ders olarak paralel hesaplamayı sunmakta iseler de öğrenciler zorunlu alması gereken derslere öncelik tanıdıklarından çok kanallı veya çok işlemli bir program yazma becerisinden yoksun olarak mezun olmaktadır. Bu durumun değişmesi gerektiği açıktır. Birçok program tek bir çekirdek üzerinde tatmin edici bir performans elde edebilmesine rağmen Bilgisayar bilimcileri paralellik ile elde edilebilecek geniş kapsamlı performans iyileştirmelerinin farkında olmalı ve ihtiyaç duyulduğunda bu potansiyelden yararlanabilmelidir.
Bu kitap kısmen bu problemi çözmek için yazılmıştır. Ayrıca paralel programlama kavramını açıklayan ilk kitaplardan biridir. Paralel programlama için en yaygın kullanılan uygulama programlama arayüzlerinden (API) ikisi olan MPI ve OpenMP ile paralel programların yazılmasına bir giriş sağlanmaktadır. Örneklerin birçoğu günümüzde yaygın kullanıma sahip C ve Python dili ile kodlanmıştır. Hedef kitle paralel programlar yazması beklenilen öğrenciler araştırmacılar ve profesyonellerdir. Kitaptan en iyi bir şekilde yararlanabilmek için önkoşullar minimal düzeyde tutulmuştur. Açıkçası lise düzeyinde bir matematik ve C dilinde temel programlar yazma becerisi bu kitabı anlayabilmek ve uygulayabilmek için yeterli gelmektedir.
Paralel hesaplama ile önceden deneyime sahip olmayan okuyucular ilk önce Bölüm 1'i okumalıdır. Burada paralel sistemlerin neden bilgisayar mimarisine ve alanına hâkim olduğuna dair açıklama bulunmaktadır. Bu bölüm ayrıca paralel sistemlere ve paralel programlamaya kısa bir giriş sağlar. Bölüm 2 3 ve 4 sırasıyla OpenMP MPI ve Python ile programlamaya dairdir. 2. ve 3. Bölümde kodlanan örnekler C programlama dili ile yazılmıştır çünkü kullanılan tüm API'lar C-dili arayüzlerine sahiptirler. Bununla birlikte C++ ve Java programcıları C dili söz dizimine aşina olduklarından bölümlerde yazılan C kodlarını rahatlıkla anlayacaklardır. 4.Bölümdeki örnek kodlarda ise günümüzde popüler bir dil olan Python 3.7 dili kullanılmıştır.
Umuyorum ki okuyucular OpenMP MPI ve Python'un tam anlamıyla kodlanma tarzını ve gücünü kullanmayı öğrenirler. Bu kitap paralel programlamaya yeni başlayanlara mükemmel bir giriş özelliğini taşımaktadır. Kitapta bulunan bütün örnek kodlar ayrı ayrı özenle test edilmiş ve düzgün çalıştığı doğrulanmıştır. Yine de gözden kaçan eksiklikler olabilir. Bu nedenle okuyucuların bulduğu sorunları ve/veya varsa önerilerini [email protected] e-posta adresine göndermelerini rica ediyorum.
Kitapta yer alan bölümler aşağıdaki gibidir.
İÇİNDEKİLER
1.Bölüm: Paralel Programlamaya Giriş
1.1 Neden Paralel Hesaplama?
1.2 Neden sürekli artan performansa ihtiyaç duyuluyor?
1.3 Neden paralel sistemler kuruyoruz?
1.4 Neden paralel programları yazmamıza gerekir?
1.5 PARALELDE SORUN GİDERME
1.5.1 Zamansal Paralellik Kavramı
1.5.2 Veri Paralelliği Kavramı
1.6 Von Neumann mimarisi
1.7 BAZI TEMEL PARALEL KAVRAMLARI
1.7.1 Program Kavramı (Program Concept)
1.7.2 Süreç / İşlem Kavramı (Process Concept)
1.7.3 İplik / İşparçacığı Kavramı (Thread Concept)
1.7.4 Eşzamanlı ve Paralel Yürütme Kavramı (Concurrent & Parallel Execution Concept)
1.7.5 Yarış Koşulları (Race Conditions)
1.7.6 Kilitlenme (Deadlocks)
1.7.7 Açlık (Starvations)
1.7.8 İplik Güvenliği (Thread Safty)
1.7.9 Granülerlik/Taneciklilik (Granularity)
1.8 VON NEUMANN MODELİNE DEĞİŞİKLİKLER
1.8.1 Caching temelleri
1.8.2 SANAL BELLEK (Virtual Memory)
1.9 PARALEL İŞLEME SEVİYELERİ
1.9.1. Komut Seviyesinde Paralellik (Instruction-level Parallelism (ILP))
1.9.1.1 Boru hattı (Pipelining)
1.9.1.2 Komut Pipeline
1.9.1.3 Komut Buffer'i:
1.9.2. Döngü Seviyesinde Paralellik (Loop Level Parallelism)
1.9.3. Prosedür Seviyesinde Paralellik (Procedure Level Parallelism)
1.9.4. Program Seviyesinde Paralellik (Program Level Parallelism)
1.10 PARALEL BİLİSAYARLARIN SINIFLANDIRILMASI
1.10.1 Flynn'in Paralel İşleme Sınıflandırması
1.10.1.1 Tek komut ve Tek Veri akışı (Single Instruction and Single Data stream (SISD))
1.10.1.2 Tek Komut ve Çoklu Veri Akışı (Single Instruction and Multiple Data stream (SIMD))
1.10.1.3 Çoklu Komut ve Tek Veri akışı (Multiple Instruction and Single Data stream (MISD))
1.10.1.4 Çoklu Komut ve Çoklu Veri akışı (Multiple Instruction and Multiple Data stream (MIMD))
1.11 YAPISAL SINIFLANDIRMA
1.11.1 Paylaşımlı Bellek Sistemleri (Shared Memory Systems)
1.11.2 Dağıtılmış Bellek Sistemleri (Distributed Memory System)
1.12 Arabağlantı ağları (Interconnection networks)
1.12.1 Tam bağlı (Fully connected) Topoloji
1.12.2 Kol Demiri (Cross Bar) Topolojisi
1.12.3 Doğrusal Array (Linear Array) Topolojisi
1.12.4 Mesh Topolojisi
1.12.5 Halka (Ring) Topolojisi
1.12.6 Torus Topolojisi
1.12.7 Ağaç ağı (Tree) Topolojisi
1.12.8 İri ağaç (Fat Tree) Topolojisi
1.12.9. Sistolik Dizi (Systolic Array) Topolojisi
1.12.10. Küp (Cube) topolojisi
1.13 Permütasyon Ağı Kavramı
1.13.1 Mükemmel Karıştırma Permütasyonu
1.13.2 Kelebek Permütasyonu
1.13.3 Clos ağı
1.13.4 Benz ağı
1.14 Önbellek Tutarlılığı (Cache Coherence)
1.14.1 Önbellek Tutarlılığını Gözetleme (Snooping cache coherence)
1.14.2 Dizin Tabanlı Önbellek Tutarlılığı (Directory-based cache coherence)
1.15 Yanlış paylaşım konsepti (False Sharing)
1.15.1 Önbellek Hatları (Cache lines)
1.15.2 Önbellek tutarlılığı (Cache coherence)
1.15.3 Yanlış paylaşım
1.16 Tanecik Boyuna (Grain size) Göre Bilgisayar Sınıflandıması
1.16.1 Paralellik Koşulları
1.16.2 Veri Bağımlılığı (Data Dependency)
1.16.3 Paralellik tespiti için Bernstein koşulları
1.16.4 Kaynak Bağımlılığı
1.17 Paralellik potansiyeli
1.18 Paralel Hesaplama Gereksinimi
1.19 Özet
Çalışma soruları
2. Bölüm: OpenMP Kullanarak Paylaşımlı Bellek Programlaması
2.1 OpenMP ile başlayalım
2.2 Visual Studio'yu kullanarak OpenMP programlarının derleme ve çalıştırması
2.3 Open MP'nin Bazı Terimelri
2.3.1 OpenMP Derleyici Yapıları
2.3.2 OpenMP Derleyici Yapıların Deyimleri
2.3.3 "Parallel" Yapısı
2.4 OpenMP Programındaki İpliklerin Arasında Paylaşma
2.4.1 Döngü Yapısı (Loop Construct)
2.4.2 "Sections" (bölümler) Yapısı
2.4.3 "Single" (Tek) Yapısı
2.5 Birleşik Paralel Çalışma-Paylaşım yapıları (Combined Parallel Work-Sharing Constructs)
2.6 Paralel ve Çalışma Paylaşım Yapılarını Kontrol Eden Deyimler
2.6.1 "Shared" (Paylaşılan) Deyimi
2.6.2 Private (Özel) Deyimi
2.6.3 "Lastprivate" deyimi
2.6.4 "Firstprivate" Deyimi
2.6.5 "Default" (Varsayılan) Deyimi
2.6.6 "Nowait" Deyimi
2.6.7 "Schedule" (zamanlama) deyimi
2.7 OpenMP Senkronizasyon Yapıları
2.7.1 Barrier (Bariyer) Yapısı
2.7.2 "Ordered" (sıralı) Yapısı
2.7.4 "Atomic" (Atomik) Yapısı
2.7.5 "Master" Yapısı
2.8 Yürütme Ortamı ile Etkileşim
2.9 Daha Fazla OpenMP deyimleri
2.9.1 "If" deyimi
2.9.2 "Num_threads" deyimi
2.9.3 "Ordered" deyimi
2.9.4 "Reduction" (azaltma) deyimi
2.10 Gelişmiş OpenMP yapıları
2.10.1 İç içe Paralelizm
2.10.2 "Threadprivate" Yapısı
2.11 Özet
Çalışma Soruları
3.Bölüm: MPI (Message-Passing Interface) Kullanarak Dağıtılmış Bellek Programlaması
3.1 Noktadan Noktaya (Point-to-Point) İşlemler Türleri
3.1.1 Engelli karşı engelsiz (Blocking vs. Non-Blocking)
3.1.1.1 Engelli (Blocking) Mod
3.1.1.2 Engelsiz (Non-Blocking) Mod
3.1.2 Buffer'li karşı Buffer'sız (Buffered vs Unbuffered)
3.2 Merhaba Dünya Programı
3.2.1 MPI_Init ve MPI_Finalize
3.2.2 İletişimciler (Communicators) MPI_Comm_size ve MPI_Comm_rank
3.3 MS Visual Studio'yu kullanarak MPI programın kurma ve çalıştırma
3.4 Engelli Mesaj Göndermesi Fonksiyonları (Blocking Message Passing Routines)
3.4.1 SIMD programları
3.4.2 İşlemler Arasında İletişim
3.4.2.1 MPI_Send
3.4.2.2 MPI_Recv
3.4.2.3 Mesaj Eşleşmesi
3.4.2.4 Status_p argümanı
3.4.2.5 MPI_Send ve MPI_Recv Anlamları
3.4.2.6 Bazı potansiyel tuzaklar
3.4.3 MPI'da İplik Desteği Seviyesi
3.5 Engelsiz Mesaj Göndermesi Fonksiyonları (Non-Blocking Message Passing Routines)
3.6 MPI'da Toplu İletişimi (Collective Communication in MPI)
3.6.1 Toplu iletişim türleri
3.6.1.1 Bariyer Senkronizasyonu
3.6.1.2 Veri Hareketi veya Global İletişim (Global Communication)
3.6.1.2.1 MPI_Bcast (Broadcast (one to all)
3.6.1.2.2 MPI_Scatter
3.6.1.2.3 MPI_Alltoall()
3.6.1.2.4 MPI_Gather (All-To-One)
3.6.1.2.5 MPI_Allgather()
3.6.1.3 Kolektif Operasyonlar (veya Küresel Azaltma)
3.6.1.3.1 MPI_Reduce
3.6.1.3.2 MPI_Allreduce
3.7 Paralel Performansı Kıyaslaması
3.8 Özet
Çalışma Soruları
4. Bölüm: Python kullanarak Paralel Programlama
4.1 Python Tanıtımı
4.2 Python indirmesi ve yüklemesi
4.3 Python temelleri
4.4 Paralel Python
4.5 Python'daki işlemlerle çalışmaya başlamak
4.6 Python'da İplikle Çalışmaya Başlamak
4.6.1 Python "threading" modülünü kullanması
4.6.2 Lock ile İş Parçacığı Senkronizasyonu
4.6.3 RLock ile İş Parçacığı Senkronizasyonu
4.6.4 Semaforlar ile İş Parçacığı Senkronizasyonu
4.6.5 Bir Koşulla İş Parçacığı Senkronizasyonu
4.6.6 Bir Olayla İş Parçacığı Senkronizasyonu
4.6.7 "with" ifadesini kullanması
4.6.8 Bir Kuyruk Kullanarak İş Parçacığı İletişimi
4.7 Çok İplikli Uygulamaların Performansının Değerlendirilmesi
4.8 Özet
Çalışma Soruları
Kaynakça
İnternet Kaynakçası