Parallel | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar parallel

Şubat 2010 Seminerleri / C# 4.0 Yenilikleri – 2

19 February 2010 2 yorum

BilgeAdam Kadıköy Şubesinde gerçekleştirdiğim Şubat Seminerlerinin ikincisinin prezentasyonuna ve proje kodlarına buradan erişebilirsiniz.

Bu seminerde değindiğim konular;

  • Dynamics (DLR)
  • Lazy Sınıfı
  • COM İyileştirmeleri
  • Task Parallel Library (TPL)
  • ASP.NET 4.0 Yenilikleri
  • SEO İyileştirmeleri
  • Dynamic Data Web Site

Powerpoint Prezentasyonu

Visual Studio 2010 Kodları

C# ile Dizi Bölümleme

30 December 2009 Yorum yapılmamış

Bilgeadam’da öğrencilerimden birinin sorduğu soru üzerine, bir dizinin, belli sayıda elemanlardan oluşan alt dizilere bölünmesi ile ilgili aşağıdaki uygulamayı yazdım.

Uygulama şöyle çalışıyor; rastgele kelimelerden oluşan bir dizimiz var, bu diziyi, n elemanlı alt dizilere bölmek istiyoruz.

Hemen kolları sıvayalım ve kod yazmaya başlayalım.

Öncelikle rastgele kelime oluşturma fonksiyonunu yazalım;

const string Harfler = "abcdefghijklmnopqrstuvwxyz";
Random r = new Random();

public string RastgeleKelimeUret(int HarfAdet)
{
	char[] arrReturn = new char[HarfAdet];

	Parallel.For(0, HarfAdet, iLoop => {
		arrReturn[iLoop] = Harfler[r.Next(0, Harfler.Length - 1)];
	});

	return new string(arrReturn);
}

Bu fonksiyonu C# ile Dizi Karıştırma yazımdan hatırlayacaksınız. Şimdi bu fonksiyonu kullanarak List<string> tipinde bir diziye 25 eleman dolduran kodumuzu yazalım;

List<string> BolunecekDizi = new List<string>();
Parallel.For(5, 25, iLoop => {
	BolunecekDizi.Add(RastgeleKelimeUret(iLoop));
});

Parallel For kullanarak Multi-Core ve Multi-Thread destekli kod yazdığımıza dikkat edelim. Bölümleme fonksiyonunu ExtensionMethod olarak yazacağız.

public static class ExtensionManager
{
	public static List<T>[] Bolumle<T>(this List<T> Dizi, int ParcaAdet)
	{
		if (Dizi == null)
			throw new Exception("Dizi boş olamaz..");

		if (ParcaAdet < 1)
			throw new Exception("Parça Adet 1'den küçük olamaz..");

		int DiziBoyu = (int)Math.Floor(Dizi.Count / (double)ParcaAdet) + 1;

		List<T>[] arrReturn = new List<T>[DiziBoyu];

		int Adim = 0;
		Parallel.For(0, Dizi.Count, iLoop => {
			if (iLoop % ParcaAdet == 0 && iLoop > 0)
				Adim += 1;

			if (arrReturn[Adim] == null)
				arrReturn[Adim] = new List<T>();

			arrReturn[Adim].Add(Dizi[iLoop]);
		});

		return arrReturn;
	}
}

Artık tek yapmamız gereken List<T> generic tipinde nesnelerde Bolumle() fonksiyonunu kullanmak olacak.

List<string>[] Bolumler = BolunecekDizi.Bolumle(3);

Uygulamanın kaynak kodlarını buradan indirebilirsiniz.

Code Challenge #1

17 December 2009 2 yorum

Dün Emre (nam-ı diğer kara) arkadaşımla internette gezerken, bir youtube video’suna denk geldik. Emre’nin bilgisayarındaki hosts dosyasında güncel youtube ip adresleri olmadığı için videoyu izleyemedik.

Aklımıza, youtube domainine ait ip adreslerini otomatik olarak bulacak ve hosts dosyasını güncelleyecek bir uygulama yazmak geldi. Öğle yemeğine çıkmamıza 15 dakika olduğu için, bunu bir yarışa dönüştürmeye karar verdik.

