• Anasayfa
  • Hakkımızda
  • Etkinlikler
  • Destek Verin
  • Site Haritası
  • Giriş Yap
  • Üye Ol
  • Facebook
  • Twitter
  • RSS
Yazılım Dilleri
  • Soru - Cevap
  • EĞİTİM SETİ
  • KATEGORİ
  • DUYURU
  • TEKNOLOJİ HABERLERİ

Son Sorular

  • 23.04.2016 00:55:33C programlama 2 oyun
  • 20.04.2016 16:34:41Local Database
  • 15.04.2016 14:26:15Fatura kayıt işlemi
  • 21.03.2016 01:55:30C# problem

Popüler Sorular

  • 27.05.2012 05:49:50Asp.Net ile Date time alana veri ekleyemiiyorum ?
  • 2.04.2012 00:45:18.exe uzantılı dosya için dijital imza nerde nasıl alınır.
  • 12.05.2012 08:44:49Acil Yardım
  • 27.05.2012 13:46:51veri tabanı bağlantısı
  • .Net Framework
  • 8085 Assembly
  • Active Directory
  • ADO.NET
  • Android
  • Apple IOS
  • Arduino
  • ASP.NET
  • ASP.NET MVC
  • Blackberry
  • C#.Net
  • C++
  • CCG Framework
  • CISCO
  • CSS
  • Diğer
  • Dreamweaver
  • Entity Framework
  • Exchange Server
  • Gömülü Sistemler
  • GSM Programlama
  • Güncel
  • Güvenlik
  • HTML5
  • Java
  • Javascript / JQuery
  • Jira
  • Kariyer ve İş Yaşamı
  • LINQ
  • LibreOffice
  • Linux
  • Matlab
  • Microsoft Dynamics CRM
  • Mobil Uygulama Geliştirme
  • MySQL
  • NoSQL
  • Oracle
  • OWIN
  • PFSense
  • PHP
  • Powershell
  • Python
  • Sanallastirma
  • SAP-ABAP
  • SCOM 2012
  • SEO
  • Sharepoint 2010
  • Sharepoint 2013
  • Silverlight
  • Sistem Analiz ve Tasarımı
  • SQL Server
  • Symantec
  • TFS
  • T-SQL
  • Ubuntu
  • VB.NET
  • Veritabanı Yönetim Sistemleri
  • Visual Studio
  • VMware
  • WCF
  • Web Hosting
  • Windows 8
  • Windows Azure
  • Windows Phone 7.1
  • Windows Phone 8
  • Windows Server
  • Wordpress
  • WPF
  • Xamarin
  • XNA
  • Yazılım Mühendisliği
  • Yöneylem Araştırması
  • ASP.NET MVC
  • Entity Framework
  • Javascript / JQuery
  • LINQ
  • PHP

Son Duyurular

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

FORParallelism

