Hybird3D

乔捷的技术博客

博客园 首页 新随笔 联系 订阅 管理

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;
        }
    }
}
posted on 2010-02-25 18:07  qiaojie  阅读(7762)  评论(0编辑  收藏  举报