OpenMP Hello World a la GAIBlog
Hari ini kali pertama saya berinteraksi dengan OpenMP sebagai bahan eksplorasi kuliah sistem berkinerja tinggi yang diajar Bapak Farid. Program pertama yang saya buat adalah program sederhana untuk melakukan image thresholding.
#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;
}
Hal yang menarik dari OpenMP (implementasi yang saya gunakan adalah GNU/MinGW yaitu GOMP) adalah penggunaannya yang menggunakan compiler directives pragma sehingga untuk melakukan pembandingan dengan eksekusi secara serial cukup dengan mengomentari pragma dan kompilasi ulang programnya. Pengolahan yang dilakukan di program di atas dikategorikan sebagai point processing yang disebut sebagai embarrassingly parallel di buku parallel programming-nya Barry Wilkinson karena perubahan yang terjadi pada tiap titik citra bersifat independen terhadap perubahan yang terjadi pada titik lainnya.
Filed under: akademik, image processing, programming | 4 Comments
Tags: openmp, parallel programming, sdl, thresholding

Haha, ada yang ngerti gak ya?
Kalo pemrograman paralel dengan MPI tertarik ndak? Beda kampus beda teknik ya, hehe.