Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
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:
 
//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 23-Nov-12 7:07am
Edited 23-Nov-12 7:11am
ProgramFOX123.6K
v2
Comments
Sergey Alexandrovich Kryukov at 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
Member 8500756 at 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

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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
  Permalink  
Comments
CPallini at 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 at 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)



Advertise | Privacy | Mobile
Web03 | 2.8.140926.1 | Last Updated 23 Nov 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100