Kelompok :
1. Arief Iman Rahman (51411100)
1. Arief Iman Rahman (51411100)
2. Asep Rohmana (51411242)
3. Cella Rofi (57411950)
4. Kutfu Dany (57411997)
5. Latifah (54411074)
6. M Fuad Fazri (54411663)
7. M Isan Guci (54411670)
8. Netty Herawaty (59411443)
9. Reni Marintan (55411973)
Komputasi paralel adalah salah satu teknik melakukan komputasi secara
bersamaan dengan memanfaatkan beberapa komputer independen secara bersamaan.
Ini umumnya diperlukan saat kapasitas yang diperlukan sangat besar, baik karena
harus mengolah data dalam jumlah besar (di industri
keuangan, bioinformatika,
dll) ataupun karena tuntutan proses komputasi yang banyak. Kasus kedua umum
ditemui di kalkulasi numerik untuk
menyelesaikan persamaan matematis di
bidang fisika (fisika komputasi), kimia (kimia komputasi) dll.
TUJUAN PARALLEL
PROCESSING
Tujuan utama dari pemrosesan paralel adalah untuk meningkatkan performa komputasi. Semakin banyak hal yang bisa dilakukan secara bersamaan (dalam waktu yang sama), semakin banyak pekerjaan yang bisa diselesaikan.
Tujuan utama dari pemrosesan paralel adalah untuk meningkatkan performa komputasi. Semakin banyak hal yang bisa dilakukan secara bersamaan (dalam waktu yang sama), semakin banyak pekerjaan yang bisa diselesaikan.
- Contoh pemrograman paralel
dengan 4 metode
1. MPI (Message Passing Interface)
MPI atau Mesage Passing Interface adalah
spesifikasi yang perlu diterapkan pengembang dan pengguna pemrograman parallel.
Sedangkan pustaka yang mengimplementasi spesifikasi tersebut dapat kita peroleh
misalnya dari bahasa C/C++. Untuk menggunakan pustaka tersebut kita hanya
tinggal mendeklarasinya di awal program seperti berikut ini.
#include
"mpi.h"
Secara umum, pemrograman parallel
menggunakan spesifikasi MPI membutuhkan tiga tahapan. Hal ini terlepas dari
kebutuhan lain terkait eksekusi seperti mem-boot layanan ini. Ketiganya
adalah:
- Inisialisasi
- Dekomposisi, distribusi dan
pengambilan kembali sub pekerjaan
- De-inisialisasi
Bagaimana ketiganya diterapkan dalam
C/C++, berikut adalah contoh prrogram sederhana.
Program berikut ini hanya bertugas
menampilkan karakter/informasi ke layar oleh masing-masing node yang terlibat
dalam komunkasi MPI. Kode sumber pertama dibuat dalam C.
#include
<stdio.h>
#include
"mpi.h"
int main(int
argc, char ** argv) {
int p;
int id;
double wtime;
//Inisialisasi MPI
MPI_Init(&argc,&argv);
//Mendapatkan id dan jumlah proses
MPI_Comm_size(MPI_COMM_WORLD,&p);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
wtime=MPI_Wtime();
//Mendistribusi pekerjaan
if(id==0) {
printf("MPI Hello - Master
Process\n");
printf(" C / MPI
version\n");
printf(" An example
program\n\n");
printf(" The number of
process = %d\n",p);
}
else {
printf("Process %d says
'Hello World!'\n",id);
}
if(id==0) {
printf("\n");
printf("Hello MPI - Master
Process:\n");
printf(" Normal end of
execution: 'Goodbye World!'\n\n");
wtime=MPI_Wtime() - wtime;
printf("Elapsed wall clock
time = %g seconds\n", wtime);
}
//De-inisialisasi
MPI_Finalize();
return 0;
}
2. openMP
OpenMP (Open
Multi-Processing) adalah sebuah API (application programming interface) yang
mendukung multi-platform memori bersama pemrograman multiprocessing dalam C, C
+ +, dan Fortran, pada arsitektur prosesor paling dan sistem operasi, termasuk
Linux, Unix, AIX, Solaris, Mac OS X, dan Microsoft Windows platform. Ini
terdiri dari satu set arahan kompiler, rutinitas perpustakaan, dan variabel
lingkungan yang mempengaruhi perilaku saat run-time
Contoh model
program parallel openMP
#include <omp.h>
|
#include <sdl.h>
|
#include <windows.h>
|
|
#include <math.h>
|
void __putpixel(SDL_Surface*
buffer, int x, int y, Uint32 color)
|
{
|
|
int bpp = buffer->format->BytesPerPixel;
|
/* Here p is the address to the pixel we want to
set */
|
|
Uint8 *p = (Uint8 *)buffer->pixels + y *
buffer->pitch + x * bpp;
|
switch(bpp) {
|
case 1:
|
|
*p = color;
|
break;
|
|
case 2:
|
|
*(Uint16 *)p = color;
|
break;
|
|
case 3:
|
|
if(SDL_BYTEORDER ==
SDL_BIG_ENDIAN) {
|
p[0]
= (color >> 16) & 0xff;
|
p[1]
= (color >> 8 ) & 0xff;
|
p[2]
= color & 0xff;
|
|
} else {
|
p[0]
= color & 0xff;
|
|
p[1]
= (color >> 8 ) & 0xff;
|
p[2]
= (color >> 16) & 0xff;
|
|
}
|
break;
|
|
case 4:
|
|
*(Uint32 *)p = color;
|
break;
|
|
}
|
}
|
|
Uint32 __getpixel(SDL_Surface* buffer, int x, int y)
|
|
{
|
int bpp = buffer->format->BytesPerPixel;
|
|
/* Here p is the address to the pixel we want to
retrieve */
|
Uint8 *p = (Uint8 *)buffer->pixels + y *
buffer->pitch + x * bpp;
|
|
switch(bpp) {
|
|
case 1:
|
return *p;
|
|
case 2:
|
|
return *(Uint16 *)p;
|
case 3:
|
if(SDL_BYTEORDER ==
SDL_BIG_ENDIAN)
|
|
return p[0] << 16 | p[1] << 8
| p[2];
|
else
|
|
return p[0] | p[1] << 8 | p[2]
<< 16;
|
case 4:
|
return *(Uint32 *)p;
|
|
default:
|
|
return 0;
/* shouldn't happen, but avoids warnings */
|
}
|
|
}
|
int WINAPI
WinMain(HINSTANCE hInst,
HINSTANCE hPrev,
LPSTR lpCmdLine,
int nShowCmd)
|
{
|
|
SDL_Surface *tmp, *screen;
|
|
|
int i, j, w, h;
|
int nThread, tid;
|
|
Uint32 starttick;
|
SDL_Event evt;
|
|
int done = 0;
|
FILE *deb = fopen("debug.txt", "w");
|
|
|
fprintf(deb, "start \n");
|
SDL_Init(SDL_INIT_VIDEO);
|
atexit(SDL_Quit);
|
|
tmp = SDL_LoadBMP("alfa256.bmp");
|
w = tmp->w;
|
h = tmp->h;
|
screen = SDL_SetVideoMode(w, h,
tmp->format->BitsPerPixel, SDL_SWSURFACE|SDL_ANYFORMAT);
|
|
SDL_BlitSurface(tmp, NULL, screen, NULL);
|
SDL_FreeSurface(tmp);
|
|
tmp = screen;
|
|
|
if ( SDL_MUSTLOCK(tmp) ) {
|
if ( SDL_LockSurface(tmp) < 0 ) {
|
|
fprintf(stderr,
"Can't lock screen: %s\n", SDL_GetError());
|
return;
|
|
}
|
}
|
|
|
fprintf(deb, "starting block \n");
|
|
starttick = SDL_GetTicks();
|
#pragma omp parallel shared(tmp, w, h)
|
|
{
|
Uint8 r, g, b, a, tmpi;
|
|
int i,j;
|
|
|
#pragma omp for
schedule(dynamic) nowait
|
for (j=0; j<h; ++j){
|
|
for (i=0; i<w; ++i){
|
SDL_GetRGBA(__getpixel(tmp,
i, j), tmp->format, &r, &g, &b, &a);
|
|
tmpi
= (Uint8)round(0.299 * r + 0.587 * g + 0.114 * b);
|
tmpi
= (tmpi>128)?255:0;
|
|
__putpixel(tmp,
i, j, SDL_MapRGBA(tmp->format, tmpi, tmpi, tmpi, a));
|
}
|
|
|
SDL_UpdateRect(screen,
0, 0, 0, 0);
|
|
}
|
}
|
|
|
SDL_UpdateRect(screen, 0, 0, 0, 0);
|
|
fprintf(deb, "end block %d\n",
SDL_GetTicks()-starttick);
|
|
|
if ( SDL_MUSTLOCK(tmp) ) {
|
SDL_UnlockSurface(tmp);
|
|
}
|
|
|
while(!done){
|
while(SDL_PollEvent(&evt)){
|
|
switch(evt.type){
|
case SDL_QUIT:
|
|
done
= 1;
|
break;
|
|
}
|
}
|
|
}
|
|
|
fclose(deb);
|
|
SDL_SaveBMP(tmp, "alfagrey.bmp");
|
return 0;
|
}
|
3. POSIX thread
POSIX
Thread, biasanya disebut sebagai pthreads, adalah standar POSIX untuk thread.
Standar, POSIX.1c, Thread ekstensi (IEEE Std 1003.1c-1995), mendefinisikan
sebuah API untuk menciptakan dan memanipulasi thread.
Implementasi
dari API yang tersedia pada banyak Unix-seperti POSIX-konforman sistem
operasi seperti FreeBSD, NetBSD,
OpenBSD, GNU / Linux, Mac OS X dan Solaris. DR-DOS dan Microsoft Windows implementasi juga ada: dalam
subsistem SFU / SUA yang menyediakan implementasi asli dari sejumlah POSIX API,
dan juga di dalam paket pihak ketiga seperti pthreads-W32, yang mengimplementasikan pthreads di atas ada
Windows API.
Contoh Posix
thread
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <pthread.h>
#include <time.h>
#define MAX_THREAD 16 /* maximum number of
threads */
#define NDIM 1024 /* number of NDIMs */
double
a[NDIM][NDIM];
double
b[NDIM][NDIM];
double
c[NDIM][NDIM];
struct timeval tvstart, tvstop;
typedef struct
{
int id; /* identification */
int noproc; /* process */
int dim; /* number of threads */
double (*a)[NDIM][NDIM],(*b)[NDIM][NDIM],(*c)[NDIM][NDIM];
} parm;
void mm(int me_no, int noproc, int n, double
a[NDIM][NDIM], double b[NDIM][NDIM], double c[NDIM][NDIM])
{
int i,j,k;
double sum;
i=me_no;
while
(i<n) {
for (j =
0; j < n; j++) {
sum =
0.0;
for (k = 0; k < n; k++) {
sum = sum + a[i][k] * b[k][j];
}
c[i][j] = sum;
}
i+=noproc;
}
}
void * worker(void *arg)
{
parm *p = (parm *) arg;
mm(p->id, p->noproc, p->dim, *(p->a), *(p->b),
*(p->c));
}
int main(int argc, char *argv[])
{
int j, k, noproc, me_no;
double sum;
double t1, t2;
pthread_t *threads;
parm *arg;
int n, i;
for (i = 0; i
< NDIM; i++)
for (j = 0;
j < NDIM; j++) {
a[i][j]
= i + j;
b[i][j] =
i + j;
}
if (argc <
2) {
n = MAX_THREAD;
}
else {
n =
atoi(argv[1]);
}
// start the
bechmark timer
gettimeofday(&tvstart, NULL);
threads =
(pthread_t *) malloc(n * sizeof(pthread_t));
arg=(parm
*)malloc(sizeof(parm)*n);
for (i = 0; i
< n; i++) {
arg[i].id
= i;
arg[i].noproc
= n;
arg[i].dim
= NDIM;
arg[i].a
= &a;
arg[i].b
= &b;
arg[i].c
= &c;
pthread_create(&threads[i],
NULL, worker, (void *)(arg+i));
}
for (i = 0;
i < n; i++) {
pthread_join(threads[i],
NULL);
}
gettimeofday(&tvstop, NULL);
double t =
(tvstop.tv_sec - tvstart.tv_sec) * 1000 +
(tvstop.tv_usec - tvstart.tv_usec) * 1e-3;
printf("Pthread: %d : Dim: %d :
Time: %f\n", n, NDIM, t);
free(arg);
return 0;
}
Sumber:
http://bagusonthespot.blogspot.com/2012/04/parallel-processing.html
http://www.academia.edu/7424831/Parallel_PROCESSING_Pemrosesan_paralel