private static List <string> GenerateTree( ICompiledGram gram, CircularQueue <string> prior, int size, int index, List <string> acceptedTypes, Func <string, string> classifier) { string[] guesses = gram.GetGuesses(prior.ToArray()); foreach (string guess in guesses) { if (classifier != null && !classifier(guess).Equals(acceptedTypes[index])) { continue; } CircularQueue <string> newPrior = prior.Clone(); newPrior.Add(guess); if (size <= 1) { return(new List <string>() { guess }); } else if (gram.HasNextStep(newPrior.ToArray())) { List <string> returnVal = GenerateTree( gram, newPrior, size - 1, index + 1, acceptedTypes, classifier); if (returnVal != null) { returnVal.Insert(0, guess); return(returnVal); } } } return(null); }
/// <summary>Initializes the scheduler.</summary> /// <param name="threadOnCpu">how many threads will be created per cpu. recommanded is 1 or 2.</param> /// <param name="cpusPerThread">When creating a thread, on how many cpus should it be distributed on? When there are: 4 cpus, <paramref name="threadCount"/> is 4 then each thread will be assinged into two cpus. thread1 to cpu1 and cpu2, thread2 to cpu2 and cpu3, thread 3 to cpu3 and cpu4, thread 4 to cpu4 and cpu1.</param> public DistributedQueuedTaskScheduler(int cpusPerThread, int threadOnCpu, int cpus = -1, string threadName = "", ThreadPriority threadPriority = ThreadPriority.Normal, ApartmentState threadApartmentState = ApartmentState.MTA, int threadMaxStackSize = 0, Action threadInit = null, Action threadFinally = null, CancellationToken?cancellationToken = null) { if (cpusPerThread <= 0) { throw new ArgumentOutOfRangeException(nameof(cpusPerThread)); } if (threadOnCpu <= 0) { throw new ArgumentOutOfRangeException(nameof(threadOnCpu)); } if (cpus < 0) { cpus = Environment.ProcessorCount; } var threadCount = threadOnCpu * cpus; var threads = new DistributedThread[threadCount]; for (int i = 0; i < threadCount; i++) { threads[i] = new DistributedThread(() => ThreadBasedDispatchLoop(threadInit, threadFinally), threadMaxStackSize) { Priority = threadPriority, IsBackground = true, Name = $"[{(threadName ?? "QWorker ")}] {i}" }; threads[i].SetApartmentState(threadApartmentState); } var possibleAffinities = new CircularQueue <int>(); for (int i = 0; i < cpus; i++) { //popular possibleAffinities.Enqueue(1 << i); } for (int i = 0; i < threadCount; i++) { var thread = threads[i]; thread.ProcessorAffinity = 0; var clone = (CircularQueue <int>)possibleAffinities.Clone(); possibleAffinities.Dequeue(); //move forward by one for (int x = 0; x < cpusPerThread; x++) { thread.ProcessorAffinity |= clone.Dequeue(); } } _disposeCancellation = new CancellationTokenSource(); _sharedCancellation = cancellationToken.HasValue ? CancellationTokenSource.CreateLinkedTokenSource(_disposeCancellation.Token, cancellationToken.Value) : _disposeCancellation; _concurrencyLevel = threadCount; // Initialize the queue used for storing tasks _blockingTaskQueue = new BlockingCollection <Task>(); _threads = new Thread[threadCount]; for (var i = 0; i < threads.Length; i++) { var dt = threads[i]; dt.Start(); _threads[i] = dt.ManagedThread; } }