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.
Paralel Koşan Program Kodu:
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;
}