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