Parallel Error Diffusion

posted on 08 Oct 2009 21:18 by c1ementia
for Operating System term project 
 
 
#include <iostream>
#include "atlimage.h"
#include "os/task_scheduler_init.h"
#include "os/task.h"
#include "os/tick_count.h"
using namespace std;
using namespace tbb;

CImage image;
CImage image2;
int wid,hig;
bool waiting[10000][10000];
short int img[10000][10000];
short int imgout[10000][10000];
void saveImage();
void saveImage2();
void error_diffusion(int n);
//void wait(bool f);

void wait(bool *f){
while((*f)==0){}
}

class FibTask: public task {

public:

const int n;

FibTask(int n_) : n(n_) { }

task *execute() {


error_diffusion(n);

return NULL;
}
};

class AllTask: public task {

public:

task* execute() {

// spawn tasks (2 cores)

int n = 1;
//for (int i = 0; i < NUM; i++) 
while(n<hig-1)
            {
                //printf("%d",n);
set_ref_count(3);

FibTask& a = *new(allocate_child()) FibTask(n++);
FibTask& b = *new(allocate_child()) FibTask(n++);

spawn(b);
spawn_and_wait_for_all(a);
}

return NULL;
}
};

int main(int argc, char *argv[]) {
image.Load("input.bmp");
    wid=image.GetWidth(),hig=image.GetHeight();
cout<<"wid="<<wid<<endl;
cout<<"hig="<<hig<<endl;
char con;
int loop,loop1;
double t4,t5;

// initialize
do{
cout<<"Storing image to array, please wait..."<<endl;
for(int i=0;i<hig;i++){
for(int j=0;j<wid;j++){
img[i][j] = (int)GetRValue(image.GetPixel(j,i));
}
}
cout<<"Press 0 for singlecore, 1 for multicores : ";
bool choice;
cin>>choice;



if(choice==1){
     for(loop=0;loop<hig-1;loop++)
{
for(loop1=0;loop1<wid+1;loop1++){
          waiting[loop][loop1]=0;    
}
    }

for(loop=0;loop<wid;loop++)
waiting[0][loop]=1;

task_scheduler_init init(2);


tick_count t0 = tick_count::now();
task::spawn_root_and_wait( *new(task::allocate_root()) AllTask() );
tick_count t1 = tick_count::now();

init.terminate();
printf("Elapsed time (multicores): %g\n", (t1 - t0).seconds());
t4=(t1 - t0).seconds();
    saveImage2();
}

if(choice==0){
int j;
    int err;
for(loop=0;loop<hig-1;loop++){
for(loop1=0;loop1<wid+1;loop1++){
          waiting[loop][loop1]=1;    
}
    }


tick_count t2=tick_count::now();
for(j=1;j<hig-1;j++){
        error_diffusion(j);
}
tick_count t3=tick_count::now();


cout<<"Time elapsed (singlecore) : "<<(t3-t2).seconds()<<endl;
t5=(t3-t2).seconds();
saveImage();
}
do{
cout<<endl<<"continue?(y/n) (c for comparing efficiency) : ";
cin>>con;
if(con=='c')cout<<(t5*100)/t4<<"%"<<endl;
}while(con=='c');
}while(con!='n');
return 0;
}


void error_diffusion(int n)
{
    int j=n;
    int err;
        for (int i = 1; i < wid-1; i++) 
{
wait(&waiting[n-1][i+1]);
            imgout[j][i] = (img[j][i] < 128 ? 0 : 255);
            if(imgout[j][i]==0)err=img[j][i];
else err=img[j][i]-255;
            img[j][i+1] += (err * 7) / 16;
            img[j+1][i-1] += (err * 3) / 16;
            img[j+1][i] += (err * 5) / 16;
            img[j+1][i+1] += (err * 1) / 16;
                 waiting[n][i]=1;
if(i==wid-2) waiting[n][i+1] = 1;
        }
    return ;
}

void saveImage(){
cout<<"saving Image..."<<endl;
for(int i=0;i<hig;i++){
for(int j=0;j<wid;j++){
int col=imgout[i][j];
image.SetPixel(j,i,RGB(col,col,col));
}
}
image.Save("output1core.bmp");
cout<<"Image was saved as output1core.bmp"<<endl;
}

void saveImage2(){
cout<<"saving Image..."<<endl;
for(int i=0;i<hig;i++){
for(int j=0;j<wid;j++){
int col = imgout[i][j];
image.SetPixel(j,i,RGB(col,col,col));
}
}
image.Save("output2core.bmp");
cout<<"Image was saved as output2core.bmp"<<endl;
}

Comment



smilebig smileopen-mounthed smileconfused smilesad smileangry smiletonguequestionembarrassedsurprised smilewinkdouble winkcry

Tweet