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 | |
22 | enum 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 | |
36 | class HillClimbing |
37 | { |
38 | private: |
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 | |
75 | public: |
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 | |
83 | struct HillClimbingLogEntry |
84 | { |
85 | DWORD TickCount; |
86 | HillClimbingStateTransition Transition; |
87 | int NewControlSetting; |
88 | int LastHistoryCount; |
89 | float LastHistoryMean; |
90 | }; |
91 | |
92 | GARY_DECL(HillClimbingLogEntry, HillClimbingLog, HillClimbingLogCapacity); |
93 | GVAL_DECL(int, HillClimbingLogFirstIndex); |
94 | GVAL_DECL(int, HillClimbingLogSize); |
95 | typedef DPTR(HillClimbingLogEntry) PTR_HillClimbingLogEntry; |
96 | |
97 | #endif |
98 | |