/// <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); }