机器学习和生物信息学实验室联盟

标题: 关于多线程及什么时候使用多线程 [打印本页]

作者: chenlin    时间: 2011-6-29 15:37
标题: 关于多线程及什么时候使用多线程
多线程使用System.Threading类

以下是一个例子

class Fibonacci
    {
        //share
        public static int [] item; //read from it
        public static int[] result; //write into it
        //instance
        public int N { get { return _n; } }
        public int _start, _end;
        private int _n;

        public int FibOfN { get { return _fibOfN; } }
        private int _fibOfN;

        private ManualResetEvent _doneEvent;

        public Fibonacci(int start, int end, ManualResetEvent doneEvent)
        {
            _start = start;
            _end = end;
            _doneEvent = doneEvent;
        }

        public Fibonacci(int start, int end)
        {
            _start = start;
            _end = end;
        }

        // Wrapper method for use with thread pool.
        public void ThreadPoolCallback(Object threadContext)
        {
            int threadIndex = (int)threadContext;

            Calculate();

            _doneEvent.Set();
        }

        // Recursive method that calculates the Nth Fibonacci number.
        public void    Calculate()
        {
            for (int i = _start; i < _end; i++)
            {
                int d = item[i];
                for (int j = 0; j < 10000; j++) //注意,这里设置大值使单个线程对单个共享数据的运算时间较大
                    d += 0;
                lock(this) //在本程序中可以不加,因为没有互斥
                      result[i] = d;
            }
        }



    }

    class TestThreading
    {
        public static void test()
        {
            Fibonacci.item = new int[10000];
            Fibonacci.result = new int[10000];
            for (int i = 0; i < 10000; i++)
            {
                Fibonacci.item[i] = i + 1;
               
            }
            Stopwatch watch = new Stopwatch();
            watch.Start();
            Fibonacci f = new Fibonacci(0, 10000);
            f.Calculate();
            watch.Stop();
            Console.WriteLine("Time no thrading takes " + watch.Elapsed);
            Console.ReadLine();
            for (int i = 0; i < 10000; i++)
            {
                Console.Write(Fibonacci.result[i] + " ");
            }
            Console.ReadLine();

            //thread 5
            watch = new Stopwatch();
            watch.Start();
            Fibonacci[] fibarray = new Fibonacci[5];
            ManualResetEvent[] doneEvents = new ManualResetEvent[5];

            for (int i = 0; i < 5; i++)
            {
                int start = i * 2000;
                int end = (i + 1) * 2000;
                doneEvents[i] = new ManualResetEvent(false);
                fibarray [i] = new Fibonacci (start ,end ,doneEvents[i]);
                ThreadPool.QueueUserWorkItem(fibarray[i].ThreadPoolCallback, i);
            }
            WaitHandle.WaitAll(doneEvents);
            watch.Stop();
            Console.WriteLine("Time 5 threads takes " + watch.Elapsed);
            Console.ReadLine();
            for (int i = 0; i < 10000; i++)
            {
                Console.Write(Fibonacci.result[i] + " ");
            }
            Console.ReadLine();

        }
    }


需要注意的一点就是,如果多个线程访问同一个数据效率是没有提升反而因为线程初始化等开销加大
这就是为什么上面的J如果是小的数目,比如5,多线程效率反而不如单线程
作者: chenlin    时间: 2011-6-29 15:38
郁闷,这么说来我的优化过程还是要很长了
作者: zouquan    时间: 2011-6-29 16:33
肯定的啊,
多线程本质上是并行,
斐波那契序列这种问题每一次运算都要用到前一次运算的结果,无法用并行的思想。
多线程应该处理在一堆数中找最大数这类问题,应该有效率;
建议明年去听我讲算法:D
作者: sunyuanshuai    时间: 2011-6-29 19:18
对于同一数据操作系统貌似有一个保护机制,在同一时刻只能有一个线程写数据,其他线程只能排队等待,所以不会提高很多。对于可以采用分治方法解决得问题,用多线程效率会提高很多。
作者: chenlin    时间: 2011-6-29 22:27
不知道稀疏矩阵怎么分治...现在做的矩阵分解模型太占内存也太耗时了:(
作者: blue_friday    时间: 2012-9-17 11:50
操作系统只能读并行,写串行,这是读写锁的保护机制

作者: chenwq    时间: 2012-9-17 18:46
Orz... 理论与实践并重的达人.




欢迎光临 机器学习和生物信息学实验室联盟 (http://123.57.240.48/) Powered by Discuz! X3.2