Programlama | Programlama Dilleri | C Programlama Dili |C++

Anasayfa Programlama C++ Builder MPI ile Asal Sayıların Hesaplanması


MPI ile Asal Sayıların Hesaplanması

Bu program MPI dili ile  Asal Sayıların daha hızlı bulunması uygulamasıdır.Büyük asal değerler şifreleme
konusunda oldukça önemli olduğundan hızlı bir şekilde bulunma işlemleri sağlanmalıdır.
Asal sayılar bulunurken efektif  bir algoritma olan karekök algoritması kullanılmıştır. (Herhangi bir sayı için 1 den sayının kareköküne kadar tam olarak bölünüp bölünmediğinin kontrolü yeterli olacaktır).

Program içinde 3 adet klasor bulunmaktadır.

MPI 'in nasıl tüm bilgisayarlara nasıl kurulacağı ve gerekli ayarlar aşağıdaki linkte anlatılmıştır.

Linki Görebilmeniz İçin Üye Olmanız Gerekmektedir...

Üye Kayıt



Paralel Asal Kodları isimli klasör MPI kodunun koştuğu ve Dev-Cpp platformunda oluşturulmuştur koddur.
MPI kutuphanesinin C++ Builder'da eklenmesi problem oluşturduğundan dolayı Dev-Cpp seçilmiştir.

Görsellik İçin Koşulacak Program ve Kodları isimli klasör bulunan asal sayıları göstermek
amaçlı kullanılmıştır.

Kosulacak İsimli klasör ise programı koşma şeklimizdir. Diğer iki klasördeki exeleri bulunduran bu klasör
tam paylaşıma açarak Paralel_Bul.exe yi çalıştırınız.Çalıştırdıktan sonra programda gerekli ayarları yapınız.

Örnek Koşma:

Server Bilgisayarın Ağ Üzerindeki İsmini Giriniz: Paralel_Bul.exe yi koştuğunuz bilgisayarın ağ ismini giriniz

Tam Paylaşıma Açılacak asal.exe'nin ve Paralel_Bul.exe'nin Bulunduğu Klasörün Ağ Paylaşım Adını Giriniz:
Buda bizden indirdiğiniz dosya olan "Kosulacak" tır. Eğer paylaşım adını değiştirirseniz onu yazmanız gerekir

Bilgisayar Ağ Üzerindeki İsimlerini Giriniz:
Ağda  MPI kurulu olan bilgisayar isimleri hangilerinde koşmak istenirse bu bilgisayarların ağ isimlerini yazmaya dikkat ediniz.Server bilgisayarda da koşulması istenirse onunda ismi eklenmelidir.

Daha sonra Hesapla Butonuna Tıkladığında:

Bir sınır değeri girilir.(Hangi sayıya kadar Asallar bulunacak)
Programın her aşamasında kullanıcıyı uyaracak ve doğru bilgi girmesini sağlayacak uyarı pencereleri yapılmıştır.


Bu değerden sonra ise bilgisayarlara gönderilecek olan block uzunluğu girilir. Daha sonra ise her bilgisayarda kaç adet process koşacağı belirlenir. Bu işlemler yapılırken dikkat edilmesi gereken hususlar vardır. Örneğin sınır değeri block uzunluğuna tam olarak bölünmesi gerekir. Eğer birden fazla bilgisayar girilmişse bu durumda ise (bilgisayar sayısı*process*block) büyüklüğünün  sınır değerini geçmemesi gerekir. Bütün bu durumlar program içinde kontrol edilmiş olup kullanıcı yanlış bilgi girse bile uyarıları sağlanmış ve doğru bilgi girilmesi için kullanıcı sürekli uyarılmıştır.

Yaptığım denemelerde (2 bilgisayar üzerinde ) 10000000 ‘a kadar asalları bul dediğimde ( 50000 block uzunluğu her bilgisayarda da 3 process koşulmak kaydıyla) süre olarak 10 sn çıktığını, 1000000’a kadar asalları tek bir bilgisayarda bul dediğimde ise( 50000 block uzunluğu 3 processs) süre olarak 14 sn çıktığını gördüm.

