7
Matrix Multiplication using MPI Fariz Maulana Department of Electrical Engineering Institut Teknologi Bandung Bandung, Indonesia [email protected] AbstrakPada tugas ini akan dibuat program perkalian antara matriks dengan vektor dengan ukuran matriks yang cukup besar yaitu 25x25, 100x100, dan 1000x1000 dan ukuran vektor yang berkesesuaian. Program dibuat dalam platform komputas paralel dengan menggunakan MPI. Pemrograman parallel diimplementasikan dengan mengginakan point to point communication. Dari program yang dibuat akan dilakukan perbandingan performa dari ketiga operasi perkalian matriks dengan vektor tersebut misal dari waktu yang diperlukan untuk melakukan komputasi. Kata kunci : Komputasi paralel, MPI, point to point communication. I. PENDAHULUAN Message Passing Interface (MPI) ada suatu standar sistem penerusan pesan (message-passing) yang digunakan pada pemrograman paralel atau komputasi terdistribusi. Standar tersebut mendefinisikan sintaks dan semantik dari inti rutin pustaka (library) yang berguna untuk berbagai kalangan pengguna yang menulis program message-passing di bahasa pemrograman komputer yang berbeda-beda seperti Fortran, C, C++ dan Java. MPI bukanlah suatu bahasa pemrograman namun sebuah pustaka yang digunakan untuk membuat suatu program dipecah menjadi beberapa proses dan mengomunikasikan antar masing-masing proses menggunakan protokol yang efisien. Ada beberapa contoh MPI yang umum digunakan antara lain, MPICH, MVAPICH, OpenMPI, Microsoft MPI, dll. MPI bertugas untuk mengirim data antar komputer di dalam sistem paralel (biasa disebut sebagai node atau host). Dalam MPI terdapat terminologi job scheduler yang berfungsi menerima tugas dari user dan menjadwalkannya pada beberapa node di dalam sistem paralel. Pemrograman paralel pada program perkalian matriks ini akan diimplementasikan dengan menggunakan point to point communication pada MPI. Sebagai ilustrasi, perhatikan matriks 1 berukuran 5x4 dan matriks 2 yang berukuran 4x3. Perkalian dari kedua buah matriks ini akan menghasilkan matriks yang berukuran 5x3. Misalkan kita menginginkan perhitungan perkalian matriks ini dilakukan oleh 3 buah proses yang berbeda, maka perhitungan akan dilakukan seperti diilustrasikan pada gambar di bawah. Kita dapat membagi pekerjaan tersebut dengan menggunakan perulangan for(i = rank; i < X; i = i+size). Gambar 1. Ilustrasi perhitungan matriks secara paralel Program dibuat dengan menggunakan pustaka MPICH. MPICH dipilih karena memiliki performa yang sangat baik dan paling umum digunakan untuk implementasi MPI yang dibuktikan oleh 9 dari 10 super komputer tercepat menggunakan MPICH (Juni 2015) termasuk super komputer tercepat saat ini yaitu Tianhe-2. II. HASIL DAN ANALISIS Ada dua buah program utama yang dibuat yaitu program perkalian matriks secara paralel dan sekuensial. Untuk source code dari kedua buah program tersebut dapat dilihat pada bagian lampiran. Program perkalian matriks untuk matriks yang berukuran 25x25, 100x100, dan 1000x1000 menggunakan source code yang sama. Perbedaannya terletak pada nilai konstanta N, X, dan Y. Perhatikan potongan source code di bawah ini MPI_Init(&argc, &argv); MPI_Finalize(); Perintah di atas digunakan untuk melakukan pembuatan penghancuran proses MPI. Fungsi MPI_Init(&argc, &argv) berfungsi untuk menginisialisasi lingkungan eksekusi MPI sedangkan fungsi MPI_Finalize() akan mengakhiri lingkungan eksekusi MPI. Jika kita lupa tidak menjalankan rutin ini maka akan dimungkinkan ada proses-proses yang tersisa di memori (orphans process). MPI_Comm_size(MPI_COMM_WORLD, &size); MPIC_Comm_rank(MPI_COMM_WORLD, &rank); Fungsi MPI_Comm_size(MPI_COMM_WORLD, &size) akan menentukan jumlah proses. Variabel rank pada fungsi

