yazılım,c# ve domates kabuğu
« Product vs Platform şirketleriturnaround time »

Parallel kütüphanesi

  22/05/11 21:16, by ertan, Categories: Yazılım, Algoritma Soruları

Uzun bir aradan sonra sonunda hakkında yazabileceğim bir şey yeni aklıma geldi. Eğer yamulmuyorsam Parallel kütüphanesi Framework 4.0 ile beraber geldi, daha öncesinde MS Research'in geliştirdiği bir extension olarak gizli bir köşede saklanıyordu.

Parallel kütüphanesi ( yada AsParallel() ) Nedir ?

Parallel kütüphanesi son 2-3 yılda yeni çıkan birden fazla işlemcilerin avantajını kullanmak için işleri kolaylaştırmak amacıyla geliştirilmiş bir kütüphane.

Temel olarak yaptığı sıralı olarak yapılacak işleri birden fazla CPU'ya dağıtarak aynı anda birden fazla iş yapmaya, dolayısıyla da verilen işi daha hızlı yapar.

Neden ihtiyacım olur

Bundan yıllar öncesinde C yada ASM'de yazdığım zamanlarla karşılaştırınca, bisikletle bir ferrari'yi karşılaştırmaya benziyor. İronik olan kısım ise yazdığımız programlar halen o zamanki programlar kadar yavaş.

Önce herhangi bir programı yavaşlatan nedir diye düşünelim;

* Donanım

* Network

* For, Foreach, While gibi döngüler.

Bunların dışında bir programın yavaş çalışmasına neden olacak bir etken yok. Donanım ve Network kısmı için zaten sürekli olarak bir şeyler yapılıyor zaten konumuzun dışında.

Eğer yazdığımız kodun hızlı çalışmasını istiyorsak yapacağımız tek şey bu döngü'lere dikkat etmek, ne kadar az döngü varsa kod o kadar hızlı çalışacaktır. Bu optimizasyonu tabiki belli dereceye kadar yapabiliriz ve nihayetinde bazı kısımlar kalacak.

Standart kodlama yaparken (eğer thread filan yaratmıyorsanız) yazdığımız kod her zaman ve her zaman tek CPU üzerinde çalışacaktır. Bazen CPU bir şeylerle uğraşırken Task Manager'i açtığınızda tüm CPU'ların bir şey yaptığını görüyor olursunuz ancak burası biraz yanıltıcıdır.

Çok merak ediyorsanız basit bir loop yaratarak CPU'yu sürekli meşgul tutan bir kod çalıştırın ve Task Manager'da olanları izleyin, eğer 2 CPU'lu bir makinanız varsa test yaptığınız exe asla %50 (4 CPU'nuz varsa %25) cpu kullanımının üzerine çıkmayacaktır. Task Manager'ın grafik kısmına baktığınız zaman tüm CPU'larda aktivite gözükür ancak bu işletim sisteminin yapılan işleri farklı CPU'lara dağıtması yüzünden kaynaklanır. Yani kodunuz kısa bir süre 1. CPU daha sonra 2. CPU'da çalışmaya devam eder. Ancak yaptığınız iş tek CPU sınırını aşmadığı için asıl rakamlara baktığınız zaman bu söylediğim görünmez bariyer'de takılırsınız.

Yazdığınız kodu hızlandırmak için birden fazla CPU kullanmayı istiyorsanız kodunuz içinde ekstra olacak bir şeyler daha ekleyerek, niyetinizi belli etmeniz gerekir.

Nasıl ?

Anlaşılır olması için örnekli gidiyorum; basit bir örnek olsun diye elimizde bir int array'i olsun ve biz array üstündeki elemanı string halline dönüştürmek isteyelim. (Pratikde string'e dönüştürmekten başka bir şeyler olacaktır)

Önce array'i tanımlayıp içini çöp'le dolduralım.

Code

List<int> arr = new List<int>();
 
 
 
   for (int i = 1; i < 9999999; i++)
 
      arr.Add(i);

Standart olarak yazacağımız kod aşağıdaki gibi;

Code

a.ForEach(delegate(int i)
 
  {
 
      return i.ToString();
 
  });

Şimdi bu kodu benim 8 CPU'lu canavar bilgisayarımda çalıştırdığımda süre olarak 01.520 saniyede tamamlanıyor.

Aynı kod üzerinde biraz değişiklik yaparak paralel kütüphanesinin kullanılmasını istersem;

Code

arr.AsParallel().ForAll(delegate(int i)
 
  {
 
      string c = i.ToString();
 
  });

Araya eklediğim bu AsParallel ile çalışma süresi 0.619 saniyeye düştü.

Karşılaştırma yapınca arada devasa bir fark var. Geriye tek sorun kalıyor;

Paralel çalışacak kod parçası üzerinde sıralı işlemler yapmamanız gerekli, örneğin toplama gibi sıralı olması gerekmeyen bir kod yazabilirsiniz ancak bir önceki değere ihtiyacınız olduğu durumlarda işler biraz zorlaşabilir.

Böyle durumlar biraz daha karmaşık, bunun detaylarını daha sonra yazarım ancak sadece bu yöntemle kodunuz içindeki döngüler'in büyük bir çoğunluğunda bu parallel kütüphanesini halen kullanabilirsiniz.

Umarım işinize yaramıştır. Unutmadan denemek isteyenler için tüm test kodu aşağıda;

Code

List<int> arr = new List<int>();
 
 
 
for (int i = 1; i < 9999999; i++)
 
    arr.Add(i);
 
 
 
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
 
 
 
s.Start();
 
 
 
arr.ForEach(delegate(int i)
 
{
 
    string c = i.ToString();
 
});
 
 
 
s.Stop();
 
 
 
Console.WriteLine(" Sure : " + s.Elapsed);
 
 
 
s.Reset();
 
s.Start();
 
 
 
arr.AsParallel().ForAll(delegate(int i)
 
{
 
    string c = i.ToString();
 
});
 
 
 
s.Stop();
 
 
 
Console.WriteLine(" Sure : " + s.Elapsed);

No feedback yet

Leave a comment


Your email address will not be revealed on this site.
  
(For my next comment on this site)
(Allow users to contact me through a message form -- Your email will not be revealed!)
Text Renderers:
 

©2017 by Ertan Tike

Contact | Help | Blog template by Asevo | blog tool | dedicated server | authors