Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (24)
# Announcement
# Petunjuk Penggunaan Program
Gunakan command "make" untuk melakukan kompilasi dan menjalankan program. Lalu ketik './dijk N' pada terminal dengan N adalah jumlah Node.
Beberapa file yang harus ada dalam repositori tersebut diantaranya:
* Direktori src yang berisi source code yang anda buat.
* File output yang berisi hasil uji dijkstra algorithm pada data uji.
* Makefile. Buatlah sehingga kompilasi program dapat dilakukan hanya dengan pemanggilan command ’make’ saja.
* File README.md yang berisi:
* Petunjuk penggunaan program.
* Pembagian tugas. Sampaikan dalam list pengerjaan untuk setiap mahasiswa. Sebagai contoh: XXXX mengerjakan fungsi YYYY, ZZZZ, dan YYZZ.
* Laporan pengerjaan, dengan struktur laporan sesuai dengan deskripsi pada bagian sebelumnya.
# Pembagian Kerja
- Muhammad Rizki Fonna (13516001) : Create matrix, dijkstra, output file, analisis, dan laporan
- Arnold Pangihutan Sianturi (13517022) : Dijkstra, makefile, hitung waktu, analisis, dan laporan
# Deskripsi solusi paralel
Algoritma dijkstra diparalelisasi menggunakan OpenMP API. Algoritma menggunakan parallel region dan node pada graf/matriks dibagi dalam beberapa thread. Hasilnya membutuhkan direktif OpenMP seperti critical, single, dan barrier.
# Analisis solusi
OpenMP menghemat lama eksekusi kode program, di mana waktu eksekusi akan tergolong lebih cepat. Dari kode yang telah kami kerjakan, kami menganalisis bahwa program bekerja lebih cepat dibanding program serial. Namun, dari hasil pekerjaan ini, masih terdapat kekurangan, sehingga belum maksimal. Misal, tidak bisa mengeksekusi lebih dari 1000 nodes karena akan mengakibatkan segemntation fault.
# Jumlah thread yang digunakan dan solusi terhadap kinerja yang lebih baik
Jumlah thread yang digunakan adalah 2 thread yang menghasilkan kinerja terbaik
# Pengukuran kinerja
Pada input 100 node, didapatkan waktu eksekusi sebesar 93.83 ms, 75.916 ms, 91.24 ms.<br></br>
![](./img/100 nodes.png)
Pada input 500 node, didapatkan waktu eksekusi sebesar 3722.102 ms, 3770.408 ms, dan 3751.154 ms.<br></br>
![](./img/500 nodes.png)
Pada input 1000 node, didapatkan waktu eksekusi sebesar 24688.844 ms, 24592.925 ms, dan 24842.796 ms.<br></br>
![](./img/1000 nodes.png)
# Analisis kinerja algoritma seri dan paralel
Setelah melakukan eksekusi program, didapatkan bahwa algoritma paralel dapat dieksekusi dengan lebih cepat dibandingkan dengan algoritma seri apabila dilakukan pemilihan jumlah thread yang tepat.
File added
img/100 nodes.png

52.7 KiB

img/1000 nodes.png

62.3 KiB

img/500 nodes.png

52 KiB

