简体   繁体   中英

parallel c# threading performance issues

This code is for transforming from colored to black and white.

  • I tried to add parallel section to the code
  • just transforming from gray-scale to black-white
  • i tried to assign to each thread a number of cols which has amount of pixels

but the performance didnt improve at all.

I tried for a 800*600 image by changing the divisor value (its here 800 in code) in the 2 for loops and the counter value increment .

This change should make the number of threads increase or decrease

the results :

value |  num of thread |   time
 800       1              1.17 sec
 400       2              1.17 sec
 200       4              1.17 sec
and so on ...

Help me to increase the performance coz it takes 8 sec for bigger images and i want to make it parallel

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace IMG
{

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    string path = "";
    public void openimage()
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            path = openFileDialog1.FileName;
        }
    }
    Bitmap bm;
    Bitmap gs;
    private void button1_Click(object sender, EventArgs e)
    {
        if (path == "")
        {
            openimage();
        }
        Graphics g = this.CreateGraphics();
        bm = new Bitmap(path);
        // Draw image with no effects.....
        g.DrawImage(bm, 100, 100, 200, 200);
        gs = new Bitmap(bm.Width, bm.Height);
        worker soso = new worker(gs, bm);
        worker.counter = 0;
        soso.tograyscale();
        // Draw gray image.......
        g.DrawImage(gs, 305, 100, 200, 200);
        DateTime x = DateTime.Now;
        for (int koko = 0; koko < gs.Width/400; koko++)
        {        
                Thread t1 = new Thread(new ThreadStart(soso.trasform));
                t1.Start();
                t1.Join();
                soso.increment();
        }
        g.DrawImage(bm, 510, 100, 200, 200);
        gs.Dispose();
        g.Dispose();
        textBox19.Text=(DateTime.Now - x).ToString();
    }
}
public class worker
{
    public static int counter = 0;
    public Bitmap gs;
    public Bitmap bm;
    public int xxxx;
    public worker(Bitmap a, Bitmap b)
    {
        gs = a;
        bm = b;
        xxxx = a.Height;
    }
    public void increment()
    {
        counter += 400;
    }
    public void trasform()
    {
        argtransform(counter);

    }
    public void tograyscale()
    {
        for (int i = 0; i < bm.Width; i++)
        {
            for (int j = 0; j < bm.Height; j++)
            {
                Color c = bm.GetPixel(i, j);
                int y = (int)(0.3 * c.R + 0.59 * c.G + 0.11 * c.B);
                gs.SetPixel(i, j, Color.FromArgb(y, y, y));
            }
        }
    }
    public void argtransform(int cc)
    {
        for (int i = cc; i < cc + 400; i++)
        {
            for (int j = 0; j < xxxx; j++)
            {
                Color c = gs.GetPixel(i, j);
                int y1 = 0;
                if (c.R >= 128)
                    y1 = 255;
                bm.SetPixel(i, j, Color.FromArgb(y1, y1, y1));
            }
        }
    }
  }
}

thank you please as soon as u can


thank you all question for Craig Stuntz : how could i edit the color of pixel without calling setpixel ? thank you for your help

Don't parallelize before you optimize. Run your code under a good profiler and fix the performance issues first. Yes, this may turn out to be a good candidate for parallelization in the end, but I'm betting that 1 million calls to SetPixel is a much bigger issue.

By calling Thread.Start then immediately calling Thread.Join , you're effectively working in serial rather than parallel. Place a second loop after the Thread.Start loop which calls Thread.Join .

List<Thread> threads = new List<Thread>();
for (int koko = 0; koko < gs.Width/400; koko++)
{        
    Thread t1 = new Thread(new ThreadStart(soso.trasform));
    t1.Start();
    threads.Add(t1);
    soso.increment();
}

foreach (Thread thread in threads) thread.Join();

GetPixel() / SetPixel() is way to slow for doing this. Instead you should use BitmapData with "unsafe" and pointers to edit the image.

Update: And a quick google search on BitmapData and grayscale turned out to list this example .

Before even thinking of parallelisation, You should profile your code to find out where the time is actually being spent.

Eqatec's profiler is a free and easy to use .NET profiling tool.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM