ÖNEMLİ : Kendim için aldığım notlar. Umarım size de bir faydası olur. Kullanılan her bir makale referans olarak eklenmiştir. Rice Üniversitesi’nin hazırladığı eğitsel bir Framework olan PCDP bu ve sonraki bölümlerde kullanılacaktır. async ve finish notasyonları bu Framework’de yer almaktadır.
Java Paralel Programlama Serisi
Genel Bakış
Bilgisayar bilimlerinde, sıralı bir algoritma(sequential algorithm) veya seri algoritma(serial algorithm), eşzamanlı(concurrently) veya paralel’in(parallel) aksine sırayla (başka bir işlem çalıştırmadan baştan sona kadar bir kez) yürütülen bir algoritmadır. Terim öncelikle eşzamanlı algoritma veya paralel algoritma ile zıtlık oluşturmak için kullanılır; çoğu standart bilgisayar algoritması, sıralı algoritmalardır ve sıralılık bir arka plan varsayımı olduğu için özel olarak tanımlanmamıştır.
Bir algoritma bir işlem sırasına sahiptir. Bunları S1, S2, S3, S4 şeklinde sıralayabiliriz. Çok çekirdekli işlemciler için paralel programlamanın arkasındaki temel fikir, bu adımlardan hangisinin birbirleriyle paralel çalışabileceğini belirlemektir. Kısacası asıl önemli olan bu paralelliklerinin nasıl koordine edilmesi gerektiğidir.
Örnek
Basit bir örnek ile başlamak gerekirse, integer içeren bir dizi olduğunu varsayalım. Amacımız array’in sahip olduğu elementlerin toplamını hesaplamak olsun. Şimdi bunu yapmanın bir yolu, onu iki yarıya bölmek ve alt yarı ile üst yarıdaki toplamı ayrı ayrı hesaplamak. Böylece;
- SUM1 = alt yarının toplamı,
- SUM2 = üst yarı toplamı
olabilir. Sonra bu ikisini birleştirerek son toplamı alabiliriz.
Ekstra bir işlem yapmaz isek, yukarıdaki adımlar sıralı bir şekilde sequential algorithm kullanılarak yapılır. Peki bunu paralel olarak nasıl yapabiliriz? Burada kullanacağımız notasyon asenkron(async
) denilen bu kelimedir. Async‘nin amacı, bir statement tarafından takip edilen async
notasyonuna sahip ifadenin asenkron(zaman uyumsuz) olarak çalışması gerektiğidir. Görüleceği üzere SUM1 async
olarak işaretlenmiştir. Bunun anlamı, bu hesaplama, SUM1(alt yarının toplamı), takip eden işlem ne olursa olsun asenkron olarak devam etmelidir. ASYNC olarak işaretli SUM1 işlemi, SUM2 işleminden önce de gerçekleşebilir, sonra da gerçekleşebilir, hatta paralel olarak da gerçekleşebilir.
Şimdi farzedelim ki bu iki işlem paralel olarak ilerliyor ve sonrasında SUM2‘yi hesaplıyoruz; buradaki kilit nokta, ikisini bir araya getirmeden, yani SUM1 ve SUM2‘yi toplamadan önce, bu “zaman uyumsuz(async
)” görevin nihayete erip SUM1 değerini elde etmemiz gerekmektedir. Tam da bu noktada bu işlemi gerçekleştirebilmek için bitiş(finish
) adında başka bir notasyonumuz vardır.
Bu yüzden finish
‘in arkasındaki temel fikir, çalışan bir dizi asenkron görev alabileceğiniz bir iş kapsamıdır. Görüleceği üzere async
notasyonu sadece SUM1‘i kapsarken, finish
notasyonu hem SUM1 hem de SUM2‘yi kapsamaktadır. Aslında finish
scope’unun(kapsamının) sonunda bütün görevlerin tamamlanacağını garanti edersiniz. Yani finish
scope’unun içindeki asenkron görevler dahil bütün görevler bitmeden bir sonraki işlem ele alınmaz. Artık SUM1 işleminin finish
notasyonundan sonra uygun olacağından emin olabiliriz. finish
notasyonundan sonra SUM1 ve SUM2 için toplama işlemi gerçekleştirebiliriz.
Yukarıdaki resimde de görüleceği üzere, eğer pentium dual bir işlemciye sahipseniz, işlemlerden biri(yani SUM1) core0
çekirdeğinde, işlemlerden diğeri(yani SUM2) core1
çekirdeğinde gerçekleşecektir. Dolayısıyla, buradaki prensibe bakarsanız, herhangi bir sıralı algoritmayı alabilir ve paralellik için fırsat gördüğümüz her yerde asyncs
ile önek ekleyebiliriz.
Paralel olarak çalışmasını istediğiniz işlemlerin bulunduğu yere bir finish
scope’u ekleyin. Yukarıdaki örnekteki gibi S2, S3, S4 birbirleriyle paralel olarak çalışacaktır. Fakat S5 işlemi, finish
scope’u tamamlanıncaya kadar bekleyecektir.
Not : Bu bölümde gördüğümüz async ve finish notasyonları eğitsel ve gösterimsel kavramlardır. Fakat Java’daki karşılıkları tabii ki bu şekilde değildir. Bir sonraki bölümde ise aynı konseptin Java’daki karşılıklarına bakacağız.
Özet
Bu bölümde bir array kullanarak görev oluşturma(task creation) ve görev sonlandırma(task termination) konseptlerini öğrendik.
1
2
3
4
5
finish {
async S1; // Asenkron olarak dizinin alt yarısının toplamını hesapla
S2; // S1 ile paralel array'in üst yarısının toplamını hesapla
}
S3; // S1 ve S2 tamamlandıktan sonra iki kısmi toplamı birleştirir.
- Görev oluşturma(task creation) için zaman uyumsuz(asenkron) gösterimini öğrendik:
async
S1 –>async
notasyonu parent task’ın bir child task oluşturmasına sebep olur.async
notasyonuna sahip task, parent task ile asenkron bir şekilde işleme alınır. Burada işlem parent task’ın öncesinde sonrasında veyahut parelel bir şekilde gerçekleşebilir. finish
notasyonunu kullanarak görev sonlandırma(task termination) gösterimini öğrendik.finish
notasyonu, parent task’ın çalışmasını vefinish
scope içinde oluşturulan tüm asenkron görevlerin tamamlanmasını bekler.async
vefinish
yapıları isteğe bağlı olarak yerleştirilmiş olabilir.
Referanslar :
- Sequential algorithm
- Asynchronous method invocation
- Analysis of parallel algorithms
- Class RecursiveAction
- Class RecursiveTask
- Class ForkJoinPool
- Package java.util.stream
- Interface Stream
- Fork/Join
- Java VisualVM
- Parallel Programming in Java
- PCDP parallel programming framework
- Şekil 1,2,3,4,5 - lucidchart ile hazırlanmıştır.