Core2Quadで、実験したマルチスレッドグレースケール処理の記事を掲載しました
こちらをご覧ください
前回、グレースケール処理でInt* Byte*、どっちの処理が速いか?ってことを、
テストしてみたけど、あまり、速度上がらず...(´・ω・`)
激怒しちゃったんで、このグレースケール処理、マルチスレッド化してみた(w
いつものように条件は以下のとおり
CPU : AMD Athlon64x2 3800+(2.0GHz)
Memory : 1GB
OS : Windows XP Pro
言語: Visual Studio 2005(C#2.0) + .Net FrameWork2.0
| 画像データ1000回の グレースケール処理を実行 |
リリースコンパイル |
|
640 * 480 24ビットピクセル 1スレッド |
11,703ミリ秒 |
|
640 * 480 24ビットピクセル 2スレッド |
7,843ミリ秒 |
|
640 * 480 24ビットピクセル 4スレッド |
7,390ミリ秒 |
う~む、余は満足じゃ!
それにしても、4コアで試してみたいなぁ。。。
もうちょっとしたら、4コアに変えるんで、そのとき再度、性能評価やってみよう...
コードは、4スレッド版です
C#:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Text;
- using System.Windows.Forms;
- using System.Threading;
- namespace GrayScaleTest
- {
- public partial class Form1 : Form
- {
- private const int THREADCOUNT = 5;
- static public Form1 m_MyObj; //スレッドへ情報を渡すため、自分自身のインスタンスをセット
- private Bitmap m_ImageBackup; // 一時データ
- private Bitmap m_bmapIn; // 入力データ
- private Bitmap m_bmapOut; // 出力データ
- private bool m_ThreadOnFL;
- private bool[] m_ThreadJobFL;
- private bool[] m_ThreadJobFixFL;
- private Thread[] m_Thread;
- private IntPtr m_SouPT;
- private IntPtr m_DesPT;
- private int m_Width; // Image サイズ
- private int m_Height; // Image サイズ
- public Form1()
- {
- InitializeComponent();
- m_MyObj = this;
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- pictureBox1.Image = null;
- m_ThreadOnFL = true;
- for (int i = 0; i <THREADCOUNT; i++)
- {
- m_ThreadJobFL[i] = false;
- m_ThreadJobFixFL[i] = false;
- }
- m_Thread[0].Name = "画像処理スレッド0";
- m_Thread[1].Name = "画像処理スレッド1";
- m_Thread[2].Name = "画像処理スレッド2";
- m_Thread[3].Name = "画像処理スレッド3";
- m_Thread[4].Name = "画像処理スレッド4";
- m_Thread[0].Start();
- m_Thread[1].Start();
- m_Thread[2].Start();
- m_Thread[3].Start();
- m_Thread[4].Start();
- }
- private void Form1_FormClosed(object sender, FormClosedEventArgs e)
- {
- m_ThreadOnFL = false;
- for(int i = 0; i <200; i++)
- {
- Application.DoEvents();
- Thread.Sleep(1);
- }
- }
- private void button1_Click(object sender, EventArgs e)
- {
- string FileName;
- if (openFileDialog1.ShowDialog() != DialogResult.OK)
- {
- return;
- }
- FileName = openFileDialog1.FileName;
- m_Width = m_ImageBackup.Width;
- m_Height = m_ImageBackup.Height;
- m_bmapIn = m_ImageBackup;
- pictureBox1.Image = m_bmapIn;
- }
- private void JobCore_Click(object sender, EventArgs e)
- {
- DateTime dt = DateTime.Now;
- int min = dt.Minute;
- int sec = dt.Second;
- int mili = dt.Millisecond;
- lblStart.Text = "";
- lblEnd.Text = "";
- lblJob.Text = "";
- lblStart.Text = "開始時間:" + min.ToString() + "_" + sec.ToString() + "_" + mili.ToString();
- Refresh();
- Bitmap bd = pictureBox1.Image as Bitmap;
- Bitmap bs;
- BitmapData bDataInS;
- BitmapData bDataInD;
- IntPtr Scan0_InS; // ピクセルデータの開始アドレス
- IntPtr Scan0_InD; // ピクセルデータの開始アドレス
- ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
- Scan0_InS = bDataInS.Scan0; // ピクセルデータの開始アドレス
- ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
- Scan0_InD = bDataInD.Scan0; // ピクセルデータの開始アドレス
- m_SouPT = Scan0_InS;
- m_DesPT = Scan0_InD;
- m_Width = bd.Width;
- m_Height = bd.Height;
- if (sender == button2)
- {
- for(int j = 1; j <THREADCOUNT; j++)
- {
- m_ThreadJobFixFL[j] = true; //スレッド処理完了フラグ (0番以外は完了させておく)
- m_ThreadJobFL[j] = false; //スレッド処理開始フラグ(0番起動 以外は停止)
- }
- for(int i = 0; i <1000; i++) //スレッド0番(480ライン処理)のみ起動
- {
- m_ThreadJobFixFL[0] = false; //スレッド処理完了フラグ (0番以外は完了させておく)
- m_ThreadJobFL[0] = true; //スレッド処理開始フラグ(0番起動 以外は停止)
- while(IsThreadJobFix() == false ) //全スレッドの処理が完了するまで待機
- {
- Thread.Sleep(1);
- }
- }
- }
- else
- {
- m_ThreadJobFixFL[0] = true; //スレッド処理完了フラグ (0番は完了させておく)
- m_ThreadJobFL[0] = false; //スレッド処理開始フラグ(0番停止 以外は起動)
- for(int i = 0; i <1000; i++) //スレッド1番2番(240ライン処理)のみ起動
- {
- for(int j = 1; j <THREADCOUNT; j++)
- {
- m_ThreadJobFixFL[j] = false; //スレッド処理完了フラグ (0番は完了させておく)
- m_ThreadJobFL[j] = true; //スレッド処理開始フラグ(0番停止 以外は起動)
- }
- while(IsThreadJobFix() == false ) //全スレッドの処理が完了するまで待機
- {
- Thread.Sleep(1);
- }
- }
- }
- bd.UnlockBits(bDataInD);
- bs.UnlockBits(bDataInS);
- DateTime dt2 = DateTime.Now;
- min = dt2.Minute;
- sec = dt2.Second;
- mili = dt2.Millisecond;
- lblEnd.Text = "終了時間:" + min.ToString() + "_" + sec.ToString() + "_" + mili.ToString();;
- TimeSpan tm = dt2.Subtract(dt);
- lblJob.Text = "経過時間:" + tm.TotalSeconds.ToString();
- //pictureBox1.Refresh();
- Refresh();
- }
- //すべてのスレッドの処理が完了したらTrue
- private bool IsThreadJobFix()
- {
- for(int i = 0; i <THREADCOUNT; i++)
- {
- if (m_ThreadJobFixFL[i] == false)
- {
- return false;
- }
- }
- return true;
- }
- //スレッド向けコールバック関数(0番)
- private static void ThreadMethod0()
- {
- m_MyObj.ThreadMainJob0();
- }
- //スレッド向けコールバック関数(1番)
- private static void ThreadMethod1()
- {
- m_MyObj.ThreadMainJob1();
- }
- //スレッド向けコールバック関数(2番)
- private static void ThreadMethod2()
- {
- m_MyObj.ThreadMainJob2();
- }
- //スレッド向けコールバック関数(3番)
- private static void ThreadMethod3()
- {
- m_MyObj.ThreadMainJob3();
- }
- //スレッド向けコールバック関数(4番)
- private static void ThreadMethod4()
- {
- m_MyObj.ThreadMainJob4();
- }
- //スレッドによるグレースケール処理
- private void ThreadMainJob0()
- {
- while(m_ThreadOnFL == true)
- {
- if (m_ThreadJobFL[0] == false)
- {
- Thread.Sleep(1);
- continue;
- }
- GrayScaleB(0, 480, m_SouPT, m_DesPT, m_Width, m_Height);
- m_ThreadJobFL[0] = false;
- m_ThreadJobFixFL[0] = true;
- }
- }
- private void ThreadMainJob1()
- {
- while(m_ThreadOnFL == true)
- {
- if (m_ThreadJobFL[1] == false)
- {
- Thread.Sleep(1);
- continue;
- }
- GrayScaleB(0, 120, m_SouPT, m_DesPT, m_Width, m_Height);
- m_ThreadJobFL[1] = false;
- m_ThreadJobFixFL[1] = true;
- }
- }
- private void ThreadMainJob2()
- {
- while(m_ThreadOnFL == true)
- {
- if (m_ThreadJobFL[2] == false)
- {
- Thread.Sleep(1);
- continue;
- }
- GrayScaleB(120, 240, m_SouPT, m_DesPT, m_Width, m_Height);
- m_ThreadJobFL[2] = false;
- m_ThreadJobFixFL[2] = true;
- }
- }
- private void ThreadMainJob3()
- {
- while(m_ThreadOnFL == true)
- {
- if (m_ThreadJobFL[3] == false)
- {
- Thread.Sleep(1);
- continue;
- }
- GrayScaleB(240, 360, m_SouPT, m_DesPT, m_Width, m_Height);
- m_ThreadJobFL[3] = false;
- m_ThreadJobFixFL[3] = true;
- }
- }
- private void ThreadMainJob4()
- {
- while(m_ThreadOnFL == true)
- {
- if (m_ThreadJobFL[4] == false)
- {
- Thread.Sleep(1);
- continue;
- }
- GrayScaleB(360, 480, m_SouPT, m_DesPT, m_Width, m_Height);
- m_ThreadJobFL[4] = false;
- m_ThreadJobFixFL[4] = true;
- }
- }
- public void GrayScaleB(int startY, int endY, IntPtr ptS, IntPtr ptD, int tmpWidth, int tmpHeight)
- {
- int x, y;
- int index;
- byte PixelData;
- byte red, green, blue;
- int scanl = tmpWidth * 3;
- unsafe
- {
- byte* ps = (byte*)ptS;
- byte* pd = (byte*)ptD;
- for (y = startY; y <endY; y++)
- {
- for (x = 0; x <scanl; x += 3)
- {
- index = (y * scanl) + x;
- blue = ps[index ];
- green = ps[index + 1];
- red = ps[index + 2];
- PixelData = (byte)(0.299f * ((float)red) + 0.587f * ((float)green) + 0.114f * ((float)blue));
- pd[index] = PixelData;
- pd[index + 1] = PixelData;
- pd[index + 2] = PixelData;
- }
- }
- }
- }
- }
- }