Günümüz yazılım teknolojilerinin belkide en popüler olan konularından biriside paralel programlamadır(Parallel Programming). Özellikle kullanıcı bilgisayarlarının artık birden fazla çekirdeğe sahip işlemcilerle donatılmış olduğu düşünüldüğünde geliştirme ortamlarının da(.Net Framework 4.0' da olduğu üzere Wink ) paralel programlamaya daha fazla destek vermeye başladığını görmekteyiz.

01.01.2013

Yazar: Burak Selim Şenyurt (Google+)

Kategori: C#.Net

2943

Merhaba Arkadaşlar,

Günümüz yazılım teknolojilerinin belkide en popüler olan konularından biriside paralel programlamadır(Parallel Programming). Özellikle kullanıcı bilgisayarlarının artık birden fazla çekirdeğe sahip işlemcilerle donatılmış olduğu düşünüldüğünde geliştirme ortamlarının da(.Net Framework 4.0' da olduğu üzere Wink ) paralel programlamaya daha fazla destek vermeye başladığını görmekteyiz. Aslında zaten var olan araçlar ile paralel programlama tekniklerini uygulayabilmekteyiz. Ne varki kodlanmasının karmaşık olması bir yana, birden fazla tekniğin kullanılabiliyor olması, hangisinin daha performanslı olduğunun anlaşılması için test aşamalarının da önemini ortaya çıkarmakta. Microsoft cephesi bir süredir, paralel programlama kütüphanesi ile söz konusu tekniklere ait tasarımları aza indirgeyip kolay geliştirilebilir ve performanslı sonuçlar üreten tiplerin tasarlanması ve geliştirilmesini gereçekleştirmekte. .Net Framework 4.0 içerisinde doğrudan gelen Task Parallel Library kütüphanesi bu anlamda önemli kabiliyetler içermekte.

Peki elimizde bu kütüphane olmasaydı? Sealed O zaman n sayıda tekrar edecek olan bir işlemi paralel hale getirmek için nasıl bir kodlama yapmamız gerekirdi?

Söz gelimi başlangıç ve bitiş değerleri parametrik olan bir döngünün içerisinden çağırılan bir fonksiyonun, birden fazla Thread' e bölünerek çalıştırılmasını istediğimizi düşünelim. Aslında teorik olarak makinede kaç işlemci yada kaç çekirdek var ise o sayıda Thread açılması tercih edilir. Buna göre tekrar edecek olan işlemler belirli aralıklara bölünerek bu aralıkların açılan Thread' ler tarafından ele alınması sağlanır. Ne demek istediğimi aşağıdaki örnek kod parçası ile aktarmaya çalışayım.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Parallelism
{
    class Program
    {
        static void Main(string[] args)
        {
            ParallelFor(48, 98,
                (i) =>
                {
                    double r = 0;
                    for (int j = 0; j < i * 99999; j++)
                        r = Math.Sqrt((i * Math.PI) / Math.E);
                    Console.Write("{0} ", i.ToString());
                }
            );

            Console.ReadLine();
        }

        static void ParallelFor(int lowerBound, int upperBound, Action<int> body)
        {
            int processorCount = Environment.ProcessorCount; // İşlemci/çekirdek sayısı bulundu
            int range = (upperBound - lowerBound) / processorCount; // Yaklaşık iterasyon sayısı hesaplanır.
            Console.WriteLine("İşlemci/Çekirdek Sayısı : {0} , Iterasyon Boyutu {1}\n", processorCount.ToString(), range.ToString());

            #region Birinci Yöntem (List<Thread> Kullanımı)

            List<Thread> threads = new List<Thread>(processorCount); // İşlemci/çekirdek sayısı kadar Thread taşıyacak koleksiyon tanımlanır.

            // İşlemci/çekirdek sayısı kadar çalışacak bir döngü
            for (int processor = 0; processor < processorCount; processor++)
            {
                // Thread tarafından ele alınacak değer aralığı hesaplanır
                int startPoint = (processor * range) + lowerBound;
                int endPoint = (processor == processor - 1) ? upperBound : startPoint + range;
                Console.WriteLine("Start : {0} End : {1}", startPoint.ToString(), endPoint.ToString());
                // Her bir çekirdek için bir Thread oluşturulur ve içerisinde iterasyon aralığı uzunluğunda bir döngü oluşturularak parametre olarak gelen fonksiyon çalıştırılır
                threads.Add(new Thread(() =>
                    {
                        for (int i = startPoint; i < endPoint; i++)
                        {
                            body(i);
                        }
                    }
                )
                );
            }

            // Thread' ler çalıştırılır
            foreach (Thread t in threads)
            {
                t.Start();
            }
            // Thread' lerin tamamlanması beklenir
            foreach (Thread t in threads)
            {
                t.Join();
            }
            #endregion
        }
    }
}

Örneğimizde tamamen anlamsız olan bir döngü çalıştırıldığını görmektesiniz. İçerdiği bazı hesaplamalar sayesinde zaman alan bir işlemler bütünü söz konusu. Burada söz konusu olan operasyonun birden fazla Thread' e bölünerek çalıştırılması içinde ParallelFor isimli yardımcı metoddan yararlanılmaktadır. Bu modelde ParallelFor isimli metod döngünün başlangıç ve bitiş değerlerini almakta, ayrıca çalıştıracağı fonksiyonu işaret eden Action<T> tipinden bir parametre almaktadır. Metoda göre Thread' lerin değerlendireceği aralıklar hesaplanır. Thread' ler basit bir List<T> koleksiyonunda tutulmakta olup çalıştırılmaları ve tamamlanmalarının beklenmeleri için iki foreach döngüsünden yararlanılır. İlk döngü oluşturulan Thread' leri başlatırken diğeride oluşturulan Thread' leri Main Thread' e katıp uygulamanın sonlanması için söz konusu Thread' lerin işlerinin bitirilmesinin beklenmesini garanti etmektedir. Dikkat edilmesi gereken nokta işlemci/çekirdek sayısı kadar Thread oluşturulması ve oluşturulan her bir Thread' in yaklaşık olarak hesap edilen iterasyon alanı kadar değeri hesaba katarak Action<T> ile gelen operasyonu çalıştırmasıdır.

Peki çalışma zamanındaki durum nedir?

Bu konuda çok şanslıyız nitekim Visual Studio 2010 ile birlikte son derece etkili performans analiz araçları gelmekte. Geliştirmeyi yapmakta olduğumuz Visual Studio 2010 Ultimate Beta 2 sürümünde yer alan Concurrency Profiler raporuna bakıldığında, yukarıdaki örnek için aşağıdaki sonuçların elde edildiği görülür.

İlk çalışmanın sonucu oluşan ekran görüntüsü;

İlk çalışma sonucu elde edilen Concurrency Profiler çıktısı;

Sarı alanlar bir Thread' in çalışmakta olduğunu ama diğer bir Thread tarafından o süre boyunca etkisizleştirildiğini göstermektedir. Yeşil renkli alanlar Thread' in işini yaptığı zaman aralıklarıdır. Sarı bölgelerin fazla olması performansı olumsuz yönde etkileyen bir faktördür. Nitekim aşırı talebin(Oversubscription) oluştuğunu göstermektedir. Peki iyileştirmenin bir yolu olabilir mi? Aslında ThreadPool tipinden yararlanarak Therad yönetiminin sisteme bırakılması sağlanabilir. İşte buna göre yazılan yeni modelimiz;

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Parallelism
{
    class Program
    {
        static void Main(string[] args)
        {
            ParallelFor(48, 98,
                (i) =>
                {
                    double r = 0;
                    for (int j = 0; j < i * 99999; j++)
                        r = Math.Sqrt((i * Math.PI) / Math.E);
                    Console.Write("{0} ", i.ToString());
                }
            );

            Console.ReadLine();
        }

        static void ParallelFor(int lowerBound, int upperBound, Action<int> body)
        {
            int processorCount = Environment.ProcessorCount; // İşlemci/çekirdek sayısı bulundu
            int range = (upperBound - lowerBound) / processorCount; // Yaklaşık iterasyon sayısı hesaplanır.
            Console.WriteLine("İşlemci/Çekirdek Sayısı : {0} , Iterasyon Boyutu {1}\n", processorCount.ToString(), range.ToString());

            #region İkinci Yöntem (ThreadPool)

            int remainingProcessor = processorCount;
            // ManualResetEvent bir olay meydana geldiğinde beklemekte olan bir veya daha çok Thread' e bilgilendirmede bulunur.
            ManualResetEvent manuelResetEvent = new ManualResetEvent(false);
            for (int processor = 0; processor < processorCount; processor++)
            {
                int startPoint = (processor * range) + lowerBound;
                int endPoint = (processor == processorCount - 1) ? upperBound : startPoint + range;

                // ThreadPool, Thread' ler için bir havuz sağlar ve asenkron işleyişin yönetimini sağlar
                // QueueUserWorkItem yürütülmek üzere bir metodu kuyruğa atar.ThreadPool içerisindeki ilgili thread kullanılabilir olduğunda da metod icra edilir.
                ThreadPool.QueueUserWorkItem((o) =>
                    {
                        for (int i = startPoint; i < endPoint; i++)
                        {
                            body(i);
                        }
                        // Birden fazla Thread tarafından kullanılan remainingProcessor değeri azaltılır ve 0 olup olmadığı kontrol edilir. Eğer 0 ise bekleyen tüm Thread' ler için sinyal verilir
                        if (Interlocked.Decrement(ref remainingProcessor) == 0)
                            manuelResetEvent.Set();
                    }
                );

            }
            // Diğer Thread' ler tamamlanıncaya kadar(ki Set dolayısıyla sinyal geldiğinde anlaşılır) ana thread' i bekletecektir.
            manuelResetEvent.WaitOne();
            manuelResetEvent.Close(); // Güncel WaitHandle ile alakalı tüm kaynaklar serbest bırakılır(Release).

            #endregion
        }
    }
}

Bu sefer ThreadPool tipinin QueueUserWorkItem static metodu kullanılmıştır. ThreadPool bir önceki modele göre Thread yönetimini daha iyi yapmaktadır. Öyleyse yeni modele göre oluşan çalışma zamanı Thread analizine bir bakalım.

İkinci modele göre çalışma sonucu;

İkinci modele göre Concurrency Profiler çıktısı;

Bu rapora göre Thread' lerin toplam çalışma sürelerinin bir önceki modele göre azaldığı görülmektedir. Sarı alanların süresi daha az görünsede sayıları yinede çok azalmış değildir. Dolayısıyla aşırı talep(Oversubscription) durumu devam ediyor görünmektedir. Ancak ana Thread' in sadece Thread' lerin çalışması tamamlanıncaya kadar bloklandığı gözlemlenmektedir. Peki yeni bir yöntem tercih edilebilir mi? Evet edilebilir. Aslında ThreadPool kullanımının iyileştirilmesi yoluna gidilebilir ki biz daha fazla ilerlemeyeceğiz...

Gördüğünüz üzere çoğu geliştirici açısından ileri seviyede kalan bir kodlama gerekmektedir. Özellikle geliştiricinin Thread konusuna son derece iyi hakim olması şarttır. Her ne kadar söz konusu karmaşık teknikler birer tasarım kalıbı olarak şekillenmiş olsalarda geliştiricinin kafa ayarını da fazla çizdirmemek gerekir. Buda yazımızın neden kafayı çizmiş bir bilgisayarcı resmi ile başladığının ispatıdırLaughing İşte Task Parallel Library ile birlikte gelen tipler bu anlamda işleri kolaylaştırmaktadır. Ama tabiki Concurrency Profiler ile üretilen rapor sonuçlarını değerlendirmek gerekir.(Bu tip karmaşık teknikleri tercih ederken kişisel görüşüme göre programcının performans mı? kolay ve hızlı kodlama mı? sorusuna verdiği cevap büyük önem kazanmaktadır) İşte aynı süreç için Parallel.For kullanımı ve rapor sonuçları;

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Parallelism
{
    class Program
    {
        static void Main(string[] args)
        {
            Parallel.For(48, 98, (i) =>
                {
                    double r = 0;
                    for (int j = 0; j < i * 99999; j++)
                        r = Math.Sqrt((i * Math.PI) / Math.E);
                    Console.Write("{0} ", i.ToString());
                }
            );

            Console.ReadLine();
        }
    }
}

Parallel.For kullanımının sonucu;

Parallel.For kullanımına göre Concurrency Profiler çıktısı;

Bu rapora göre Thread işlemlerinin tamamlanma süresinin çok daha azaldığı görülmektedir. Ayrıca Sarı alanların sayısında belirgin ölçüde azalma gözlemlenmektedir. İlginç olan noktalardan biriside Main Thread' de bloklanmanın(Kırmızı alanlar) diğer modellere göre çok daha az sayıda olmasıdır. Bir başka deyişle aşırı talep(Oversubscription) durumu biraz daha azalmıştır.

Raporlar ile ilişkili not: Döngülerin çalışma zamanında açtıkları Thread' lerin çalışma şeklini raporlamak amacıyla Visual Studio 2010 ile birlikte gelen Debug menüsündeki Start Peformance Analysis öğesi kullanılmaktadır. Bu öğe ile açılan sihirbazda bizim örneğimiz için Concurrency seçeneği işaretlenmelidir. Ayrıca bu seçeneğin alt seçimi olan Visualize the behavior of multithreaded application kutucuğunun işaretlenmiş olması da gerekmektedir. Ancak bu son seçenek Windows 7, Server 2008 işletim sistemleri üzerinde kullanılabilmektedir. Raporların oluşturulması programın çalıştırılması ile birlikte başlamaktadır. Bu nedenle söz konusu analiz raporlarının üretilmesi zaman alabilir. Raporlarda n sayıda Thread' in görülmesi mümkündür. Örneklerimizdeki analizlerimizi kolayca incelemek için sadece ilgili Thread' lerin çalışma zamanı durumları göz önüne alınmıştır. Diğerleri ise gizlenmiştir. Üretilen analiz raporundaki Threads kısmında yer alan renklerin belirli anlamları vardır. Sarı renkler Preemption olarak adlandırılmakta olup genellikle aşırı talep(Oversubscription) ile ilişkili süreleri belirtmektedir. Yeşil alanlar Thread' in iş yaptığını gösteren zaman aralıkları iken kırmızı alanlar bloklama yapılan zaman aralıklarını ifade etmektedir.

Tabiki bu test sonuçları, uygulamanın çalıştığı sistemin donanımsal özelliklerine göre değişiklik gösterecektir. Ancak sonuç olarak Parallel.For döngüsünün paralel işlemleri daha efektif olarak yürüttüğünü düşünebiliriz. Bunlara ek olarak aslında Parallel.For döngüsünün sağladığı başka avantajlarda vardır. Bunlar aşağıda listelenmiştir.

  • Etkili Yük Dengelemesi (Load Balancing) : Parallel.For Thread' ler arasındaki yük dağılımını organize eder.
  • Dinamik Thread Sayısı : Parallel.For akılldır ve zaman aşımları durumunda döngü içerisindeki Thread sayılarını dinamik olarak ayarlayabilir.
  • Yüksek Değer Aralıkları : Parallel.For metodu Int32 dışında Int64 tipini de kullanılabilir.
  • Konfigurasyon Seçenekleri : Örneğin Parallel.For içerisinde açılacak olan Thread sayısı için limit belirlenebilir.
  • İstisna Yönetimi (Exception Handling) : Döngü içerisinde bir istisna oluştuğunda, dahil olan tüm Thread' ler mümkün olduğunca kısa sürede işlemlerini durdururlar. Aslında varsayılan olarak yeni iterasyonların başlaması durdurulur. Bu nedenle exception sonrası Thread' lerin yürüttüğü bazı iterasyon adımları devam edebilir ancak yenilerinin başlatılması exception nedeniyle engellenir.
  • İç içe paralellik (Nested Parallelism) :İç içe çalıştırılan Parallel.For döngüleri birbirlerinin Thread kaynaklarını koordineli olarak paylaşarak çalışırlar.
  • vb...

Şimdi bu avantajları kendi yazdığımız ParallelFor metodu içinde gerçellemeye çalıştığımızı düşünelim. Hatta deneyin Wink Böylece geldik bir yazımızın daha sonuna. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.

TaskParallelLibrary.rar (89,38 kb)

Yazar Hakkında

Burak Selim Şenyurt

Burak Selim Şenyurt

buraksenyurt.com

Yıldız Teknik Üniversitesi Matematik Mühendisliği mezunu olan Şenyurt, 1999 yılında profesyonel olarak adım attığı yazılım dünyasında, 2003 yılından beri Microsoft .Net teknolojileri ile ilgilenmektedir. Yazılım hayatına Assist Line isimli Call Center firmasında Delphi programcısı olarak başlayan Şenyurt sonrasında, sırasıyla Bizitek(Junior Developer), Netron(Master Trainer), Citibank(Outsource Senior Software Developer), Innova(Application Development Consultant), ve TCM(Software Architect) firmalarında görev almıştır. Su anda ING Bank bünyesinde Kıdemli Yazılım Danışmanı olarak görev yapmaktadir. 2006, 2007 yıllarında C#, 2008,2009,2010 yıllarında ise Connected System Developer kategorisinde Microsoft MVP seçilen Şenyurt, evli ve 1 çocuk babasıdır. C# diline olan düşkünlüğü, oğluna S(h)arp adının verilmesinde önemli bir etken olmustur.

Sosyal Medya

ORANLAR

  • 2943izleme

Arkadaşlarınla Paylaş

  • Tweet

0 Yorum

Yorum Yaz / Soru Sor

Lütfen yorum yazmak veya soru sormak için üye girişi yapınız.

Son Yorumlar

  • Hocam Link başka sayfaya yönlendiriyor.
  • merhaba benim merak ettiğim bir konu var y...
  • Merhaba download linki çalışmıyor. Rica et...
  • Nevzat Bey selamlar, Açıkçası bizler a...
  • Parametreleri Cache İşleminden Yalıtma kon...

En Güncel Sorular

  • Bilgilendirme maili (C#.Net)
  • Power Pivot (Sharepoint 2010)
  • BigInteger, BigDecimal (Asp.Net ve Asp.Net MVC)
  • visual C# ile asp nette veritabanı islemleri (Asp.Net ve Asp.Net MVC)
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ? (Sharepoint 2010)

En Son Cevap Verilen Sorular

  • Bilgilendirme maili
  • BigInteger, BigDecimal
  • visual C# ile asp nette veritabanı islemleri
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ?
  • txt dosyasına veri yazma

Twitter

Takip et: @yazilim_dilleri

En Çok Okunanlar

Elif BAYRAKDAR

C# ile SQL Server Bağlantısı, Insert, Update ve Delete Sorguları

23.05.2013

  • 120152
  • 0
Hakan Keskin

C# ile Windows Service Projesi Oluşturma, Debug Etme ve Setup Hazırlama

17.12.2013

  • 65269
  • 0
batuhan avlayan

Php - Mail Gönderme (İletişim Formu)

02.09.2013

  • 48392
  • 0

Sponsorlar

KODLAB
Pluralsight
Exchange server is
Office 365
YAZILIM DİLLERİ
Yukarı Çık
  • Hakkımızda
  • Facebook
  • Twitter
  • RSS

© Yazılım Dillerinin Buluşma Noktası | Kaynak belirtildiği sürece makaleler kopyalanabilir.
YazilimDilleri.Net sitesinde yer alan kullanıcıların oluşturduğu tüm içeriklerin yayınlanması ile ilgili yasal yükümlülükler içeriği oluşturan kullanıcıya aittir, YazilimDilleri.Net hiçbir şekilde sorumlu değildir.

Kapat

Giriş Yap

Kullanıcı Adı

Şifre

Şifremi Unuttum

KULLANICI GİRİŞİ