1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5//=========================================================================
6
7//
8// HillClimbing.h
9//
10// Defines classes for the ThreadPool's HillClimbing concurrency-optimization
11// algorithm.
12//
13
14//=========================================================================
15
16#ifndef _HILLCLIMBING_H
17#define _HILLCLIMBING_H
18
19#include "complex.h"
20#include "random.h"
21
22enum HillClimbingStateTransition
23{
24 Warmup,
25 Initializing,
26 RandomMove,
27 ClimbingMove,
28 ChangePoint,
29 Stabilizing,
30 Starvation, //used by ThreadpoolMgr
31 ThreadTimedOut, //used by ThreadpoolMgr
32 Undefined,
33};
34
35
36class HillClimbing
37{
38private:
39 int m_wavePeriod;
40 int m_samplesToMeasure;
41 double m_targetThroughputRatio;
42 double m_targetSignalToNoiseRatio;
43 double m_maxChangePerSecond;
44 double m_maxChangePerSample;
45 int m_maxThreadWaveMagnitude;
46 DWORD m_sampleIntervalLow;
47 double m_threadMagnitudeMultiplier;
48 DWORD m_sampleIntervalHigh;
49 double m_throughputErrorSmoothingFactor;
50 double m_gainExponent;
51 double m_maxSampleError;
52
53 double m_currentControlSetting;
54 LONGLONG m_totalSamples;
55 int m_lastThreadCount;
56 double m_elapsedSinceLastChange; //elapsed seconds since last thread count change
57 double m_completionsSinceLastChange; //number of completions since last thread count change
58
59 double m_averageThroughputNoise;
60
61 double* m_samples; //Circular buffer of the last m_samplesToMeasure samples
62 double* m_threadCounts; //Thread counts effective at each of m_samples
63
64 unsigned int m_currentSampleInterval;
65 CLRRandom m_randomIntervalGenerator;
66
67 int m_accumulatedCompletionCount;
68 double m_accumulatedSampleDuration;
69
70 void ChangeThreadCount(int newThreadCount, HillClimbingStateTransition transition);
71 void LogTransition(int threadCount, double throughput, HillClimbingStateTransition transition);
72
73 Complex GetWaveComponent(double* samples, int sampleCount, double period);
74
75public:
76 void Initialize();
77 int Update(int currentThreadCount, double sampleDuration, int numCompletions, int* pNewSampleInterval);
78 void ForceChange(int newThreadCount, HillClimbingStateTransition transition);
79};
80
81#define HillClimbingLogCapacity 200
82
83struct HillClimbingLogEntry
84{
85 DWORD TickCount;
86 HillClimbingStateTransition Transition;
87 int NewControlSetting;
88 int LastHistoryCount;
89 float LastHistoryMean;
90};
91
92GARY_DECL(HillClimbingLogEntry, HillClimbingLog, HillClimbingLogCapacity);
93GVAL_DECL(int, HillClimbingLogFirstIndex);
94GVAL_DECL(int, HillClimbingLogSize);
95typedef DPTR(HillClimbingLogEntry) PTR_HillClimbingLogEntry;
96
97#endif
98