Ejemplo n.º 1
0
        /// <summary>
        /// Helps spreading the same repetetive workload over multiple threads/cores in an easy way.
        /// </summary>
        /// <typeparam name="D">Generic-Type of the delegate that will be executed and compute the workload</typeparam>
        /// <typeparam name="T">Generic-Type of the object you want to be computed by the executor</typeparam>
        /// <param name="executor">A (static) method that computes one workLoad-object at a time</param>
        /// <param name="workLoad">An array with objects you want to get computed by the executor</param>
        /// <param name="onComplete">Fired when all re-packaged workLoad-objects are finished computing</param>
        /// <param name="onPackageComplete">Fires foreach finished re-packaged set of workLoad-object</param>
        /// <param name="maxThreads"> Lets you choose how many threads will be run simultaneously by the threadpool. Default: -1 == number of cores minus one, to make sure the MainThread has at least one Core to run on. (quadcore == 1 Core Mainthread, 3 cores used by the ThreadPoolScheduler)</param>
        /// <param name="scheduler">If Null, a new ThreadPoolScheduler will be instantiated.</param>
        /// <param name="safeMode">Executes all the computations within try-catch events, logging it the message + stacktrace</param>
        /// <returns>A ThreadPoolScheduler that handles all the repackaged workLoad-Objects =</returns>
        public static ThreadPoolScheduler StartMultithreadedWorkloadExecution <D, T>(D executor, T[] workLoad, object extraArgument, MultithreadedWorkloadComplete <T> onComplete, MultithreadedWorkloadPackageComplete <T> onPackageComplete, int maxThreads = -1, ThreadPoolScheduler scheduler = null, bool safeMode = true)
        {
            if (scheduler == null)
            {
                scheduler = Loom.CreateThreadPoolScheduler();
            }
            else if (scheduler.isBusy)
            {
                Debug.LogError("Provided Scheduler stil busy!!!");
            }

            if (maxThreads <= 0)
            {
                maxThreads = Mathf.Max(SystemInfo.processorCount - 1, 1);
            }

            int packagesPerThread = 1;

            if (maxThreads > 1) //If we are running in just one thread at a time, just use one, if more, for sake of better cpu-saturation, subdive into smaller packages per Core.
            {
                packagesPerThread = 2;
            }

            int packages          = Mathf.Min(maxThreads * packagesPerThread, workLoad.Length);
            int objectsPerPackage = (int)Mathf.Ceil((float)workLoad.Length / (float)packages);

            ThreadWorkDistribution <T>[] workerPackages = new ThreadWorkDistribution <T> [packages];
            Type delegateType = typeof(D);
            //Debug.Log(delegateType.FullName);

            int count = 0;

            for (int i = 0; i < packages; i++)
            {
                int packagedSize = Mathf.Min(workLoad.Length - count, objectsPerPackage);
                if (delegateType == typeof(ThreadWorkloadExecutor <T>))
                {
                    workerPackages[i] = new ThreadWorkDistribution <T>((executor as ThreadWorkloadExecutor <T>), workLoad, count, count + packagedSize);
                }
                else if (delegateType == typeof(ThreadWorkloadExecutorIndexed <T>))
                {
                    workerPackages[i] = new ThreadWorkDistribution <T>((executor as ThreadWorkloadExecutorIndexed <T>), workLoad, count, count + packagedSize);
                }
                else if (delegateType == typeof(ThreadWorkloadExecutorArg <T>))
                {
                    workerPackages[i] = new ThreadWorkDistribution <T>((executor as ThreadWorkloadExecutorArg <T>), workLoad, extraArgument, count, count + packagedSize);
                }
                else if (delegateType == typeof(ThreadWorkloadExecutorArgIndexed <T>))
                {
                    workerPackages[i] = new ThreadWorkDistribution <T>((executor as ThreadWorkloadExecutorArgIndexed <T>), workLoad, extraArgument, count, count + packagedSize);
                }

                workerPackages[i].ID = i;
                count += objectsPerPackage;
            }



            //--------------- Store session data --------------------
            ThreadWorkDistributionSession <T> sessionData = new ThreadWorkDistributionSession <T>();

            sessionData.workLoad          = workLoad;
            sessionData.onComplete        = onComplete;
            sessionData.onPackageComplete = onPackageComplete;
            sessionData.packages          = workerPackages;
            //--------------- Store session data --------------------


            scheduler.StartASyncThreads(workerPackages, sessionData.onCompleteBubble, sessionData.onPackageCompleteBubble, maxThreads, safeMode);
            return(scheduler);
        }
        public static ThreadPoolScheduler StartMultithreadedWorkloadExecution <D, T>(D executor, T[] workLoad, object extraArgument, MultithreadedWorkloadComplete <T> onComplete, MultithreadedWorkloadPackageComplete <T> onPackageComplete, int maxThreads = -1, ThreadPoolScheduler scheduler = null, bool safeMode = true)
        {
            bool flag = scheduler == null;

            if (flag)
            {
                scheduler = Loom.CreateThreadPoolScheduler();
            }
            else
            {
                bool isBusy = scheduler.isBusy;
                if (isBusy)
                {
                    Debug.LogError("Provided Scheduler stil busy!!!");
                }
            }
            bool flag2 = maxThreads <= 0;

            if (flag2)
            {
                maxThreads = Mathf.Max(SystemInfo.processorCount - 1, 1);
            }
            int  num   = 1;
            bool flag3 = maxThreads > 1;

            if (flag3)
            {
                num = 2;
            }
            int num2 = Mathf.Min(maxThreads * num, workLoad.Length);
            int num3 = (int)Mathf.Ceil((float)workLoad.Length / (float)num2);

            ThreadWorkDistribution <T>[] array = new ThreadWorkDistribution <T> [num2];
            Type typeFromHandle = typeof(D);
            int  num4           = 0;
            int  num6;

            for (int i = 0; i < num2; i = num6 + 1)
            {
                int  num5  = Mathf.Min(workLoad.Length - num4, num3);
                bool flag4 = typeFromHandle == typeof(ThreadWorkloadExecutor <T>);
                if (flag4)
                {
                    array[i] = new ThreadWorkDistribution <T>(executor as ThreadWorkloadExecutor <T>, workLoad, num4, num4 + num5);
                }
                else
                {
                    bool flag5 = typeFromHandle == typeof(ThreadWorkloadExecutorIndexed <T>);
                    if (flag5)
                    {
                        array[i] = new ThreadWorkDistribution <T>(executor as ThreadWorkloadExecutorIndexed <T>, workLoad, num4, num4 + num5);
                    }
                    else
                    {
                        bool flag6 = typeFromHandle == typeof(ThreadWorkloadExecutorArg <T>);
                        if (flag6)
                        {
                            array[i] = new ThreadWorkDistribution <T>(executor as ThreadWorkloadExecutorArg <T>, workLoad, extraArgument, num4, num4 + num5);
                        }
                        else
                        {
                            bool flag7 = typeFromHandle == typeof(ThreadWorkloadExecutorArgIndexed <T>);
                            if (flag7)
                            {
                                array[i] = new ThreadWorkDistribution <T>(executor as ThreadWorkloadExecutorArgIndexed <T>, workLoad, extraArgument, num4, num4 + num5);
                            }
                        }
                    }
                }
                array[i].ID = i;
                num4       += num3;
                num6        = i;
            }
            ThreadWorkDistributionSession <T> threadWorkDistributionSession = new ThreadWorkDistributionSession <T>();

            threadWorkDistributionSession.workLoad          = workLoad;
            threadWorkDistributionSession.onComplete        = onComplete;
            threadWorkDistributionSession.onPackageComplete = onPackageComplete;
            threadWorkDistributionSession.packages          = array;
            scheduler.StartASyncThreads(array, new ThreadPoolSchedulerEvent(threadWorkDistributionSession.onCompleteBubble), new ThreadedWorkCompleteEvent(threadWorkDistributionSession.onPackageCompleteBubble), maxThreads, safeMode);
            return(scheduler);
        }