Thursday, May 21, 2015

Contoh pemograman pararel

TUGAS KELOMPOK SOFTSKILL PENGANTAR KOMPUTASI MODERN

NAMA KELOMPOK :
  1. BAYU YONAR (51411449)
  2. DIMAS IBRAHIM (52411116)
  3. FERINA CAESSARI W. (52411832)
  4. JANU PRIHARTINI (53411785)
  5. KINTAN YULANDA (54411005)
  6. RIANDA ZULHAMJANI (56411103)
  7. RIKO ARFIAN (56411212)
  8. YOEL ELBIN S. (57411515)
  • PENDAHULUAN

Komputasi Paralel adalah salah satu teknik melakukan komputasi secara bersamaan dengan memanfaatkan beberapa komputer independent secara bersamaan. Pada umumnya diperlukan saat kapasitas yang diperlukan sangat besar, baik karena harus mengolah data dalam jumlah besar ataupun karena tuntutan proses komputasi yang banyak. Kasus kedua umumnya ditemui di kalkulasi numerik untuk menyelesaikan persamaan matematis dibidang fisika, kimia dll.
Tujuan utama dari pemrograman paralel adalah untuk meningkatkan performa komputasi. Semakin banyak hal yang bisa dilakukan secara bersamaan, semakin banyak pekerjaan yang bisa diselesaikan. Analagi yang paling gampang adalah bila anda dapat merebus air sambil memotong-motong bawang saat anda akan memasak, waktu yang anda butuhkan akan lebih sedikit dibandingkan bila saat anda mengerjakan hal tersebut secara berurutan. 



    • 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, intnShowCmd)

    {
        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://chachados.blogspot.com/2013/07/parallel-computation.html
    http://cerita-punyaryan.blogspot.com/2012/01/contoh-pemrograman-paralel-dengan-4.html