Programın Tamamını Aşağıdaki Linkten İndirebilirsiniz

Linki Görebilmeniz İçin Üye Olmanız Gerekmektedir...

Üye Kayıt

 Programın Görsellik İçin Koşulan Kodu:

  1. //---------------------------------------------------------------------------
  2.  
  3. #include <vcl.h>
  4. #pragma hdrstop
  5.  
  6. #include "Unit1.h"
  7. #include "stdio.h"
  8. //---------------------------------------------------------------------------
  9. #pragma package(smart_init)
  10. #pragma resource "*.dfm"
  11. TForm1 *Form1;
  12. //---------------------------------------------------------------------------
  13. __fastcall TForm1::TForm1(TComponent* Owner)
  14.         : TForm(Owner)
  15. {
  16. }
  17. //---------------------------------------------------------------------------
  18.  
  19. void __fastcall TForm1::Button1Click(TObject *Sender)
  20. {
  21. ListBox1->Items->Clear();
  22. ListBox2->Items->Clear();
  23. if(ListBox3->Items->Count>0)
  24. {
  25. if(FileExists("tamam.dat"))
  26. DeleteFile("tamam.dat");
  27. if(FileExists("sonuc.dat"))
  28.    DeleteFile("sonuc.dat");
  29.  int sinir=StrToInt(InputBox("Sınır Değeri","Bulunacak Asal Sayılar İçin Sınır Değeri Giriniz",""));
  30.  int blok=StrToInt(InputBox("Parça Bloğu","Her İşlemciye Gönderilecek Blok Sayısını Veriniz",""));
  31.  int tut=sinir%blok;
  32.  while(tut!=0)
  33.  {
  34.   Application->MessageBoxA("Sınır Değeri Blok Uzunluğuna Tam Bölünmelidir","UYARI",MB_ICONINFORMATION);
  35.   blok=StrToInt(InputBox("Parça Bloğu","Her İşlemciye Gönderilecek Blok Sayısını Veriniz",""));
  36.   tut=sinir%blok;
  37.  }
  38.  
  39.  int proces=StrToInt(InputBox("Process Sayısı","Her İşlemciye Gönderilecek Process Sayısını Veriniz",""));
  40.  int kontrol=proces*blok*ListBox3->Items->Count;
  41.  while(kontrol>sinir)
  42.  {
  43.   String oeh="Process*Blok*Bilgisayar Sayısı(";
  44.   oeh+=ListBox3->Items->Count;
  45.   oeh+=")Sınırı Aşamaz";
  46.   Application->MessageBoxA(oeh.c_str(),"UYARI",MB_ICONINFORMATION);
  47.   proces=StrToInt(InputBox("Process Sayısı","Her İşlemciye Gönderilecek Process Sayısını Veriniz",""));
  48.   kontrol=proces*blok*ListBox3->Items->Count;
  49.  }
  50.   String x="C:\\Program Files\\MPICH2\\bin\\mpiexec.exe -wdir \\\\";
  51.   x+=Edit2->Text;
  52.   x+="\\";
  53.   x+=Edit3->Text;
  54.   x+="\\";
  55.   x+=" -hosts ";
  56.    x+=ListBox3->Items->Count;
  57.  x+=" ";
  58.  for(int k=0;k<ListBox3->Items->Count;k++)
  59.  {
  60.  x+=ListBox3->Items->Strings[k];
  61.  x+=" ";
  62.  x+=proces;
  63.  x+=" ";
  64.  }
  65.  
  66.  x+=" \\\\";
  67.  x+=Edit2->Text;
  68.  x+="\\";
  69.  x+=Edit3->Text;
  70.  x+="\\";
  71.  x+="asal.exe ";
  72.  x+=sinir;
  73.  x+=" ";
  74.  x+=blok;
  75.  
  76.  TDateTime p=Time();
  77.  Label7->Caption=p;
  78.  WinExec(x.c_str(),NULL);
  79.  bool durum=true;
  80. while(durum)
  81. {
  82.  if(FileExists("tamam.dat"))
  83.  durum =false;
  84. }
  85.  TDateTime h=Time();
  86.  Label8->Caption=h;
  87.  Label9->Caption=h-p;
  88.  Application->MessageBoxA(x.c_str(),"MPI İFADESİ",MB_ICONINFORMATION);
  89. ListBox1->Items->LoadFromFile("sonuc.dat");
  90. AnsiString yazdir="Bulunan Asal Sayı Adedi: ";
  91. yazdir+=IntToStr(ListBox1->Items->Count);
  92. Label3->Caption=yazdir;
  93. for(int i=0;i<ListBox1->Items->Count;i++)
  94. {
  95. String corsi=ListBox1->Items->Strings[i];
  96. String nokta=".";
  97.         int yakala=corsi.Pos(nokta);
  98.         if(yakala!=0)
  99.         {
  100.          corsi.Delete(yakala,(ListBox1->Items->Strings[i]).Length());
  101.         }
  102. ListBox2->Items->Add(corsi);
  103. DeleteFile("tamam.dat");
  104.    DeleteFile("sonuc.dat");
  105. }
  106. }
  107. else
  108. Application->MessageBoxA("En Az Bir Bilgisayar İsmi Girmelisiniz","UYARI",MB_ICONINFORMATION);
  109. }
  110. //---------------------------------------------------------------------------
  111.  
  112. void __fastcall TForm1::Button2Click(TObject *Sender)
  113. {
  114. if(Edit1->Text!="")
  115. {
  116.  ListBox3->Items->Add(Edit1->Text);
  117.  Edit1->Text="";
  118. }
  119. else
  120. Application->MessageBoxA("Lütfen Bilgisayar İsmi Giriniz","UYARI",MB_ICONINFORMATION);
  121. }
  122. //---------------------------------------------------------------------------
  123.  

Paralel Koşan Program Kodu:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <mpi.h>
#define YENI_IS 1 // Yeni iş göndermek içim
#define IS_BITTI 2 // İşin bittiğini haber vermek için
 
 
bool Asalmi(double sayi)
{
  double kok=sqrt(sayi);
  double i;
  for(i=2.0;i<=kok;i=i+1.0)
  {
    //printf("kalan: %f, sayi: %f, i: %f, kok: %f\n",fmod(sayi,i),sayi,i,kok);
    if(fmod(sayi,i)==0.0)//(sayi%i)==0.0) yemedi
      return false;
  }
  return true;
}
 
int main(int argc,char *argv[])
{
       FILE *f;
       f=fopen("sonuc.dat","a+");
  int numprocs;
  int myid;
 
  MPI_Status stat;
  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD,&myid);
 
 
  if(argc!=3 && myid==0)
  {
    printf("Kullanim: %s <Ust Sinir> <Surec Basina Is>\n");
    MPI_Finalize();
    exit(0);
  }
 
  if(argc!=3)
  {
   MPI_Finalize();
   exit(0);
  }
  double UstSinir=50;
  int ProcessBasinaIs=5;
  UstSinir=atof(argv[1]);
  ProcessBasinaIs=atoi(argv[2]);
 
  int i,j;
  double *DonenAsallar;
  int DonenAsalSayisi;
  double aralik[2];
  DonenAsallar=malloc(sizeof(double)*ProcessBasinaIs);
 
 
 
  if(myid == 0)
  {
    //Master işlemci kodu
    for(i=1;i<numprocs;i++)
    {
      aralik[0]=(i-1)*ProcessBasinaIs;
      aralik[1]=(i)*ProcessBasinaIs;
      MPI_Send(aralik,2,MPI_DOUBLE,i,YENI_IS,MPI_COMM_WORLD);
    }
    for(i=numprocs;i<=UstSinir/ProcessBasinaIs;i++)
    {
      MPI_Recv(&DonenAsalSayisi,1,MPI_INT,MPI_ANY_SOURCE,1,MPI_COMM_WORLD,&stat);
      MPI_Recv(DonenAsallar,DonenAsalSayisi,MPI_DOUBLE,stat.MPI_SOURCE,1,MPI_COMM_WORLD,&stat);
      for(j=0;j<DonenAsalSayisi;j++)
      {
   
      
       fprintf(f,"%f",DonenAsallar[j]);
       fputs("\n",f);                     
       printf("%f\n",DonenAsallar[j]);
      }
      aralik[0]=(i-1)*ProcessBasinaIs;
      aralik[1]=(i)*ProcessBasinaIs;
      MPI_Send(aralik,2,MPI_DOUBLE,stat.MPI_SOURCE,YENI_IS,MPI_COMM_WORLD);
    }
    for(i=1;i<numprocs;i++)
    {
      MPI_Recv(&DonenAsalSayisi,1,MPI_INT,MPI_ANY_SOURCE,1,MPI_COMM_WORLD,&stat);
      MPI_Recv(DonenAsallar,DonenAsalSayisi,MPI_DOUBLE,stat.MPI_SOURCE,1,MPI_COMM_WORLD,&stat);
      for(j=0;j<DonenAsalSayisi;j++)
          {
       fprintf(f,"%f",DonenAsallar[j]);
       fputs("\n",f);                         
       printf("%f\n",DonenAsallar[j]);
      }
      MPI_Send(aralik,2,MPI_DOUBLE,i,IS_BITTI,MPI_COMM_WORLD);
    }  
 
  }
  else
  {
      //Slave işlemci kodu
      bool isVar=true; //iş var
      double sayac;
      while(isVar)
      {
        MPI_Recv(aralik,2,MPI_DOUBLE,0,MPI_ANY_TAG,MPI_COMM_WORLD,&stat);
       
        if(stat.MPI_TAG!=IS_BITTI)
        {
          DonenAsalSayisi=0;
          if(aralik[0]<2)
            aralik[0]=2;
          for(sayac=aralik[0];sayac<aralik[1];sayac+=1.0)
          if(Asalmi(sayac))
          {
            DonenAsallar[DonenAsalSayisi++]=sayac;
          }
          //for(j=0;j<DonenAsalSayisi;j++)
          //  printf("%f , ",DonenAsallar[j]);         
          //printf("DAS:%d\n",DonenAsalSayisi);
          MPI_Send(&DonenAsalSayisi,1,MPI_INT,0,1,MPI_COMM_WORLD);
          MPI_Send(DonenAsallar,DonenAsalSayisi,MPI_DOUBLE,0,1,MPI_COMM_WORLD);
           
        }
        else
          isVar=false;
      }
     
  }
 
  fflush(stdout);
  MPI_Finalize();
    fclose(f);
   FILE *p;
   p=fopen("tamam.dat","a+");
   fclose(p);
 
    return 0;
}
 

Yorumlar (2)
  • Umran  - OpenMP
    Merhaba,anlatımınız için tesekkurler.İşime yaradı gerçekten.OpenMP ile asalsayıların hesabı örneğini de varsa paylaşmanızı rica ediyorum...Tesekkurler...
  • Tunahan Altıntop  - Mpi, OpenMpi
    öncelikle merhaba mpi konusunda kısıtlı kaynak olmasından ve gerçekten ilgilenilerek yapılan bu örnekten dolayı teşekkürler. openmpi ve mpi ile ilgili çeşitli dökümanlar mevcut ama genel olarak çoğu kopyalanıp yapıştırılan dökümanlar benim sorum ise şu aynı işlemleri openmpi ile linux üzerinde yapmak istersek hangi araçları hangi aşamalarda kullanmamız gerekiyor? ilgilenirseniz sevinirim.
Sadece kayıtlı kullanıcılar yorum yazabilir!
Son Güncelleme ( Perşembe, 07 Nisan 2011 23:21 )