This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# include <stdlib.h>
# include <stdio.h>
# include <time.h>
# include <omp.h>
# define NV 3000
# define inf 99999
// main
int main ( int argc, char **argv);
// algoritma dijkstra pakai openmp
int *dijkstra_algorithm (int path_mat[NV][NV], int i_node, int N);
// algoritma untuk mencari jarak terdekat dari node-i ke tiap-tiap node
void nearest_dist ( int s, int e, int dist_mat[NV], int connected[NV], int *d, int *v );
// inisialisasi matrix
void init_mat (int path_mat[NV][NV], int N);
void timestamp ( void );
// update nilai matriks jarak
void dist_mat_update ( int s, int e, int mv, int connected[NV], int path_math[NV][NV], int dist_mat[NV] );
/******************************************************************************/
int main (int argc, char **argv) {
int N = atoi(argv[1]);
int i, j;
int *dist_mat;
int path_mat[NV][NV];
init_mat ( path_mat, N );
int x, y;
int result_mat[N][N];
clock_t begin = clock();
for (x=0; x<N; x++){
dist_mat = dijkstra_algorithm(path_mat, x, N);
for (y=0; y<N; y++){
result_mat[x][y]= dist_mat[y];
result_mat[y][x]= dist_mat[y];
}
for(int i=0; i<N; i++)
dist_mat[i] = 0;
}
clock_t end = clock();
double time_spent = (double)((end - begin)*1000) / CLOCKS_PER_SEC;
FILE* fp;
fp = fopen("output.txt", "w");
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (j == N - 1)
{
fprintf(fp, "%d\n", result_mat[i][j]);
}
else
{
fprintf(fp, "%d ", result_mat[i][j]);
}
}
}
free ( dist_mat );
printf("Algorithm took %f ms to be executed.\n", time_spent);
return 0;
}
/******************************************************************************/
int *dijkstra_algorithm (int path_mat[NV][NV], int i_node, int N) {
int *connected;
int i;
int md;
int *dist_mat;
int mv;
int my_first;
int my_id;
int my_last;
int my_md;
int my_mv;
int my_step;
int nth;
connected = ( int * ) malloc ( N * sizeof ( int ) );
i=0;
if(i<i_node){
for (i=0; i<i_node; i++)
connected[i] = 0;
}
connected[i_node] = 1;
for ( i = i_node+1; i < N; i++ )
{
connected[i] = 0;
}
/*
Initial estimate of minimum distance is the 1-step distance.
*/
dist_mat = ( int * ) malloc ( N * sizeof ( int ) );
for ( i = 0; i < N; i++ )
{
dist_mat[i] = path_mat[i_node][i];
}
/*
Begin the parallel region.
*/
# pragma omp parallel private ( my_first, my_id, my_last, my_md, my_mv, my_step ) \
shared ( connected, md, dist_mat, mv, nth, path_mat )
{
my_id = omp_get_thread_num ( );
nth = omp_get_num_threads ( );
my_first = ( my_id * N) / nth;
my_last = ( ( my_id + 1 ) * N) / nth - 1;
# pragma omp single
{}
for ( my_step = 1; my_step < N; my_step++ )
{
# pragma omp single
{
md = inf;
mv = -1;
}
nearest_dist ( my_first, my_last, dist_mat, connected, &my_md, &my_mv );
# pragma omp critical
{
if ( my_md < md )
{
md = my_md;
mv = my_mv;
}
}
# pragma omp barrier
# pragma omp single
{
if ( mv != - 1 )
{
connected[mv] = 1;
}
}
# pragma omp barrier
if ( mv != -1 )
{
dist_mat_update ( my_first, my_last, mv, connected, path_mat, dist_mat );
}
#pragma omp barrier
}
# pragma omp single
{}
}
free ( connected );
return dist_mat;
}
/******************************************************************************/
void nearest_dist ( int s, int e, int dist_mat[NV], int connected[NV], int *d, int *v ) {
int i;
*d = inf;
*v = -1;
for ( i = s; i <= e; i++ )
{
if ( !connected[i] && ( dist_mat[i] < *d ) )
{
*d = dist_mat[i];
*v = i;
}
}
return;
}
/******************************************************************************/
void init_mat (int path_mat[NV][NV], int N) {
int i, j;
srand(13516001);
// #pragma omp parallel for num_threads(10)
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (i == j)
{
path_mat[i][j] = 0;
}
else if (path_mat[i][j] > 800) {
path_mat[i][j] = inf;
path_mat[j][i] = inf;
}
else {
int temp = rand() % 1000;
path_mat[i][j] = temp;
path_mat[j][i] = temp;
}
}
}
return;
}
/******************************************************************************/
void timestamp ( void ) {
# define TIME_SIZE 40
static char time_buffer[TIME_SIZE];
const struct tm *tm;
time_t now;
now = time ( NULL );
tm = localtime ( &now );
strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
printf ( "%s\n", time_buffer );
return;
# undef TIME_SIZE
}
/******************************************************************************/
void dist_mat_update ( int s, int e, int mv, int connected[NV], int path_mat[NV][NV], int dist_mat[NV] ) {
int i;
for ( i = s; i <= e; i++ )
{
if ( !connected[i] )
{
if ( path_mat[mv][i] < inf )
{
if ( dist_mat[mv] + path_mat[mv][i] < dist_mat[i] )
{
dist_mat[i] = dist_mat[mv] + path_mat[mv][i];
}
}
}
}
return;
}
\ No newline at end of file
output: dijkstra_openmp.c
gcc -g -Wall -o dijk dijkstra_openmp.c -fopenmp