8kez Yığıntı

MPI ile Asal Sayıların Hesaplanması

Ahbap

Harbi Üye
Forum Üyesi
Katılım
29 Mayıs 2019
Mesajlar
8,583
Tepkime puanı
2
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.

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.

Kod:
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
#include "stdio.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ListBox1->Items->Clear();
ListBox2->Items->Clear();
if(ListBox3->Items->Count>0)
{
if(FileExists("tamam.dat"))
DeleteFile("tamam.dat");
if(FileExists("sonuc.dat"))
   DeleteFile("sonuc.dat");
 int sinir=StrToInt(InputBox("Sınır Değeri","Bulunacak Asal Sayılar İçin Sınır Değeri Giriniz",""));
 int blok=StrToInt(InputBox("Parça Bloğu","Her İşlemciye Gönderilecek Blok Sayısını Veriniz",""));
 int tut=sinir%blok;
 while(tut!=0)
 {
  Application->MessageBoxA("Sınır Değeri Blok Uzunluğuna Tam Bölünmelidir","UYARI",MB_ICONINFORMATION);
  blok=StrToInt(InputBox("Parça Bloğu","Her İşlemciye Gönderilecek Blok Sayısını Veriniz",""));
  tut=sinir%blok;
 }
 
 int proces=StrToInt(InputBox("Process Sayısı","Her İşlemciye Gönderilecek Process Sayısını Veriniz",""));
 int kontrol=proces*blok*ListBox3->Items->Count;
 while(kontrol>sinir)
 {
  String oeh="Process*Blok*Bilgisayar Sayısı(";
  oeh+=ListBox3->Items->Count;
  oeh+=")Sınırı Aşamaz";
  Application->MessageBoxA(oeh.c_str(),"UYARI",MB_ICONINFORMATION);
  proces=StrToInt(InputBox("Process Sayısı","Her İşlemciye Gönderilecek Process Sayısını Veriniz",""));
  kontrol=proces*blok*ListBox3->Items->Count;
 }
  String x="C:\\Program Files\\MPICH2\\bin\\mpiexec.exe -wdir \\\\";
  x+=Edit2->Text;
  x+="\\";
  x+=Edit3->Text;
  x+="\\";
  x+=" -hosts ";
   x+=ListBox3->Items->Count;
 x+=" ";
 for(int k=0;k<ListBox3->Items->Count;k++)
 {
 x+=ListBox3->Items->Strings[k];
 x+=" ";
 x+=proces;
 x+=" ";
 }
 
 x+=" \\\\";
 x+=Edit2->Text;
 x+="\\";
 x+=Edit3->Text;
 x+="\\";
 x+="asal.exe ";
 x+=sinir;
 x+=" ";
 x+=blok;
 
 TDateTime p=Time();
 Label7->Caption=p;
 WinExec(x.c_str(),NULL);
 bool durum=true;
while(durum)
{
 if(FileExists("tamam.dat"))
 durum =false;
}
 TDateTime h=Time();
 Label8->Caption=h;
 Label9->Caption=h-p;
 Application->MessageBoxA(x.c_str(),"MPI İFADESİ",MB_ICONINFORMATION);
ListBox1->Items->LoadFromFile("sonuc.dat");
AnsiString yazdir="Bulunan Asal Sayı Adedi: ";
yazdir+=IntToStr(ListBox1->Items->Count);
Label3->Caption=yazdir;
for(int i=0;i<ListBox1->Items->Count;i++)
{
String corsi=ListBox1->Items->Strings[i];
String nokta=".";
        int yakala=corsi.Pos(nokta);
        if(yakala!=0)
        {
         corsi.Delete(yakala,(ListBox1->Items->Strings[i]).Length());
        }
ListBox2->Items->Add(corsi);
DeleteFile("tamam.dat");
   DeleteFile("sonuc.dat");
}
}
else
Application->MessageBoxA("En Az Bir Bilgisayar İsmi Girmelisiniz","UYARI",MB_ICONINFORMATION);
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(Edit1->Text!="")
{
 ListBox3->Items->Add(Edit1->Text);
 Edit1->Text="";
}
else
Application->MessageBoxA("Lütfen Bilgisayar İsmi Giriniz","UYARI",MB_ICONINFORMATION);
}
//---------------------------------------------------------------------------


Paralel Koşan Program Kodu:

Kod:
#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;
}
 

Benzer konular

DarK

< MasaLFM.Net >
Forum Üyesi
Katılım
1 Nisan 2019
Mesajlar
666
Tepkime puanı
0
emeğine yüreğine sağlık
 

Nutella

Harbi Üye
Bayan Üye
Özel Üye
Katılım
2 Ocak 2021
Mesajlar
9,434
Tepkime puanı
8
Cinsiyet
  1. Bayan
Takım
Galatasaray
Paylaşım için teşekkürler.
 
İçerik sağlayıcı "paylaşım" sitelerinden biri olan Harbimekan.Com Forum, Eğlence ve Güncel Paylaşım Platformu Adresimizde 5651 Sayılı Kanun’un 8. Maddesine ve T.C.K’nın 125. Maddesine göre TÜM ÜYELERİMİZ yaptıkları paylaşımlardan sorumludur. Harbimekan.Com sitesindeki konular yada mesajlar hakkında yapılacak tüm hukuksal Şikayetler için info@harbimekan.com yada iletişim sayfası üzerinden iletişime geçilmesi halinde ilgili kanunlar ve yönetmelikler çerçevesinde en geç 3 Gün (72 Saat) içerisinde Forum yönetimi olarak tarafımızdan gereken işlemler yapılacaktır.

Bu Site, Bilim ve Sağlık Haber Ajansı Üyesidir.