2010-01-11 52 views
1

此代碼用於將顏色轉換爲黑色和白色。並行c#線程性能問題

  • 我試圖平行部添加到代碼
  • 剛剛從灰度變換到黑白
  • 我試圖分配給每個線程數的cols的,其具有的像素的量

但性能沒有改善。

我試圖通過更改2 for循環中的除數值(其中800代碼)和計數器值增量800 * 600圖像。

這種變化應該使線程的數量增加或減少

結果:

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

幫我提高性能怎麼把它需要更大的圖片8秒,我希望把它平行

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)); 
      } 
     } 
    } 
    } 
} 

儘快請U可以

謝謝

謝謝大家 Craig Stuntz問題:如何在不調用setpixel的情況下編輯像素的顏色? 感謝您的幫助

+3

週期是你的朋友;他們劃定下一句話。 – Joe 2010-01-11 16:03:57

+0

Profiler也是你的朋友! – 2010-01-11 16:32:27

回答

4

通過調用Thread.Start然後立即調用Thread.Join,您可以有效地使用串行而非並行。在調用Thread.JoinThread.Start循環之後放置第二個循環。

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(); 
+0

+1我只是在輸入那個:) – Paolo 2010-01-11 16:39:24

+1

此外,還有其他人所說的+1。我的答案只是在並行化方面確定示例代碼的問題,而不是性能方面。 – user7116 2010-01-11 16:41:57

+0

它沒有工作我的朋友 因爲當我做到了,我遇到了一個異常「對象目前正在其他地方使用。」 我不知道爲什麼請你可以幫我,如果你有一封電子郵件我可以發送項目到你的郵箱 謝謝 – FarOoOosa 2010-01-13 17:05:24

7

在優化之前不要並行化。在一個好的分析器下運行你的代碼並首先解決性能問題。是的,這可能最終成爲並行化的一個很好的候選者,但我敢打賭,撥打SetPixel的一百萬個呼叫是一個更大的問題。

+0

「,但我敢打賭,100萬次撥打SetPixel是一個更大的問題」 - 我認爲你是對的! +1 – 2010-01-11 16:36:41

+0

如何在不調用setpixel的情況下編輯像素的顏色?感謝您的幫助 – FarOoOosa 2010-01-13 17:06:22

+0

Christian Vik爲您提供了一個體面的例子。 – 2010-01-13 17:11:50

2

GetPixel()/ SetPixel()是這樣做的緩慢方式。相反,您應該使用帶有「不安全」的BitmapData和指向編輯圖像的指針。

更新: 而上的BitmapData和灰階一個快速谷歌搜索橫空出世列出此example

0

在甚至考慮並行化之前,您應該對您的代碼進行配置以找出時間爲實際上正在花費的時間。

Eqatec's profiler是一個免費且易於使用的.NET分析工具。