Matrix Multiplication using MPI

Embed Size (px)

DESCRIPTION

Compare matrix multiplication performance between serial and parallel programming. The parallel programming implemented using Message Passing Interface.

Citation preview

Page 1: Matrix Multiplication using MPI

Matrix Multiplication using MPI

Fariz Maulana

Department of Electrical Engineering

Institut Teknologi Bandung

Bandung, Indonesia

[email protected]

Abstrak—Pada tugas ini akan dibuat program perkalian

antara matriks dengan vektor dengan ukuran matriks yang

cukup besar yaitu 25x25, 100x100, dan 1000x1000 dan ukuran

vektor yang berkesesuaian. Program dibuat dalam platform

komputas paralel dengan menggunakan MPI. Pemrograman

parallel diimplementasikan dengan mengginakan point to point

communication. Dari program yang dibuat akan dilakukan

perbandingan performa dari ketiga operasi perkalian matriks

dengan vektor tersebut misal dari waktu yang diperlukan untuk

melakukan komputasi.

Kata kunci : Komputasi paralel, MPI, point to point

communication.

I. PENDAHULUAN

Message Passing Interface (MPI) ada suatu standar

sistem penerusan pesan (message-passing) yang digunakan

pada pemrograman paralel atau komputasi terdistribusi.

Standar tersebut mendefinisikan sintaks dan semantik dari inti

rutin pustaka (library) yang berguna untuk berbagai kalangan

pengguna yang menulis program message-passing di bahasa

pemrograman komputer yang berbeda-beda seperti Fortran, C,

C++ dan Java. MPI bukanlah suatu bahasa pemrograman

namun sebuah pustaka yang digunakan untuk membuat suatu

program dipecah menjadi beberapa proses dan

mengomunikasikan antar masing-masing proses menggunakan

protokol yang efisien. Ada beberapa contoh MPI yang umum

digunakan antara lain, MPICH, MVAPICH, OpenMPI,

Microsoft MPI, dll.

MPI bertugas untuk mengirim data antar komputer di

dalam sistem paralel (biasa disebut sebagai node atau host).

Dalam MPI terdapat terminologi job scheduler yang berfungsi

menerima tugas dari user dan menjadwalkannya pada

beberapa node di dalam sistem paralel.

Pemrograman paralel pada program perkalian matriks ini

akan diimplementasikan dengan menggunakan point to point

communication pada MPI. Sebagai ilustrasi, perhatikan

matriks 1 berukuran 5x4 dan matriks 2 yang berukuran 4x3.

Perkalian dari kedua buah matriks ini akan menghasilkan

matriks yang berukuran 5x3. Misalkan kita menginginkan

perhitungan perkalian matriks ini dilakukan oleh 3 buah

proses yang berbeda, maka perhitungan akan dilakukan seperti

diilustrasikan pada gambar di bawah. Kita dapat membagi

pekerjaan tersebut dengan menggunakan perulangan for(i =

rank; i < X; i = i+size).

Gambar 1. Ilustrasi perhitungan matriks secara paralel

Program dibuat dengan menggunakan pustaka MPICH.

MPICH dipilih karena memiliki performa yang sangat baik

dan paling umum digunakan untuk implementasi MPI yang

dibuktikan oleh 9 dari 10 super komputer tercepat

menggunakan MPICH (Juni 2015) termasuk super komputer

tercepat saat ini yaitu Tianhe-2.

II. HASIL DAN ANALISIS

Ada dua buah program utama yang dibuat yaitu program

perkalian matriks secara paralel dan sekuensial. Untuk source

