/// <summary> /// Выполнить переход в состояние /// </summary> /// <param name="description">Описание причин перехода</param> /// <param name="state">Новое состояние</param> private void GoToState(string description, ExecutionThroughoutTrackerUpSmartDownCorrectionState state) { if (!CanChangeState(_state, state)) { throw new InvalidOperationException("Invalid state change from " + _state.ToString() + " to " + state.ToString()); } //Console.WriteLine(description + ". State = " + _state.ToString() + ", NewState = " + state.ToString()); if (_state != state) { _state = state; _enterStateTimeStamp = GetTimestamp(); _enterStateThroughoutData = this.GetCurrentMeasure(); _stateMeasureCount = 0; _tryIncreaseBlinkCount = 0; _tryDecreaseBlinkCount = 0; _tryDecreaseInitialThreadCount = -1; _optimalStateAverageThroughout = -1; TurboContract.Assert(_isPerfMeasureThreadWork == false, conditionString: "_isPerfMeasureThreadWork == false"); } }
/// <summary> /// Конструктор ExecutionThroughoutTrackerUpHardDownCorrection /// </summary> /// <param name="maxThreadCount">Максимальное число потоков</param> /// <param name="reasonableThreadCount">Базовое число потоков</param> public ExecutionThroughoutTrackerUpHardDownCorrection(int maxThreadCount, int reasonableThreadCount) { Contract.Requires(maxThreadCount > 0); Contract.Requires(reasonableThreadCount > 0); Contract.Requires(maxThreadCount >= reasonableThreadCount); _maxThreadCount = maxThreadCount; _reasonableThreadCount = reasonableThreadCount; _executedTasks = 0; _lastTimeStamp = GetTimestamp(); _data = new ThroughoutData[EstimationDataLength]; _nextDataIndex = 0; _state = ExecutionThroughoutTrackerUpHardDownCorrectionState.FindBestDirection; _enterStateTimeStamp = GetTimestamp(); _enterStateThroughoutData = new ThroughoutData(); _stateMeasureCount = 0; _findBestDirectionBlinkCount = 0; _optimalStateAverageThroughout = -1; _isPerfMeasureThreadWork = false; }
/// <summary> /// Конструктор ExecutionThroughoutTrackerUpSmartDownCorrection /// </summary> /// <param name="maxThreadCount">Максимальное число потоков</param> /// <param name="reasonableThreadCount">Базовое число потоков</param> public ExecutionThroughoutTrackerUpSmartDownCorrection(int maxThreadCount, int reasonableThreadCount) { TurboContract.Requires(maxThreadCount > 0, conditionString: "maxThreadCount > 0"); TurboContract.Requires(reasonableThreadCount > 0, conditionString: "reasonableThreadCount > 0"); TurboContract.Requires(maxThreadCount >= reasonableThreadCount, conditionString: "maxThreadCount >= reasonableThreadCount"); _maxThreadCount = maxThreadCount; _reasonableThreadCount = reasonableThreadCount; _executedTasks = 0; _lastTimeStamp = GetTimestamp(); _data = new ThroughoutData[EstimationDataLength]; _nextDataIndex = 0; _state = ExecutionThroughoutTrackerUpSmartDownCorrectionState.InOptimalState; _enterStateTimeStamp = GetTimestamp(); _enterStateThroughoutData = new ThroughoutData(); _stateMeasureCount = 0; _tryIncreaseBlinkCount = 0; _tryDecreaseBlinkCount = 0; _tryDecreaseInitialThreadCount = -1; _optimalStateAverageThroughout = -1; _isPerfMeasureThreadWork = false; }
/// <summary> /// Выполнить переход в состояние /// </summary> /// <param name="description">Описание причин перехода</param> /// <param name="state">Новое состояние</param> private void GoToState(string description, ExecutionThroughoutTrackerUpHardDownCorrectionState state) { if (!CanChangeState(_state, state)) { throw new InvalidOperationException("Invalid state change from " + _state.ToString() + " to " + state.ToString()); } //Console.WriteLine(description + ". State = " + _state.ToString() + ", NewState = " + state.ToString()); if (_state != state) { _state = state; _enterStateTimeStamp = GetTimestamp(); _enterStateThroughoutData = this.GetCurrentMeasure(); _stateMeasureCount = 0; _findBestDirectionBlinkCount = 0; _optimalStateAverageThroughout = -1; Debug.Assert(_isPerfMeasureThreadWork == false); } }
/// <summary> /// Зарегистрировать измерение /// </summary> /// <param name="workThreadCount">Текущее число потоков</param> /// <param name="isPerfThreadActive">Работает ли сейчас поток замера производительности</param> /// <param name="elapsedMs">Прошедшее время (для отладки, учитывается при значениях больше 0)</param> /// <returns>Выполненный замер</returns> private ThroughoutData RegisterMeasure(int workThreadCount, bool isPerfThreadActive, int elapsedMs = -1) { Contract.Requires(workThreadCount >= 0); int executedTasks = Interlocked.Exchange(ref _executedTasks, 0); var currentTime = GetTimestamp(); var elapsedTime = currentTime - _lastTimeStamp; if (elapsedMs > 0) { elapsedTime = (uint)elapsedMs; } double throughout = (double)executedTasks / elapsedTime; double newThroughoutAvg = (_data.Sum(o => o.Throughout) - _data[_nextDataIndex].Throughout + throughout) / _data.Length; var result = new ThroughoutData(executedTasks, throughout, newThroughoutAvg, workThreadCount, isPerfThreadActive); _lastTimeStamp = currentTime; _data[_nextDataIndex] = result; _nextDataIndex = (_nextDataIndex + 1) % _data.Length; _stateMeasureCount++; return(result); }