Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have write a program in c# for comparing images pixel by pixel i parallel form to use all cores of computer but it runs faster when i run it in one core then in two (max core of my PC). This is the part of code in parallel:
C#
//Krahsimi parallel i fotografive piksel për piksel
                    if (opsioni_per_krahasim_sipas_pikselave.Checked == true)
                    {
                        int numri_i_procesorve = Numri_i_berthamave.Value;
                        progressBar1.Visible = true;
                        Color gabim = Color.Red;
                        Color ngjyra_nga_foto_1;
                        Color ngjyra_nga_foto_2;
                        ParallelOptions po = new ParallelOptions();
                        po.MaxDegreeOfParallelism = numri_i_procesorve;
                        koha_e_kaluar.Start();
                        Parallel.For(0, gjersia,po,pikselat_ne_rresht=>
                        {
                            for (int pikselat_ne_kolone = 0; pikselat_ne_kolone < lartesia; pikselat_ne_kolone++)
                            {
                                //Application.DoEvents();
                                  //Color mire = b.GetPixel(pikselat_ne_rresht, pikselat_ne_kolone);
                                lock (a)
                                {
                                    lock (b)
                                    {
                                        ngjyra_nga_foto_1 = a.GetPixel(pikselat_ne_rresht, pikselat_ne_kolone);
                                        ngjyra_nga_foto_2 = b.GetPixel(pikselat_ne_rresht, pikselat_ne_kolone);
                                    }
                                }
                                      if (ngjyra_nga_foto_1 == ngjyra_nga_foto_2)
                                      {
                                              //b.SetPixel(pikselat_ne_rresht, pikselat_ne_kolone, mire);
                                          fillon++;
                                      }
                                      else
                                      {
                                          lock (b)
                                          {
                                              b.SetPixel(pikselat_ne_rresht, pikselat_ne_kolone, gabim);
                                          }
                                              fotot_e_njejta = false;
                                      }
                                 //fillon++;
                            }
                            //double bb = fillon * 100 / (1024 * 768);
                            //Perqindja_e_krahasimit.Text = bb.ToString() + " " + fillon.ToString();
                    
                            //perqinde = (decimal)fillon / (gjersia * lartesia);
                            //Perqindja_e_krahasimit.Text = ((int)(perqinde * 100)).ToString() + "%";
                            //Perqindja_e_krahasimit.Refresh();
                            //progressBar1.Value++;
                        });
                        koha_e_kaluar.Stop();
                        //}
                        }

I have a trackbar that hold numbers of cores named Numri_i_berthamave. When i set the track bar in 1 core and run the program it runs faster then when i set the track bar in 2 cores. Did i use right the MaxDegreeOfParallelism property of ParallelOptions. Any sugestion please.
Posted
Updated 23-Nov-12 7:11am
v2
Comments
Sergey Alexandrovich Kryukov 23-Nov-12 13:51pm    
What is the imaging library you use? As you don't show declaration of a and b, it is not 100% apparent. In question, you should not assume there is only one library. In particular, showing full type names and a bit more of declarations could greatly improve the clarity of your question.
--SA
Rafeti 25-Nov-12 9:44am    
I attempt to improve my code (code above) but when i use two or more cores the reult picture is made with horizontal stripes (i deformed) it is right just when i run the app in one core.
here is the code with declared variables:


private unsafe Bitmap krahas(Bitmap nje, Bitmap dy)
{
Bitmap a = new Bitmap(nje);
Bitmap b = new Bitmap(dy);
int gjersia = Math.Min(a.Width, b.Width);
int lartesia = Math.Min(a.Height, b.Height);
Bitmap rez = new Bitmap(gjersia,lartesia);
int numri_i_procesorve = Numri_i_berthamave.Value;
progressBar1.Visible = true;
//Bëjmë lock bitat e fotove
Rectangle per_a = new Rectangle(0, 0, a.Width, a.Height);
Rectangle per_b = new Rectangle(0, 0, b.Width, b.Height);
Rectangle per_rez=new Rectangle(0,0,gjersia,lartesia);
BitmapData t_per_a = a.LockBits(per_a, ImageLockMode.ReadWrite, a.PixelFormat);
BitmapData t_per_b = b.LockBits(per_b, ImageLockMode.ReadWrite, b.PixelFormat);
BitmapData t_per_rez = rez.LockBits(per_rez, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

byte* adresa_per_a =(byte*)t_per_a.Scan0;
byte* adresa_per_b = (byte*)t_per_b.Scan0;
byte* rezult = (byte*)t_per_rez.Scan0;

Color cl=Color.Red;
byte[] ngj=new byte[4];
ngj[0] = cl.A;
ngj[1] = cl.R;
ngj[2] = cl.G;
ngj[3] = cl.B;

int rowpadding = t_per_a.Stride - (a.Width*4);
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = numri_i_procesorve;
koha_e_kaluar.Reset();
koha_e_kaluar.Start();
//for (int i = 0; i < lartesia; i++)
//Task.Factory.StartNew(() =>
// {

Parallel.For(0, lartesia, po, i =>
{
for (int j = 0; j < gjersia; j++)
{
int same = 0;
byte[] tmp = new byte[4];
for (int x = 0; x < 4; x++)
{
tmp[x] = adresa_per_b[0];
if (adresa_per_a[0] == adresa_per_b[0])
{
same++;

}
adresa_per_a++;
adresa_per_b++;

}
for (int x = 0; x < 4; x++)
{
rezult[0] = (same != 4) ? ngj[x] : tmp[x];
rezult++;
}
}
if (rowpadding > 0)
{
adresa_per_a += rowpadding;
adresa_per_b += rowpadding;
rezult += rowpadding;
}
});
//});

koha_e_kaluar.Stop();
//System.Runtime.InteropServices.Marshal.Copy(bitat_per_b, 0, adresa_per_b, nr_bitatve_per_b);
a.UnlockBits(t_per_a);
b.UnlockBits(t_per_b);
rez.UnlockBits(t_per_rez);
//}
//Rezultati_vizuel.Image=(b, gjersia, lartesia);
// Rezultati_vizuel.Image = b;
return rez;
}

1 solution

An advice? You use of parallel is pretty much pointless here. You kill all the performance with the use of GetPixel/SetPixel. You should not use these methods at all, unless you don't care of performance at all, or if you have to access very few pixels. If this is System.Drawing, you should use System.Drawing.Bitmap.LockBits:
http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.lockbits.aspx[^].

The MSDN help page on the first of the methods contains a short and very simple code sample.

With WPF, you need to use pretty similar approach with the class System.Windows.Media.Imaging.WriteableBitmap:
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.aspx[^].

—SA
 
Share this answer
 
Comments
CPallini 24-Nov-12 8:01am    
Good point, my 5.
As a side note, in my personal experience, parallel for (as well hand-crafted multithreading) overhead makes it slower then serial approach, if core operations are simple instructions.
Sergey Alexandrovich Kryukov 24-Nov-12 18:49pm    
Thank you, Carlo.
Absolutely. Parallel technology can only gain you some throughput when there are enough cores to take some highly independent tasks by improving CPU utilization level, otherwise you only loose performance due to overhead. It also happens where you have a number of concurrent active processes -- it makes CPU cores busy, so parallel for won't help.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900