Parallel Error Diffusion
posted on 08 Oct 2009 21:18 by c1ementiafor 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;
}
Tags: error diffusion, os, project, tbb0 Comments