blob: 9902e37018a5b14019dc04bed1437e426b55b410 (
plain) (
blame)
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
|
#ifndef GEL_PL_H
#define GEL_PL_H
#ifndef SWIG
#include <vector>
#endif
class GELPl
{
private:
std::vector<unsigned long> bounds;
int no_cpus;
const TaskSet& tasks;
int util_ceil;
int rounds;
std::vector<fractional_t> S_i;
std::vector<fractional_t> G_i;
// For faster lookups, to avoid too many conversions.
std::vector<fractional_t> utilizations;
void compute_exact_s(const fractional_t& S,
const std::vector<fractional_t>& Y_ints,
fractional_t& s);
void compute_binsearch_s(const fractional_t& S,
const std::vector<fractional_t>& Y_ints,
fractional_t& s);
inline bool M_lt_0(const fractional_t& s, const fractional_t& S,
const std::vector<fractional_t>& Y_ints);
// These are basically just structs that override operator< to allow
// sort algorithms to work.
class ReplacementType {
public:
unsigned int old_task;
unsigned int new_task;
fractional_t location;
fractional_t old_task_utilization;
bool operator<(const ReplacementType& other) const {
return (location < other.location)
|| ((location == other.location)
&& (old_task_utilization < other.old_task_utilization));
}
};
class TaggedValue {
public:
unsigned int task;
fractional_t value;
//Order is reversed - we are going to want the largest, rather than the
//smallest, values.
bool operator<(const TaggedValue& other) const {
return other.value < value;
}
};
public:
GELPl(unsigned int num_processors,
const TaskSet& tasks,
unsigned int rounds);
unsigned long get_bound(unsigned int index) {
return bounds[index];
}
// Converted to double for the sake of Python
double get_Si(unsigned int index) {
return S_i[index].get_d();
}
// Converted to double for the sake of Python
double get_Gi(unsigned int index) {
return G_i[index].get_d();
}
};
#endif
|