最新の更新情報

2012年2月
« 1月    
 1234
567891011
12131415161718
19202122232425
26272829  

本ブログのURL

qrcode.png

雨雲の動き

お天気

 
 
吟遊詩人の戯言 内専用の記事検索...
 
 

この前のグレースケール処理 マルチスレッド化してみた


キーワード(クリックで関連記事が読めます) → , , ,

関連記事



 
 

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#:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Drawing.Imaging;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Threading;
  10.  
  11.  
  12. namespace GrayScaleTest
  13. {
  14.     public partial class Form1 : Form
  15.     {
  16.         private const int THREADCOUNT = 5;
  17.  
  18.         static public Form1 m_MyObj;            //スレッドへ情報を渡すため、自分自身のインスタンスをセット
  19.  
  20.         private Bitmap m_ImageBackup;   // 一時データ
  21.         private Bitmap m_bmapIn;        // 入力データ
  22.         private Bitmap m_bmapOut;      // 出力データ
  23.  
  24.         private bool    m_ThreadOnFL;
  25.         private bool[]  m_ThreadJobFL;
  26.         private bool[]  m_ThreadJobFixFL;
  27.  
  28.         private Thread[] m_Thread;
  29.  
  30.         private IntPtr m_SouPT;
  31.         private IntPtr m_DesPT;
  32.         private int m_Width;            // Image サイズ
  33.         private int m_Height;           // Image サイズ
  34.  
  35.  
  36.         public Form1()
  37.         {
  38.             InitializeComponent();
  39.  
  40.             m_MyObj = this;
  41.         }
  42.  
  43.         private void Form1_Load(object sender, EventArgs e)
  44.         {
  45.  
  46.             pictureBox1.Image = null;
  47.  
  48.             m_ThreadOnFL = true;
  49.  
  50.             m_ThreadJobFL    = new bool[THREADCOUNT];
  51.             m_ThreadJobFixFL = new bool[THREADCOUNT];
  52.  
  53.             for (int i = 0; i <THREADCOUNT; i++)
  54.             {
  55.                 m_ThreadJobFL[i]    = false;
  56.                 m_ThreadJobFixFL[i] = false;
  57.             }
  58.  
  59.  
  60.             m_Thread = new Thread[THREADCOUNT];
  61.  
  62.             m_Thread[0] = new Thread(new ThreadStart(ThreadMethod0));
  63.             m_Thread[1] = new Thread(new ThreadStart(ThreadMethod1));
  64.             m_Thread[2] = new Thread(new ThreadStart(ThreadMethod2));
  65.             m_Thread[3] = new Thread(new ThreadStart(ThreadMethod3));
  66.             m_Thread[4] = new Thread(new ThreadStart(ThreadMethod4));
  67.            
  68.             m_Thread[0].Name = "画像処理スレッド0";
  69.             m_Thread[1].Name = "画像処理スレッド1";
  70.             m_Thread[2].Name = "画像処理スレッド2";
  71.             m_Thread[3].Name = "画像処理スレッド3";
  72.             m_Thread[4].Name = "画像処理スレッド4";
  73.  
  74.             m_Thread[0].Start();
  75.             m_Thread[1].Start();
  76.             m_Thread[2].Start();
  77.             m_Thread[3].Start();
  78.             m_Thread[4].Start();
  79.  
  80.         }
  81.  
  82.         private void Form1_FormClosed(object sender, FormClosedEventArgs e)
  83.         {
  84.             m_ThreadOnFL = false;
  85.             for(int i = 0; i <200; i++)
  86.             {
  87.                 Application.DoEvents();
  88.                 Thread.Sleep(1);
  89.             }
  90.         }
  91.  
  92.         private void button1_Click(object sender, EventArgs e)
  93.         {
  94.             string FileName;
  95.  
  96.             if (openFileDialog1.ShowDialog() != DialogResult.OK)
  97.             {
  98.                 return;
  99.             }
  100.             FileName = openFileDialog1.FileName;
  101.  
  102.             m_ImageBackup = new Bitmap(FileName);
  103.             m_Width = m_ImageBackup.Width;
  104.             m_Height = m_ImageBackup.Height;
  105.             m_bmapOut = new Bitmap(m_Width, m_Height);
  106.  
  107.             m_bmapIn = m_ImageBackup;
  108.  
  109.             pictureBox1.Image = m_bmapIn;
  110.  
  111.         }
  112.  
  113.  
  114.         private void JobCore_Click(object sender, EventArgs e)
  115.         {
  116.             DateTime dt = DateTime.Now
  117.  
  118.             int min  = dt.Minute;
  119.             int sec  = dt.Second;
  120.             int mili = dt.Millisecond
  121.  
  122.             lblStart.Text = "";
  123.             lblEnd.Text   = "";
  124.             lblJob.Text   = "";
  125.  
  126.             lblStart.Text = "開始時間:" + min.ToString() + "_" + sec.ToString() + "_" + mili.ToString();
  127.  
  128.             Refresh();
  129.  
  130.             Bitmap bd = pictureBox1.Image as Bitmap;
  131.             Bitmap bs;
  132.  
  133.             BitmapData bDataInS;
  134.             BitmapData bDataInD;
  135.             IntPtr Scan0_InS;     // ピクセルデータの開始アドレス
  136.             IntPtr Scan0_InD;     // ピクセルデータの開始アドレス
  137.             bs = new Bitmap(m_bmapIn);
  138.  
  139.             bDataInS = bs.LockBits(new Rectangle(0, 0, bs.Width, bs.Height),
  140.                                 ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  141.             Scan0_InS = bDataInS.Scan0;  // ピクセルデータの開始アドレス
  142.  
  143.             bDataInD = bd.LockBits(new Rectangle(0, 0, bd.Width, bd.Height),
  144.                                 ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  145.             Scan0_InD = bDataInD.Scan0;  // ピクセルデータの開始アドレス
  146.  
  147.  
  148.             m_SouPT  = Scan0_InS;
  149.             m_DesPT  = Scan0_InD;
  150.             m_Width  = bd.Width;
  151.             m_Height = bd.Height;
  152.  
  153.             if (sender == button2)
  154.             {
  155.  
  156.                 for(int j = 1; j <THREADCOUNT; j++)
  157.                 {
  158.                     m_ThreadJobFixFL[j] = true;         //スレッド処理完了フラグ (0番以外は完了させておく)
  159.                     m_ThreadJobFL[j]    = false;        //スレッド処理開始フラグ(0番起動 以外は停止)
  160.                 }
  161.                 for(int i = 0; i <1000; i++)           //スレッド0番(480ライン処理)のみ起動
  162.                 {
  163.                     m_ThreadJobFixFL[0] = false;        //スレッド処理完了フラグ (0番以外は完了させておく)
  164.                     m_ThreadJobFL[0] = true;            //スレッド処理開始フラグ(0番起動 以外は停止)
  165.  
  166.                     while(IsThreadJobFix() == false )            //全スレッドの処理が完了するまで待機
  167.                     {
  168.                         Thread.Sleep(1);
  169.                     }
  170.                 }
  171.  
  172.             }
  173.             else
  174.             {
  175.                 m_ThreadJobFixFL[0] = true;         //スレッド処理完了フラグ (0番は完了させておく)
  176.                 m_ThreadJobFL[0]    = false;        //スレッド処理開始フラグ(0番停止 以外は起動)
  177.  
  178.                 for(int i = 0; i <1000; i++)           //スレッド1番2番(240ライン処理)のみ起動
  179.                 {
  180.                     for(int j = 1; j <THREADCOUNT; j++)
  181.                     {
  182.                         m_ThreadJobFixFL[j] = false;        //スレッド処理完了フラグ (0番は完了させておく)
  183.                         m_ThreadJobFL[j] = true;            //スレッド処理開始フラグ(0番停止 以外は起動)
  184.                     }
  185.                     while(IsThreadJobFix() == false )            //全スレッドの処理が完了するまで待機
  186.                     {
  187.                         Thread.Sleep(1);
  188.                     }
  189.                 }
  190.             }
  191.  
  192.             bd.UnlockBits(bDataInD);
  193.             bs.UnlockBits(bDataInS);
  194.  
  195.             DateTime dt2 = DateTime.Now
  196.             min  = dt2.Minute;
  197.             sec  = dt2.Second;
  198.             mili = dt2.Millisecond
  199.  
  200.             lblEnd.Text = "終了時間:" + min.ToString() + "_" + sec.ToString() + "_" + mili.ToString();;
  201.  
  202.             TimeSpan tm = dt2.Subtract(dt);
  203.  
  204.             lblJob.Text = "経過時間:" + tm.TotalSeconds.ToString();
  205.  
  206.             //pictureBox1.Refresh();
  207.             Refresh();
  208.         }
  209.  
  210.  
  211.  
  212.         //すべてのスレッドの処理が完了したらTrue
  213.         private bool IsThreadJobFix()
  214.         {
  215.             for(int i = 0; i <THREADCOUNT; i++)
  216.             {
  217.                 if (m_ThreadJobFixFL[i] == false)
  218.                 {
  219.                     return false;
  220.                 }
  221.             }
  222.  
  223.             return true;
  224.         }
  225.  
  226.         //スレッド向けコールバック関数(0番)
  227.         private static void ThreadMethod0()
  228.         {
  229.             m_MyObj.ThreadMainJob0();
  230.         }
  231.  
  232.         //スレッド向けコールバック関数(1番)
  233.         private static void ThreadMethod1()
  234.         {
  235.             m_MyObj.ThreadMainJob1();
  236.         }
  237.  
  238.         //スレッド向けコールバック関数(2番)
  239.         private static void ThreadMethod2()
  240.         {
  241.             m_MyObj.ThreadMainJob2();
  242.         }
  243.  
  244.         //スレッド向けコールバック関数(3番)
  245.         private static void ThreadMethod3()
  246.         {
  247.             m_MyObj.ThreadMainJob3();
  248.         }
  249.  
  250.         //スレッド向けコールバック関数(4番)
  251.         private static void ThreadMethod4()
  252.         {
  253.             m_MyObj.ThreadMainJob4();
  254.         }
  255.  
  256.  
  257.         //スレッドによるグレースケール処理
  258.         private void ThreadMainJob0()
  259.         {
  260.             while(m_ThreadOnFL == true)
  261.             {
  262.                 if (m_ThreadJobFL[0] == false)
  263.                 {
  264.                     Thread.Sleep(1);
  265.                     continue;
  266.                 }
  267.  
  268.                 GrayScaleB(0, 480, m_SouPT, m_DesPT, m_Width, m_Height);
  269.  
  270.                 m_ThreadJobFL[0]      = false;
  271.                 m_ThreadJobFixFL[0]   = true;
  272.             }
  273.         }
  274.  
  275.         private void ThreadMainJob1()
  276.         {
  277.             while(m_ThreadOnFL == true)
  278.             {
  279.                 if (m_ThreadJobFL[1] == false)
  280.                 {
  281.                     Thread.Sleep(1);
  282.                     continue;
  283.                 }
  284.  
  285.                 GrayScaleB(0, 120, m_SouPT, m_DesPT, m_Width, m_Height);
  286.  
  287.                 m_ThreadJobFL[1]      = false;
  288.                 m_ThreadJobFixFL[1]   = true;
  289.             }
  290.         }
  291.  
  292.         private void ThreadMainJob2()
  293.         {
  294.             while(m_ThreadOnFL == true)
  295.             {
  296.                 if (m_ThreadJobFL[2] == false)
  297.                 {
  298.                     Thread.Sleep(1);
  299.                     continue;
  300.                 }
  301.  
  302.                 GrayScaleB(120, 240, m_SouPT, m_DesPT, m_Width, m_Height);
  303.  
  304.                 m_ThreadJobFL[2]      = false;
  305.                 m_ThreadJobFixFL[2]   = true;
  306.             }
  307.         }
  308.  
  309.         private void ThreadMainJob3()
  310.         {
  311.             while(m_ThreadOnFL == true)
  312.             {
  313.                 if (m_ThreadJobFL[3] == false)
  314.                 {
  315.                     Thread.Sleep(1);
  316.                     continue;
  317.                 }
  318.  
  319.                 GrayScaleB(240, 360, m_SouPT, m_DesPT, m_Width, m_Height);
  320.  
  321.                 m_ThreadJobFL[3]      = false;
  322.                 m_ThreadJobFixFL[3]   = true;
  323.             }
  324.         }
  325.  
  326.         private void ThreadMainJob4()
  327.         {
  328.             while(m_ThreadOnFL == true)
  329.             {
  330.                 if (m_ThreadJobFL[4] == false)
  331.                 {
  332.                     Thread.Sleep(1);
  333.                     continue;
  334.                 }
  335.  
  336.                 GrayScaleB(360, 480, m_SouPT, m_DesPT, m_Width, m_Height);
  337.  
  338.                 m_ThreadJobFL[4]      = false;
  339.                 m_ThreadJobFixFL[4]   = true;
  340.             }
  341.         }
  342.  
  343.         public void GrayScaleB(int startY, int endY, IntPtr ptS, IntPtr ptD, int tmpWidth, int tmpHeight)
  344.         {
  345.             int x, y;
  346.             int index;
  347.             byte PixelData;
  348.             byte red, green, blue;
  349.  
  350.             int scanl = tmpWidth * 3;
  351.  
  352.             unsafe
  353.             {
  354.                 byte* ps = (byte*)ptS;
  355.                 byte* pd = (byte*)ptD;
  356.  
  357.                 for (y = startY; y <endY; y++)
  358.                 {
  359.                     for (x = 0; x <scanl; x += 3)
  360.                     {
  361.                         index = (y * scanl) + x;
  362.  
  363.                         blue  = ps[index ];
  364.                         green = ps[index + 1];
  365.                         red   = ps[index + 2];
  366.  
  367.                         PixelData = (byte)(0.299f * ((float)red) + 0.587f * ((float)green) + 0.114f * ((float)blue));
  368.  
  369.                         pd[index]     = PixelData;
  370.                         pd[index + 1] = PixelData;
  371.                         pd[index + 2] = PixelData;
  372.  
  373.                     }
  374.                 }
  375.             }
  376.         }
  377.  
  378.     }
  379. }

 
 
 
 

Comments are closed.