Kamis, 21 Mei 2015

PEMROGRAMAN PARALLEL


 Kelompok :
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 keuanganbioinformatika, 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.
  • 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:
  1. Inisialisasi
  2. Dekomposisi, distribusi dan pengambilan kembali sub pekerjaan
  3. 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