Skip to content
Snippets Groups Projects
Commit 647ecb72 authored by Meyjan's avatar Meyjan
Browse files

Updated documentation and revised code a bit

parent c13bde93
Branches
No related tags found
No related merge requests found
......@@ -33,66 +33,64 @@ Paralel Dijkstra:
| NIM | Nama | Pembagian Tugas |
|-----|------|-----------------|
|13517050 | Christopher Billy Setiawan | Paralelisasi, Makefile, Laporan|
|13517131 | Jan Meyer Saragih | Paralelisasi, |
|13517131 | Jan Meyer Saragih | Paralelisasi, File save, Laporan|
## <u>Deskripsi Solusi</u>
Solusi paralel yang dikerjakan adalah dengan membagi tugas algoritma Djikstra. Jadi processor menerima sejumlah node yang harus diberikan hasil dari algoritma dijkstra-nya. Hasilnya diberikan kepada node root yang nanti akan mengumpulkan semua hasilnya dan dituliskan ke dalam file.
Jadi paralelisasi yang dilakukan adalah paralelisasi data (*data parallelism*). Alasannya adalah data dibagi-bagi kepada processor-processor yang ada untuk diproses sebelum dikumpulkan kembali di node master untuk dituliskan ke file.
Solusi paralel yang dikerjakan adalah paralelisasi data (*data parallelism*). Alasannya adalah data dibagi-bagi kepada thread-thread yang ada untuk diproses.
File yang dihasilkan ada 2 buah:
- *graph.txt* yang merupakan file yang berisi graph yang di-*generate*
- *result.txt* yang merupakan hasil algoritma Dijkstra.
Solusi dilakukan pertama kali dengan meng-*generate* graph pada setiap processor. Graph yang dihasilkan pada tiap processor pasti sama dikarenakan seed untuk srand yang sama.
Jadi, setelah semua graph selesai di-*generate*, maka perhitungan waktu dimulai. Waktu hanya dihitung dari node ke-0.
Pembagian tugas setiap node adalah sebagai berikut:
- Node 0 (*root*) berfungsi sebagai node yang menerima semua hasil perhitungan Dijkstra dari node lain
- Node lain berfungsi untuk menjalankan algoritma Dijkstra, lalu mengirimkan hasilnya di node root.
Jadi terdapat (n - 1) node yang mengerjakan algoritma Dijkstra disebabkan karena node *root* hanya menerima hasil eksekusi Dijkstra. Setelah semua hasil dari Dijkstra diterima oleh node *root*, maka hasilnya akan dituliskan pada file *result.txt*.
Solusi dilakukan pertama kali dengan meng-*generate* graph. Setelah itu, perhitungan waktu dimulai. Waktu hanya dihitung dari node ke-0. Setiap thread berfungsi untuk menangani sejumlah {jumlah size} / {jumlah thread} proses Dijkstra. Dengan demikian, setiap thread melakukan algortima Dijkstra.
Setelah semua proses Dijkstra diselesaikan oleh setiap thread, maka hasilnya akan dituliskan pada file *result.txt*.
Terdapat pengecualian, yaitu saat jumlah node hanya 1. Di saat seperti itu, maka cara solusi yang digunakan adalah dengan menggunakan Dijkstra serial.
## <u>Analisis Solusi</u>
Kelebihan dari solusi ini adalah:
- Dipastikannya ada node yang menerima hasil MPI_Send. Dengan demikian, setiap hasil MPI_Send yang diberikan oleh node selain *root* pasti ditangani oleh node *root*.
- Lebih cepat setup karena graph sudah diinstansiasi terlebih dahulu dan tidak menggunakan malloc untuk graph awal dan graph solusi.
- Dari segi proses, lebih hemat pada sisi memori karena melakukan malloc dan free.
- Waktu lebih cepat daripada proses yang membutuhkan malloc dan free
- Membagi task sama rata kepada setiap thread
Kelemahan dari solusi ini adalah:
- Utilisasi processor yang tidak maksimal.
- Boros memori saat setup (graph yang digunakan pasti berukuran 3000 x 3000 karena sudah diset dari awal), tidak menggunakan malloc dan free.
- Tidak terlalu cepat dalam prosesnya karena malloc digunakan pada passing parameter di MPI_Send dan MPI_Receive.
- Graph dibuat oleh semua processor (tidak menggunakan MPI_Broadcast untuk graph).
- Utilisasi memori yang tidak maksimal.
- Tidak melakukan paralelisasi dalam proses Dijkstra (*task parallelism*), hanya *data parallelism*
Terdapat beberapa perbaikan yang dapat dilakukan, yaitu:
- Melakukan inisiasi graph di node master dan melakukan broadcast untuk diterima di node lain.
- Menggunakan malloc (jika ingin keseluruhan setup dan proses hemat memori) atau menggunakan array untuk passing parameter MPI_Send (jika ingin kecepatan setup dan proses cepat)
- Melakukan paralelisasi task di Dijkstra. Paralelisasi ini sebenarnya lebih baik namun tidak terlalu berefek. Hal ini disebabkan jumlah processor yang memproses Dijkstra tidak sebanyak jumlah value yang sedang dihitung.
- Menggunakan malloc untuk inisasi graph dan result. Dengan demikian, akan menghemat memori.
- Melakukan paralelisasi task di Dijkstra. Paralelisasi ini sebenarnya lebih baik namun tidak terlalu berefek. Hal ini disebabkan jumlah thread yang memproses Dijkstra tidak sebanyak jumlah value yang sedang dihitung.
## <u>Jumlah thread yang digunakan</u>
Setelah pengujian yang dilakukan berulang-ulang, kami memutuskan untuk menggunakan 6 thread pada tugas ini. karena dapat dilihat dari hasil pengujian yang dilakukan, waktu terefisien dapat terlihat di pengujian paralel dengan 6 thread. Kenapa angka 6? karena tugas ini hanya memungkinkan untuk memecah task menjadi 6 proses karena hanya tersedia 6 VM instance.
### <b>Pengukuran Kinerja</b>
|Jenis Pemrosesan|Thread|Jumlah titik|Percobaan 1 (microsec)|Percobaan 2 (microsec)|Percobaan 3 (microsec)|Rata-Rata (microsec)|
|----------------|------|------------|----------------------|----------------------|----------------------|--------------------|
|SERIAL|1|100|||||
||1|500|||||
||1|1000|||||
||1|3000|||||
|PARALEL|2|100|||||
||2|500|||||
||2|1000|||||
||3|100|||||
|SERIAL|1|100|11504.00|11167.00|12010.00||
||1|500|1019503.00|990011.00|1006271.00||
||1|1000|7973299.00|8231811.00|8225954.00||
||1|3000|219673752.00|219273150.00|226677442.00||
|PARALEL|2|100|15425.00|14979.00|14923.00||
||2|500|999357.00|1027944.00|975471.00||
||2|1000|7655367.00|7979176.00|8022177.00||
||2|3000|223608979.00|221121754.00|219693503.00||
||3|100|15842.00|14773.00|15687.00||
||3|500|||||
||3|1000|||||
||4|100|||||
||3|3000|||||
||4|100|13993.00|16382.00|13646.00||
||4|500|||||
||4|1000|||||
||5|100|||||
||4|3000|||||
||5|100|13155.00|15668.00|13627.00||
||5|500|||||
||5|1000|||||
||6|100|||||
||5|3000|||||
||6|100|14748.00|13171.00|14554.00||
||6|500|||||
||6|1000|||||
||6|3000|||||
||6|3000|220053619.00|227671866.00|227737159.00||
## Analisis Perbandingan Kinerja Serial dan Paralel
Kami tidak melakukan pengukuran paralel dengan processor berjumlah 2, 3, 4, dan 5 untuk jumlah node = 3000 dikarenakan node 6 sudah ditentukan sebagai node terbaik.
......
......@@ -26,7 +26,7 @@ int processorCount;
/********************************/
// Creates a new matrix
void generateGraph (int graph[V][V], int size) {
void generateGraph (int size) {
// Randomize matrix file
srand(13517131);
int i, j;
......@@ -62,29 +62,27 @@ void printGraph(int graph[V][V], int size) {
}
// Write to file
void writeToFile(int result[V][V], int size) {
void writeToFile(int size) {
FILE *fp;
fp = fopen("out/result.txt", "w");
fp = fopen("result.txt", "w");
for (int i = 0; i < size; i++) {
for (int j = 0; j < (size - 1); j++) {
fprintf(fp, "%d\t", result[i][j]);
}
fprintf(fp, "%d\n", result[i][size - 1]);
printf("Printed line: %d out of %d\n", i, size);
}
}
void writeGraphToFile(int graph[V][V], int size) {
void writeGraphToFile(int size) {
FILE *fp;
fp = fopen("out/graph.txt", "w");
fp = fopen("graph.txt", "w");
for (int i = 0; i < size; i++) {
for (int j = 0; j < (size - 1); j++) {
fprintf(fp, "%d\t", graph[i][j]);
}
fprintf(fp, "%d\n", graph[i][size - 1]);
printf("Printed line: %d out of %d\n", i, size);
}
}
......@@ -152,9 +150,6 @@ void paralelDijkstra(int size) {
int myRank = omp_get_thread_num();
int thread_count = omp_get_num_threads();
printf("myRank = %d, thread_count = %d\n", myRank, thread_count);
printf("size = %d\n", size);
for (i = myRank; i < size; i += thread_count) {
dijkstra(graph, i, size, result[i]);
if (i == 0) {
......@@ -181,10 +176,11 @@ int main(int argc, char *argv[]) {
thread_count = atoi(argv[2]);
printf("Execution execution (processor = %d)\n", thread_count);
generateGraph(graph, size);
generateGraph(size);
printf("Writing graph to graph.txt\n");
writeGraphToFile(graph, size);
writeGraphToFile(size);
printf("Finished writing graph.txt\n");
begin = clock();
printf("Begin execution\n");
......@@ -202,7 +198,8 @@ int main(int argc, char *argv[]) {
printf("Time elapsed: %.2f microseconds\n", ((double)(end -begin) * 1000000 / CLOCKS_PER_SEC));
printf("Writing result to result.txt\n");
writeToFile(result, size);
writeToFile(size);
printf("Finished writing result.txt\n");
return 0;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment