• 也谈并行计算(一)C#版的Parallel.For实现


    Parallel.For可以算是并行计算的基石了,有了他可以解决90%以上的并行计算问题。当然了,他的实现实在是简单的不值一提,先发一个我写的C#实现,下回我们就以它为基础来讲解如何实现并行计算。对于已经使用.net 4.0的同学请自动无视该实现。

    static class Parallel
    {
        public delegate void Kernel();
        public delegate void KernelFor(int index);
    
        [ThreadStaticAttribute]
        static int currId;
    
        class Worker
        {
            int id;
            EventWaitHandle[] events = new EventWaitHandle[2];
            public EventWaitHandle endEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
            Thread thread;
            Kernel kernel;
    
            void Start()
            {
                Parallel.currId = id;
    
                while(true)
                {
                    int ret = EventWaitHandle.WaitAny(events, -1);
                    if(ret == 0)
                    {
                        kernel();
                        endEvent.Set();
                    }
                    else
                        break;
                }
            }
    
            public Worker(int i)
            {
                id = i;
                events[0] = new EventWaitHandle(false, EventResetMode.AutoReset);
                events[1] = new EventWaitHandle(false, EventResetMode.AutoReset);
    
                thread = new Thread(new ThreadStart(this.Start));
                thread.Start();
            }
    
            public void Exit()
            {
                events[1].Set();
                thread.Join();
            }
    
            public void Run(Kernel kernel)
            {
                this.kernel = kernel;
                events[0].Set();
            }
        }
    
        static Worker[] workers;
        static WaitHandle[] endEvents;
    
        static public void Initialize(int maxThread)
        {
            if(maxThread <= 0)
                maxThread = Environment.ProcessorCount;
    
            workers = new Worker[maxThread];
            endEvents = new WaitHandle[maxThread];
    
            for(int i = 0; i < workers.Length; ++i)
            {
                workers[i] = new Worker(i);
                endEvents[i] = workers[i].endEvent;
            }
        }
    
        static public void Destroy()
        {
            for(int i = 0; i < workers.Length; ++i)
                workers[i].Exit();
        }
    
        static public void For(int from, int to, KernelFor kernel)
        {
            int index = from;
    
            for(int i = 0; i < workers.Length; ++i)
                workers[i].Run(delegate()
                {
                    while(true)
                    {
                        int j = Interlocked.Increment(ref index);
                        if(j >= to)
                            break;
                        kernel(j - 1);
                    }
                });
    
            WaitHandle.WaitAll(endEvents);
        }
    
        static public int WorkerCount
        {
            get
            {
                return workers.Length;
            }
        }
    
        static public int CurrentWorkerId
        {
            get
            {
                return currId;
            }
        }
    }
  • 相关阅读:
    【转】PLSQL developer 连接不上64位Oracle 的解决方法
    Cadence 错误合集
    二十三、原理图和PCB交互式布局
    二十二、导入DXF文件
    二十一、打开和关闭飞线
    电源设计基础(罗伯特.A.曼马诺) TI电源书籍
    ORA-01033: ORACLE initialization or shutdown in progress 实用的处理方法
    转载“启动关闭Oracle数据库的多种方法”--来自百度#Oracle
    vue+django+mysql前后端分离的课程管理系统
    webshell扫描器
  • 原文地址:https://www.cnblogs.com/Hybird3D/p/1673720.html
Copyright © 2020-2023  润新知