İşte Yarışmanın Kuralları;

  • youtube.com, www.youtube.com, img.youtube.com alan adlarının ve v{1-24}.lscache{1-8}.c.youtube.com formatındaki alan adlarının ip adresleri otomatik olarak çözümlenecek
  • Domain adından IP adresini çözen bir servis kullanılacak (Ben böyle bir web service bulamadım, o yüzden http://www.hcidata.info/host2ip.cgi adresindeki formu kullandık)
  • Sonuç bilgisi C:\Windows\System32\drivers\etc\ altındaki hosts dosyasına otomatik olarak yazılacak
  • Uygulamayı yazma – test etme ve çalıştırma sonucunda, ilk kimin uygulaması hosts dosyasını güncellerse kazanmış olacak

YoutubeHostDuzenleyici_2

Sizinde 15 dakikanız var, code challenge‘ımıza katılmak ister misiniz?

Benim çözümümü görmek için  Devamını oku…

Normal For ve Paralel For Döngülerinin Karşılaştırması

08 December 2009 Yorum yapılmamış

Yazdığımız uygulamaların olmazsa-olmaz’larından birisi de, for döngüleridir.

Ne kadar basit’te olsa, ne kadar karmaşık’ta olsa, mutlaka uygulamalarımızda for döngülerine ihtiyaç duyarız ve sıklıkla kullanırız.

Bu makaleyi okumaya devam etmeden önce, .Net Framework 4.0 ile birlikte gelecek olan Task Parallel Library hakkında yazdığım şu yazıyı (TPL (Task Parallel Library) – Task Class) okumanızı tavsiye ederim.

Task Parallel Library ile gelen Parallel sınıfının For methodunu kullanarak, Multi-Core destekli for döngüleri oluşturabiliriz.

Multi-Core destekli olması, Multi-CPU (birden çok CPU içeren) bilgisayarlarda, döngünün CPU’lara dağıtılabilmesini sağlıyor.

Parallel Library‘den önce for döngüsü;

//10 adımlı döngü (0 dahil, 10 hariç)
for (int iLoop = 0; iLoop < 100; iLoop++)
{
	// Yapılacak İş
}

Parallel Library ile for döngüsü;

//10 adımlı döngü (0 dahil, 10 hariç)
Parallel.For(0, 10, iLoop => {
	// Yapılacak İş
});

Parallel.For metodunu kullarak örnek bir proje hazırladım, projenin kaynak kodlarına buradan ulaşabilirsiniz.

NormalFor_ParallelFor_1

Uzun tek bir döngü yazmak yerine, içiçe iki döngü yazdım, böylece, CPU ve İşletim Sistemi’nin çok adımlı döngülerde yaptığı iyileştirmeleri bir miktar azaltmayı ve daha doğru bir sonuç elde etmeyi amaçladım.

Döngülerden bir tanesini gene de uzun tuttum (100.000.000 – Yüz Milyon Adım), böylece, eğer Framework’ün kendisi döngülerde iyileştirme yapıyorsa, bunları yakalamayı hedefledim.

Diğer döngüyü ise nispeten daha kısa (500 – Beş Yüz) tuttum.

NormalFor_ParallelFor_2

Böylece toplamda 50.000.000 (Elli Milyar) adımlı döngü oluşmuş oluyor.

Gelelim, kodlara;

private void btnNormalDongu_Click(object sender, EventArgs e)
{
	int Sayac = 0;
	Stopwatch sw = Stopwatch.StartNew();
	for (int iLoop = 0; iLoop < (int)txtTekrarAdedi.Value; iLoop++)
	{
		for (int yLoop = 0; yLoop < (int)txtDonguAdedi.Value; yLoop++)
		{
			Sayac++;
		}
	}
	sw.Stop();

	lblNormalDonguSonuc.Text = string.Format("{0:0,0} ms.", sw.ElapsedMilliseconds);
}

ve

private void btnParalelDongu_Click(object sender, EventArgs e)
{
	int Sayac = 0;
	Stopwatch sw = Stopwatch.StartNew();
	Parallel.For(0, (int)txtTekrarAdedi.Value, i => {
		Parallel.For(0, (int)txtDonguAdedi.Value, y => {
			Sayac++;
		});
	});
	sw.Stop();

	lblParalelDonguSonuc.Text = string.Format("{0:0,0} ms.", sw.ElapsedMilliseconds);
}

Teker teker butonlara bastığımızda, for döngüleri çalışacak ve sonuçları Label’larda göreceğiz.

Uygulamayı kendi bilgisayarımda çalıştırdığımda aldığım sonuçlar;

NormalFor_ParallelFor_3

Normal for döngüsü: 888.700 ms. (yaklaşık 14 dakika 48 saniye)

Paralel for döngüsü: 219.326 ms. (yaklaşık 3 dakika 39 saniye)

Aradaki fark: 75%

Uygulamayı çalıştırdığım bilgisayarın özellikleri;

NormalFor_ParallelFor_4