Sinta Maresa
Summary
Message Passing Interface (MPI) adalah sebuah standar yang digunakan untuk melakukan komunikasi antara proses pada sistem komputasi paralel. MPI memungkinkan beberapa proses berjalan secara bersamaan pada banyak komputer yang terhubung dalam jaringan, dan saling berkomunikasi untuk menyelesaikan tugas-tugas yang diberikan. Dengan menggunakan MPI. program paralel dapat dibuat lebih efisien dan cepat, karena tugas yang dibagi menjadi beberapa proses dapat diselesaikan secara bersamaan.
Perkalian matriks dapat diimplementasikan dengan menggunakan program paralel untuk mempercepat waktu eksekusi. Metode program paralel dapat dilakukan dengan membagi tugas perkalian matriks ke dalam beberapa tugas kecil yang dapat dijalankan secara simultan pada beberapa prosesor atau komputer yang terhubung ke jaringan
A. Pendahuluan
Program ini merupakan implementasi MPI pada HPC dalam kasus perkalian matriks menggunakan bahasa pemrograman C. Operasi perkalian matriks melibatkan dua buah matriks yang mempunyai kolom matriks pertama yang sama dengan baris matriks kedua. Operasi dilakukan pada baris matriks pertama dengan kolom matriks kedua yang tidak bergantung pada baris dan kolom yang lain sehingga perkalian matriks ini memiliki kesempatan untuk di implementasikannya komputasi paralel
Penjalasan dan tahap-tahap dasar program:
Material dan spesifikasi yang digunakan:
B. Koding Program
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int m, n, p, q, i, j, k;
clock_t start_time, end_time;
double cpu_time_used;
printf(" --- Perkalian Matriks --- ");
// Input matriks A dan B
printf(" Masukkan jumlah baris matriks A: ");
fflush(stdout);
scanf("%d", &m);
printf("Masukkan jumlah kolom matriks A: ");
fflush(stdout);
scanf("%d", &n);
fflush(stdout);
printf("Masukkan jumlah baris matriks B: ");
fflush(stdout);
scanf("%d", &p);
printf("Masukkan jumlah baris matriks B: ");
fflush(stdout);
scanf("%d", &q);
if (n != p) {
printf("Error: jumlah baris matriks A tidak sama dengan jumlah kolom matriks. ");
return 1;
}
start_time = clock();
int A[m][n], B[p][q], C[m][q];
srand(time(NULL));
printf(" Matrix A: ");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
A[i][j] = rand()% 10;
printf("%d ", A[i][j]);
}
printf(" ");
}
printf(" Matrix B: ");
for (i = 0; i < p; i++) {
for (i = 0; i < p; i++) {
B[i][j] = rand()% 10;
printf("%d ", B[i][j]);
}
printf(" ");
}
for (i=0; i<m; i++) {
for (j=0; j<q; j++) {
C[i][j] = 0;
for (k = 0; k < n; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
end_time = clock();
// Display the resulting matrix C
printf(" Matrix C = A*B: ");
for (i=0; i<m; i++) {
for (j=0;j<q; j++) {
printf("%d ", C[i][j]);
}
printf(" ");
}
cpu_time_used = ((double) (end_time - start_time)) / CLOCKS_PER_SEC;
printf("Total waktu komputasi: %f detik ", cpu_time_used);
return 0;
}
2. Perkalian Matriks Paralel
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
// Inisialisasi MPI
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size (MPI_COMM_WORLD, &size);
int m, n, p, q, i, j, k,
double start_time, end_time, total_time;
if (rank == 0){
printf(" --- Implementasi Perkalian Matriks menggunakan Message Passing Interface pada HPC --- ");
printf(" ---------------------------------------------");
printf(" Jumlah baris matriks A = jumlah kolom matriks B ");
printf("--------------------------------------------- ");
// Input matriks A dan B
printf(" Masukkan jumlah baris matriks A: ");
fflush(stdout);
scanf("%d", &m);
printf("Masukkan jumlah kolom matriks A: ");
fflush(stdout);
scanf("%d", &n);
fflush(stdout);
printf("Masukkan jumlah baris matriks B: ");
fflush(stdout);
scanf("%d", &p);
printf("Masukkan jumlah baris matriks B: ");
fflush(stdout);
scanf("%d", &q);
if (n != p) {
printf("Error: jumlah baris matriks A tidak sama dengan jumlah kolom matriks B. ");
return 1;
}
start_time= MPI_Wtime(); // mulai merekam waktu
// processor 0 melakukan broadcast variable m, n, p dan q
MPI_Bcast(&m, 1, MPI_INT, 0, MPI_COMM WORLD);
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI Bcast(&p, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&q, 1, MPI_INT, 0, MPI_COMM WORLD);
}
Else{
// processor 1, 2 dan 3 menerima broadcast
// variable m, n, p dan q
MPI_Bcast(&m, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&p, 1, MPI_INT, 0, MPI_COMM WORLD);
MPI_Bcast(&q, 1, MPI_INT, 0, MPI_COMM WORLD);
}
// membagi baris matriks A untuk diproses lebih lanjut
// oleh semua processor
int baris_per_proses = m / size;
int A[m][n], B[p][q], C[m][q],
A_lokal[baris_per_proses][n];
B_lokal[baris_per_proses][q];
if (rank == 0){
srand(time(NULL));
for (i=0; i<m; i++) { // membuat random elemen matriks A
for (j = 0; j < n; j++) {
A[i][j] = rand()% 10;
}
}
for (i = 0; i < p; i++) { // membuat random elemen matrik B
for (j=0;j<q; j++)
{ B[i][j] = rand()% 10;
}
}
}
// processor 0 membagi ratakan baris matriks A kepada semua processor
MPI_Scatter (A, baris_per_proses*n,
MPI_INT, A lokal, baris_per_proses*n,
MPI_INT, 0, MPI_COMM_WORLD);
// processor 0 melakukan broadcast matriks B kesemua processor
MPI_Bcast(&B, p*q, MPI_INT, 0, MPI_COMM WORLD);
// melakukan operasi perkalian matriks pada masing-masing processor
for (i = 0; i < baris_per_proses; i++) {
for (j=0; j<q; j++) {
C_lokal[i][j] = 0;
for (k = 0; k < n; k++) {
C_lokal[i][j] += A_lokal[i][k] * B[k][j]; 十二
}
}
}
// processor 0 mengumpulkan semua matriks dari pekerjaan processor lain dan menjadikannya matriks C
MPI_Gather(C_lokal, baris_per_proses*q, MPI_INT, C, baris_per_proses*q, MPI_INT, 0, MPI_COMM WORLD);
if (rank == 0){
end_time = MPI_Wtime(); //berhenti merekam waktu
total_time = end_time - start_time;
printf(" Matriks A: "); //menampilkan matriks A, B dan C
for (i=0; i<m; i++) {
for (j = 0; j < n; j++) {
printf("%d ", A[i][j]);
}
printf(" ");
}
printf(" Matriks B: ");
for (i = 0; i < p; i++) {
for (j = 0; j<q; j++) {
printf("%d ", B[i][j]);
}
printf(" ");
}
printf(" Matriks C = A*B: ");
for (i=0; i<m; i++) {
for (j=0;j<q; j++) {
printf("%d ", C[ii]);
}
printf(" ");
}
}
if (rank==0){
// menampilkan total waktu eksekusi program
printf(" Total waktu komputasi: %fdetik ", total_time);
}
MPI_Finalize(); //MPI berakhir
return 0;
}
C. Hasil Keluaran Program
1. Perkalian Matriks sekuensial
2. Perkalian Matriks Paralel
D. Evaluasi Performa
Performa diuji menggunakan dimensi matriks 760x760 dengan merekam waktu komputasi sekuensial dan komputasi paralel.
2. Efisiensi
3. Cost