您的位置:首页 > 其它

使用.net4.0中的并行计算来处PI值,及多线程处理比较

2009-10-13 15:14 288 查看
看到另一位老兄介绍的NET4.0并行计算(http://blog.csdn.net/bitfan/archive/2009/09/09/4534359.aspx),忍不住下载了一个2010BETA来试试。



实验后的结果表明并行计算的最终效果还是比较明显的,更主要是非常简单。



用计算PI的结果来做实验,算法来自:http://en.wikipedia.org/wiki/Pi

贴一下:)





先用传统的算法、多线程、然后用并行算法。比较结果如下(环境:CPU(双核 T5600 1.83G*2) + 2.5G内存 + WinXPsp2):



让人意外的结果,基本上并行没有带来什么性能提升。



以下的结果是在另一机器上测得(CPU E8400:双核 3.0G*2 + 2G内存 + win2003Server)





上两张图的明显不同是:CPU的的第一次处理曲线。在2003Server的机器上两个核基本上负担相同。

(是不是在2003SERVER下,已经有过处理均衡优化了?!)





先不管并行有没有带来什么提升性能,2010中的并行处理的确太简单了,只要有多线程的编程经验就足够



下面贴代码(有问题请大家指出来)

class CPICacu
    {
        const int iTruncatedNum = 100;
        const int m_iCacuTimes = 5000000;
        byte[] m_bytaryResult1 = new byte[iTruncatedNum];
        byte[] m_bytaryResult2 = new byte[iTruncatedNum];
        bool m_bFinish1 = false;
        bool m_bFinish2 = false;
        void Cacu1()
        {
            byte[] bytaryTmp = new byte[iTruncatedNum];
            int iTopValue = 4;
            int iBaseValue = 1;
            for (int i = 0; i < m_iCacuTimes; i += 2)
            {
                iTopValue = 4;
                int j = 0;
                //计算一个分式
                for (; j < iTruncatedNum; ++j)
                {
                    bytaryTmp[j] = 0;
                    if (iTopValue == 0)
                        continue;
                    while (iTopValue >= iBaseValue)
                    {
                        bytaryTmp[j] += 1;
                        iTopValue -= iBaseValue;
                    }
                    iTopValue *= 10;
                }
                //把计算出来的值相加
                int iNeedIncrease = 0;
                for (j = iTruncatedNum - 1; j >= 0; --j)
                {
                    iTopValue = m_bytaryResult1[j] + bytaryTmp[j] + iNeedIncrease;
                    System.Diagnostics.Debug.Assert(iTopValue < 20);
                    if (iTopValue > 9)
                    {
                        m_bytaryResult1[j] = Convert.ToByte(iTopValue % 10);
                        iNeedIncrease = (iTopValue - m_bytaryResult1[j]) - 9;
                    }
                    else
                    {
                        m_bytaryResult1[j] = Convert.ToByte(iTopValue);
                        iNeedIncrease = 0;
                    }
                }
                iBaseValue += 2 + 2;
            }
            m_bFinish1 = true;
        }
        void Cacu2()
        {
            byte[] bytaryTmp = new byte[iTruncatedNum];
            int iTopValue = 4;
            int iBaseValue = 1+2;
            for (int i = 0; i < m_iCacuTimes; i += 2)
            {
                iTopValue = 4;
                int j = 0;
                //计算一个分式
                for (; j < iTruncatedNum; ++j)
                {
                    bytaryTmp[j] = 0;
                    if (iTopValue == 0)
                        continue;
                    while (iTopValue >= iBaseValue)
                    {
                        bytaryTmp[j] += 1;
                        iTopValue -= iBaseValue;
                    }
                    iTopValue *= 10;
                }
                //把计算出来的值相加
                int iNeedIncrease = 0;
                for (j = iTruncatedNum - 1; j >= 0; --j)
                {
                    iTopValue = m_bytaryResult2[j] + bytaryTmp[j] + iNeedIncrease;
                    System.Diagnostics.Debug.Assert(iTopValue < 20);
                    if (iTopValue > 9)
                    {
                        m_bytaryResult2[j] = Convert.ToByte(iTopValue % 10);
                        iNeedIncrease = (iTopValue - m_bytaryResult2[j]) - 9;
                    }
                    else
                    {
                        m_bytaryResult2[j] = Convert.ToByte(iTopValue);
                        iNeedIncrease = 0;
                    }
                }
                iBaseValue += 2 + 2;
            }
            m_bFinish2 = true;
        }
        public void Cacu()
        {
            System.Action[] aryAction = new Action[]{ this.Cacu1,this.Cacu2};
            System.Threading.Parallel.Invoke(aryAction);
            //sub the two arrary
            Program.SubArray(m_bytaryResult1, m_bytaryResult2);
            for (int i = 0; i < iTruncatedNum; ++i)
                System.Console.Write(m_bytaryResult1[i]);
        }
        public void CacuByThread()
        {
            System.Threading.Thread thd0 = new System.Threading.Thread(new System.Threading.ThreadStart(Cacu1));
            System.Threading.Thread thd1 = new System.Threading.Thread(new System.Threading.ThreadStart(Cacu2));
            thd0.Start();
            thd1.Start();
            m_bFinish1 = m_bFinish2 = false;
            while (m_bFinish1 != true || m_bFinish2 != true) System.Threading.Thread.Sleep(1);
            //sub the two arrary
            Program.SubArray(m_bytaryResult1, m_bytaryResult2);
            for (int i = 0; i < iTruncatedNum; ++i)
                System.Console.Write(m_bytaryResult1[i]);
        }
    }
    class Program
    {
        public static void SubArray( byte[] bytaryOne,byte[] bytaryTwo )
        {
            int iTmp = 0,iNeedIncrease = 0;
            for (int j = bytaryOne.Length - 1; j >= 0; --j)
            {
                iTmp = bytaryOne[j] - bytaryTwo[j] + iNeedIncrease;
                System.Diagnostics.Debug.Assert(iTmp >= -10);
                if (iTmp < 0)
                {
                    iTmp += 10;
                    System.Diagnostics.Debug.Assert(iTmp >= 0);
                    iNeedIncrease = -1;
                }
                else
                {
                    iNeedIncrease = 0;
                }
                bytaryOne[j] = Convert.ToByte(iTmp);
            }
        }
        public static void CacuPITrid()
        {
            int iTruncatedNum = 100;
            byte[] bytaryResult = new byte[iTruncatedNum];
            byte[] bytaryTmp = new byte[iTruncatedNum];
            int iTopValue = 4;
            int iBaseValue = 1;
            bool bAdd = true;
            for (int i = 0; i < 5000000; ++i)
            {
                iTopValue = 4;
                int j = 0;
                //计算一个分式
                for (; j < iTruncatedNum; ++j)
                {
                    bytaryTmp[j] = 0;
                    if (iTopValue == 0)
                        continue;
                    while (iTopValue >= iBaseValue)
                    {
                        bytaryTmp[j] += 1;
                        iTopValue -= iBaseValue;
                    }
                    iTopValue *= 10;
                }
                //把计算出来的值相加
                int iNeedIncrease = 0;
                if (bAdd)
                {
                    for (j = iTruncatedNum - 1; j >= 0; --j)
                    {
                        iTopValue = bytaryResult[j] + bytaryTmp[j] + iNeedIncrease;
                        System.Diagnostics.Debug.Assert(iTopValue < 20);
                        if (iTopValue > 9)
                        {
                            bytaryResult[j] = Convert.ToByte(iTopValue % 10);
                            iNeedIncrease = (iTopValue - bytaryResult[j]) - 9;
                        }
                        else
                        {
                            bytaryResult[j] = Convert.ToByte(iTopValue);
                            iNeedIncrease = 0;
                        }
                    }
                }
                else
                {
                    for (j = iTruncatedNum - 1; j >= 0; --j)
                    {
                        iTopValue = bytaryResult[j] - bytaryTmp[j] + iNeedIncrease;
                        System.Diagnostics.Debug.Assert(iTopValue >= -10);
                        if (iTopValue < 0)
                        {
                            iTopValue += 10;
                            System.Diagnostics.Debug.Assert(iTopValue >= 0);
                            iNeedIncrease = -1;
                        }
                        else
                        {
                            iNeedIncrease = 0;
                        }
                        bytaryResult[j] = Convert.ToByte(iTopValue);
                    }
                }
                iBaseValue += 2;
                bAdd = !bAdd;
            }
            for (int i = 0; i < iTruncatedNum; ++i)
                System.Console.Write(bytaryResult[i]);
        }
        
        static void Main(string[] args)
        {
            System.Console.WriteLine("Traditional algorithm.../n");
            DateTime dteStart = DateTime.Now;
            CacuPITrid();
            TimeSpan ts = DateTime.Now - dteStart;
            System.Console.WriteLine("/nTotal used:" + ts.ToString());
            System.Console.WriteLine("/nMulti-Thread algorithm.../n");
            dteStart = DateTime.Now;
            CPICacu parrallelPICacu = new CPICacu();
            parrallelPICacu.CacuByThread();
            ts = DateTime.Now - dteStart;
            System.Console.WriteLine("/nTotal used:" + ts.ToString());
            System.Console.WriteLine("/nParallel algorithm.../n");
            dteStart = DateTime.Now;
            CPICacu parrallelPICacu1 = new CPICacu();
            parrallelPICacu1.Cacu();
            ts = DateTime.Now - dteStart;
            System.Console.WriteLine("/nTotal used:" + ts.ToString());
            System.Console.Read();
        }
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: