Example #1
0
            private int _logSize;                                         // SOS's ThreadPool command depends on this name

            public HillClimbing()
            {
                _wavePeriod                = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.WavePeriod", 4, false);
                _maxThreadWaveMagnitude    = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxWaveMagnitude", 20, false);
                _threadMagnitudeMultiplier = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.WaveMagnitudeMultiplier", 100, false) / 100.0;
                _samplesToMeasure          = _wavePeriod * AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.WaveHistorySize", 8, false);
                _targetThroughputRatio     = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.Bias", 15, false) / 100.0;
                _targetSignalToNoiseRatio  = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.TargetSignalToNoiseRatio", 300, false) / 100.0;
                _maxChangePerSecond        = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxChangePerSecond", 4, false);
                _maxChangePerSample        = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxChangePerSample", 20, false);
                int sampleIntervalMsLow  = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.SampleIntervalLow", DefaultSampleIntervalMsLow, false);
                int sampleIntervalMsHigh = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.SampleIntervalHigh", DefaultSampleIntervalMsHigh, false);

                if (sampleIntervalMsLow <= sampleIntervalMsHigh)
                {
                    _sampleIntervalMsLow  = sampleIntervalMsLow;
                    _sampleIntervalMsHigh = sampleIntervalMsHigh;
                }
                else
                {
                    _sampleIntervalMsLow  = DefaultSampleIntervalMsLow;
                    _sampleIntervalMsHigh = DefaultSampleIntervalMsHigh;
                }
                _throughputErrorSmoothingFactor = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.ErrorSmoothingFactor", 1, false) / 100.0;
                _gainExponent   = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.GainExponent", 200, false) / 100.0;
                _maxSampleError = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxSampleErrorPercent", 15, false) / 100.0;

                _samples      = new double[_samplesToMeasure];
                _threadCounts = new double[_samplesToMeasure];

                _currentSampleMs = _randomIntervalGenerator.Next(_sampleIntervalMsLow, _sampleIntervalMsHigh + 1);
            }
 private static HillClimbing CreateHillClimber()
 {
     // Default values pulled from CoreCLR
     return(new HillClimbing(wavePeriod: AppContextConfigHelper.GetInt32Config("HillClimbing_WavePeriod", 4, false),
                             maxWaveMagnitude: AppContextConfigHelper.GetInt32Config("HillClimbing_MaxWaveMagnitude", 20, false),
                             waveMagnitudeMultiplier: AppContextConfigHelper.GetInt32Config("HillClimbing_WaveMagnitudeMultiplier", 100, false) / 100.0,
                             waveHistorySize: AppContextConfigHelper.GetInt32Config("HillClimbing_WaveHistorySize", 8, false),
                             targetThroughputRatio: AppContextConfigHelper.GetInt32Config("HillClimbing_Bias", 15, false) / 100.0,
                             targetSignalToNoiseRatio: AppContextConfigHelper.GetInt32Config("HillClimbing_TargetSignalToNoiseRatio", 300, false) / 100.0,
                             maxChangePerSecond: AppContextConfigHelper.GetInt32Config("HillClimbing_MaxChangePerSecond", 4, false),
                             maxChangePerSample: AppContextConfigHelper.GetInt32Config("HillClimbing_MaxChangePerSample", 20, false),
                             sampleIntervalMsLow: AppContextConfigHelper.GetInt32Config("HillClimbing_SampleIntervalLow", DefaultSampleIntervalMsLow, false),
                             sampleIntervalMsHigh: AppContextConfigHelper.GetInt32Config("HillClimbing_SampleIntervalHigh", DefaultSampleIntervalMsHigh, false),
                             errorSmoothingFactor: AppContextConfigHelper.GetInt32Config("HillClimbing_ErrorSmoothingFactor", 1, false) / 100.0,
                             gainExponent: AppContextConfigHelper.GetInt32Config("HillClimbing_GainExponent", 200, false) / 100.0,
                             maxSampleError: AppContextConfigHelper.GetInt32Config("HillClimbing_MaxSampleErrorPercent", 15, false) / 100.0
                             ));
 }
Example #3
0
        private static int GetIOCompletionPollerCount()
        {
            // Named for consistency with SocketAsyncEngine.Unix.cs, this environment variable is checked to override the exact
            // number of IO completion poller threads to use. See the comment in SocketAsyncEngine.Unix.cs about its potential
            // uses. For this implementation, the ProcessorsPerIOPollerThread config option below may be preferable as it may be
            // less machine-specific.
            if (uint.TryParse(Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SOCKETS_THREAD_COUNT"), out uint count))
            {
                return(Math.Min((int)count, MaxPossibleThreadCount));
            }

            if (UnsafeInlineIOCompletionCallbacks)
            {
                // In this mode, default to ProcessorCount pollers to ensure that all processors can be utilized if more work
                // happens on the poller threads
                return(Environment.ProcessorCount);
            }

            int processorsPerPoller =
                AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.ProcessorsPerIOPollerThread", 12, false);

            return((Environment.ProcessorCount - 1) / processorsPerPoller + 1);
        }
#pragma warning disable CA1810 // remove the explicit static constructor
            static BlockingConfig()
            {
                // Summary description of how blocking compensation works and how the config settings below are used:
                // - After the thread count based on MinThreads is reached, up to ThreadsToAddWithoutDelay additional threads
                //   may be created without a delay
                // - After that, before each additional thread is created, a delay is induced, starting with DelayStepMs
                // - For every ThreadsPerDelayStep threads that are added with a delay, an additional DelayStepMs is added to
                //   the delay
                // - The delay may not exceed MaxDelayMs
                // - Delays are only induced before creating threads. If threads are already available, they would be released
                //   without delay to compensate for cooperative blocking.
                // - Physical memory usage and limits are also used and beyond a threshold, the system switches to fallback mode
                //   where threads would be created if starvation is detected, typically with higher delays

                // After the thread count based on MinThreads is reached, this value (after it is multiplied by the processor
                // count) specifies how many additional threads may be created without a delay
                int blocking_threadsToAddWithoutDelay_procCountFactor =
                    AppContextConfigHelper.GetInt32Config(
                        "System.Threading.ThreadPool.Blocking.ThreadsToAddWithoutDelay_ProcCountFactor",
                        1,
                        false);

                // After the thread count based on ThreadsToAddWithoutDelay is reached, this value (after it is multiplied by
                // the processor count) specifies after how many threads an additional DelayStepMs would be added to the delay
                // before each new thread is created
                int blocking_threadsPerDelayStep_procCountFactor =
                    AppContextConfigHelper.GetInt32Config(
                        "System.Threading.ThreadPool.Blocking.ThreadsPerDelayStep_ProcCountFactor",
                        1,
                        false);

                // After the thread count based on ThreadsToAddWithoutDelay is reached, this value specifies how much additional
                // delay to add per ThreadsPerDelayStep threads, which would be applied before each new thread is created
                DelayStepMs =
                    (uint)AppContextConfigHelper.GetInt32Config(
                        "System.Threading.ThreadPool.Blocking.DelayStepMs",
                        25,
                        false);

                // After the thread count based on ThreadsToAddWithoutDelay is reached, this value specifies the max delay to
                // use before each new thread is created
                MaxDelayMs =
                    (uint)AppContextConfigHelper.GetInt32Config(
                        "System.Threading.ThreadPool.Blocking.MaxDelayMs",
                        250,
                        false);

                int processorCount = Environment.ProcessorCount;

                ThreadsToAddWithoutDelay = (short)(processorCount * blocking_threadsToAddWithoutDelay_procCountFactor);
                if (ThreadsToAddWithoutDelay > MaxPossibleThreadCount ||
                    ThreadsToAddWithoutDelay / processorCount != blocking_threadsToAddWithoutDelay_procCountFactor)
                {
                    ThreadsToAddWithoutDelay = MaxPossibleThreadCount;
                }

                blocking_threadsPerDelayStep_procCountFactor = Math.Max(1, blocking_threadsPerDelayStep_procCountFactor);
                short maxThreadsPerDelayStep = (short)(MaxPossibleThreadCount - ThreadsToAddWithoutDelay);

                ThreadsPerDelayStep =
                    (short)(processorCount * blocking_threadsPerDelayStep_procCountFactor);
                if (ThreadsPerDelayStep > maxThreadsPerDelayStep ||
                    ThreadsPerDelayStep / processorCount != blocking_threadsPerDelayStep_procCountFactor)
                {
                    ThreadsPerDelayStep = maxThreadsPerDelayStep;
                }

                MaxDelayMs  = Math.Max(1, Math.Min(MaxDelayMs, GateThread.GateActivitiesPeriodMs));
                DelayStepMs = Math.Max(1, Math.Min(DelayStepMs, MaxDelayMs));
            }