code dari kedua buah program tersebut dapat dilihat pada

bagian lampiran.

Program perkalian matriks untuk matriks yang berukuran

25x25, 100x100, dan 1000x1000 menggunakan source code

yang sama. Perbedaannya terletak pada nilai konstanta N, X,

dan Y.

Perhatikan potongan source code di bawah ini …

MPI_Init(&argc, &argv);

MPI_Finalize();

Perintah di atas digunakan untuk melakukan pembuatan

penghancuran proses MPI. Fungsi MPI_Init(&argc, &argv)

berfungsi untuk menginisialisasi lingkungan eksekusi MPI

sedangkan fungsi MPI_Finalize() akan mengakhiri lingkungan

eksekusi MPI. Jika kita lupa tidak menjalankan rutin ini maka

akan dimungkinkan ada proses-proses yang tersisa di memori

(orphans process). …

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPIC_Comm_rank(MPI_COMM_WORLD, &rank);

Fungsi MPI_Comm_size(MPI_COMM_WORLD, &size)

akan menentukan jumlah proses. Variabel rank pada fungsi

Page 2: Matrix Multiplication using MPI

MPIC_Comm_rank(MPI_COMM_WORLD, &rank) digunakan

sebagai process identifier.

Untuk membuat matriks digunakan prosedur

create_matrix(). Prosedur ini berfungsi untuk membuat

matriks dinamis dan melakukan alokasi memori serta

inisialisasi nilai-nilai elemen masing-masing matriks dengan

angka acak (menggunakan fungsi rand() % 8).

Kompilasi dilakukan di lingkungan Windows dengan

menggunakan gcc. Perintah yang dipakai untuk melakukan

kompilasi adalah

gcc –I “c:\Program Files\MPICH2\include” –o

matrix_mul_mpi matrix_mul_mpi.c –L “c:\Program

Files\MPICH2\lib” –lmpi

Setelah dilakukan kompilasi dan dihasilkan file executable,

program dieksekusi dengan menjalankan perintah berikut pada

jendela terminal

mpiexec –n x ./matrix_mul_mpi

Parameter –n x menunjukkan bahwa program akan dijalankan

dengan menggunakan x buah node (proses) secara bersamaan.

Berikut ini adalah tangkapan layar dari beberapa hasil

eksekusi program perhitungan matriks yang menggunakan

pemrograman sekuensial dan pemrograman paralel dengan

jumlah proses yang berbeda-beda.

Gambar 2. Hasil perhitungan paralel matrix 25x25 dengan

n = 2

Gambar 3. Hasil perhitungan paralel matrix 25x25 dengan

n = 4

Gambar 4. Hasil perhitungan parallel matrix 1000x1000

dengan n = 2

Gambar 5. Hasil perhitungan paralel matrix 1000x1000

dengan n = 4

Gambar 6. Hasil perhitungan sekuensial matrix 25x25

Page 3: Matrix Multiplication using MPI

n = 1 n = 2 n = 3 n = 4

25 x 25 0.000007 0.00044 0.00159 0.000077

100 x 100 0.000062 0.00023 0.000357 0.000379

1000 x 1000 0.005579 0.005533 0.006058 0.004469

Waktu Eksekusi (s)Ukuran Matriks

Ukuran Matriks Waktu Eksekusi (s)

25 x 25 0

100 x 100 0

1000 x 1000 0.015626

Gambar 7. Hasil perhitungan sekuensial matrix 1000x1000

Hasil eksekusi program menampilkan informasi mengenai

waktu yang dibutuhkan untuk melakukan komputasi dan

matriks hasil perkalian. Hasil tersebut disajikan dalam bentuk

tabel di bawah ini

Tabel 1. Waktu Eksekusi Pemrograman Paralel

Tabel 2. Waktu Eksekusi Pemrograman Sekuensial

Apabila kita menjalankan program MPI pada komputer

yang memiliki 2 inti (cores) atau lebih memungkinkan untuk

dihasilkannya performa yang lebih baik dibandingkan

pemrograman sekuensial. Dari tabel di atas, terlihat bahwa

pada perhitungan matriks yang memiliki 25x25 dan 100x100

(ukurannya relative kecil) waktu eksekusi lebih cepat

dibandingkan pemrograman paralel. Namun untuk matriks

yang berukuran cukup besar (1000x1000) terlihat bahwa

waktu eksekusi pemrograman paralel lebih cepat bila

dibandingkan pemrograman sekuensial. Hal ini disebabkan

pada pemrograman paralel dibutuhkan waktu untuk

pembuatan proses yang lebih banyak dan transmisi pesan antar

proses membutuhkan waktu juga.

Ukuran matriks memberikan dampak pada waktu eksekusi

program. Dari data di atas terlihat bahwa, semakin besar

ukuran matriks maka waktu eksekusi akan menjadi semakin

besar. Hal ini disebabkan karena dengan ukuran matriks yang

besar maka dibutuhkan jumlah komputasi yang lebih banyak

dibandingkan matriks yang berukuran kecil.

Dalam segi pemakaian memori, penggunaan MPI akan

membutuhkan memori yang lebih besar bila dibandingkan

pemrograman sekuensial biasa. Hal ini disebabkan karena

program yang menggunakan MPI dijalankan dengan banyak

proses yang berjalan bersama sehingga penggunaan

memoripun akan semakin meningkat. Selain itu semakin besar

ukuran matriks juga berkontribusi pada semakin besarnya

memori yang dibutuhkan ketika eksekusi program. Matriks

dengan ukuran besar membutuhkan variabel yang lebih

banyak dan juga jumlah stack yang lebih banyak bila

dibandingkan matriks berukuran kecil.

PUSTAKA

[1] https://en.wikipedia.org/wiki/Message_Passing_Interface

[2] http://www.just4tech.com/2013/10/matrix-multiplication-in-mpi.html

[3] http://mpitutorial.com/tutorials/mpi-hello-world/

[4] http://galihguawel.blogspot.co.id/2014/10/cara-install-mpi-compiler-di-windows.html

Page 4: Matrix Multiplication using MPI

LAMPIRAN

Paralel matrix multiplication program /* File : matrix_mul_mpi.c

* Program untuk melakukan perhitungan perkalian matriks secara paralel dengan menggunakan

library MPI

*/

#include <stdio.h>

#include <stdlib.h>

#include <mpi.h>

#define N 1000

#define X 1000

#define Y 1

void create_matrix(void);

int i, j, k;

int **matrix_1; // matrix_1[X][N]

int **matrix_2; // matrix_2[N][Y]

int **matrix_result; // matrix_result[X][Y]

int main(int argc , char **argv) {

double start_time, end_time, total_time;

int size, rank;

int sum = 0;

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

create_matrix();

MPI_Barrier(MPI_COMM_WORLD);

if (rank == 0) {

// Start measuring time

start_time = MPI_Wtime();

}

// Divide the task in multiple processes

for (i = rank;i < X;i = i+size) {

for (j = 0;j < Y;j++) {

sum = 0;

for (k = 0;k < N;k++) {

sum = sum + matrix_1[i][k] * matrix_2[k][j];

}

matrix_result[i][j] = sum;

}

}

if (rank != 0) {

for (i = rank;i < X;i = i+size) {

// Send calculated rows to process with rank 0

MPI_Send(&matrix_result[i][0], Y, MPI_INT, 0, 10+i, MPI_COMM_WORLD);

}

}

if (rank == 0) {

for (j = 1;j< size;j++) {

Page 5: Matrix Multiplication using MPI

for (i = j;i < X;i = i+size) {

// Receive calculated rows from respective process

MPI_Recv(&matrix_result[i][0], Y, MPI_INT, j, 10+i, MPI_COMM_WORLD, &status);

}

}

}

MPI_Barrier(MPI_COMM_WORLD);

if (rank == 0) {

// Stop measuring time

end_time = MPI_Wtime();

}

total_time = end_time - start_time;

if (rank == 0) {

for (i = 0;i < X;i++) {

for (j = 0;j < Y;j++) {

// Print the result

printf("%d\t", matrix_result[i][j]);

}

printf("\n");

}

}

if (rank == 0) {

// Total time taken for performing matrix multiplication

printf("Total time taken by CPU is = %f second\n", total_time);

}

MPI_Finalize();

return 0;

}

void create_matrix(void) {

// Create array of pointers (Rows)

matrix_1 = (int **)malloc(X * sizeof(int*));

matrix_2 = (int **)malloc(N * sizeof(int*));

matrix_result = (int **)malloc(X * sizeof(int*));

// Allocate memory for each Row pointer

for (i = 0;i < X;i++) {

matrix_1[i] = (int *)malloc(N * sizeof(int));

matrix_result[i] = (int *)malloc(Y * sizeof(int));

}

for (i = 0;i < N;i++) {

matrix_2[i]=(int *)malloc(Y * sizeof(int));

}

for (i = 0; i < X; i++) {

for (j = 0; j < N; j++) {

// initialize random number to matrix1 for all processes

matrix_1[i][j] = rand() % 8;

}

}

for (i = 0; i < N; i++) {

for (j = 0;j < Y;j++) {

// initialize random number to matrix2 for all processes

matrix_2[i][j] = rand() % 8;

}

}

Page 6: Matrix Multiplication using MPI

}

Sequential matrix multiplication /* File : matrix_mul_seq.c

* Program untuk melakukan perhitungan perkalian matriks secara sekuensial

*/

#include <stdio.h>

#include <sys/time.h>

#include <stdlib.h>

#define N 1000

#define X 100

#define Y 1

void create_matrix(void);

int i, j, k;

int **matrix_1; // matrix_1[X][N]

int **matrix_2; // matrix_2[N][Y]

int **matrix_result; // matrix_result[X][Y]

int main() {

double start_time, end_time, total_time;

int sum = 0;

struct timeval time;

create_matrix();

gettimeofday(&time, NULL);

start_time = time.tv_sec + (time.tv_usec/1000000.0);

for (i = 0;i < X;i++) {

for (j = 0;j < Y;j++) {

sum = 0;

for (k = 0;k < N;k++) {

sum = sum + matrix_1[i][k] * matrix_2[k][j];

}

matrix_result[i][j] = sum;

}

}

gettimeofday(&time, NULL);

end_time = time.tv_sec + (time.tv_usec/1000000.0);

total_time = end_time - start_time;

for (i = 0;i < X;i++) {

for (j = 0;j < Y;j++) {

printf("%d\t", matrix_result[i][j]);

}

printf("\n");

}

printf("Total time taken by CPU is = %f second\n", total_time);

return 0;

}

void create_matrix(void) {

// Create array of pointers(Rows)

matrix_1 = (int **)malloc(X*sizeof(int*));

matrix_2 = (int **)malloc(N*sizeof(int*));

matrix_result = (int **)malloc(X*sizeof(int*));

Page 7: Matrix Multiplication using MPI

// Allocate memory for each Row pointer

for (i = 0;i < X;i++) {

matrix_1[i] = (int *)malloc(N * sizeof(int));

matrix_result[i] = (int *)malloc(Y * sizeof(int));

}

for (i = 0;i < N;i++) {

matrix_2[i] = (int *)malloc(Y * sizeof(int));

}

for (i = 0;i < X;i++) {

for (j = 0;j < N;j++) {

// Initialize random number to matrix_1 for all processes

matrix_1[i][j] = rand() % 8;

}

}

for (i = 0;i < N;i++) {

for (j = 0;j < Y;j++) {

// Initialize random number to matrix_2 for all processes

matrix_2[i][j] = rand() % 8;

}

}

}