-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCloudModelDynamic.m
More file actions
142 lines (115 loc) · 5.23 KB
/
Copy pathCloudModelDynamic.m
File metadata and controls
142 lines (115 loc) · 5.23 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
function [t, X] = CloudModelDynamic()
maxTime = 1000; % mystical time units
tau = 2; % delay for information to travel in time units
lags = [tau, 2*tau];
compute_speed = 10; % tasks per time unit
number_of_computers = 10;
history = zeros(number_of_computers, 1);
t_data = 0:1:maxTime;
r = zeros(number_of_computers, length(t_data));
history(1:5) = [200; 200; 200; 0; 100]; % starting point
% define task inputs to the system
r(1,:) = 12*(sin(t_data/8))+12;
r(2,:) = linspace(5, 15, length(t_data));
r(3,:) = 10 * ones(size(t_data)); r(3,floor(1/4*maxTime):floor(3/4*maxTime)) = 50;
r(4,:) = linspace(0, 20, length(t_data));
r(5,:) = 10*ones(size(t_data));
r(6,:) = 10*ones(size(t_data));
r(7,:) = 10*ones(size(t_data));
r(8,:) = 10*ones(size(t_data));
% r(:,maxTime/4:maxTime/4+maxTime/20) = 3*r(:,maxTime/4:maxTime/4+maxTime/20);
% r(:,3*maxTime/4:3*maxTime/4+3*maxTime/20) = 4*r(:,3*maxTime/4:3*maxTime/4+3*maxTime/20);
% r(:,7*maxTime/8:maxTime) = .1*r(:,7*maxTime/8:maxTime);
%r(7,501:1001) = zeros(501,1);
sol = dde23(@(t,X,Xdel) calcDX(t, X, Xdel, t_data, r, tau, compute_speed), lags, history, [0, maxTime]);
% Plot results
figure;
subplot(2,1,1);
legend_names = [];
hold on
for i=1:number_of_computers
plot(sol.x, sol.y(i,:));
legend_names = [legend_names, sprintf("C%.0f Load", i)];
% add legend based on i
end
legend(legend_names);
subplot(2,1,2);
legend_names = [];
hold on
for i=1:number_of_computers
plot(t_data, r(i,:));
legend_names = [legend_names, sprintf("C%.0f Input (r%.0f Input)", i, i)];
end
legend(legend_names);
end
function dX = calcDX(t, X, Xdel, t_data, r, tau, compute_speed)
c = compute_speed * ones(length(r(:,1)), 1); % rate each computer can complete tasks
dX = zeros(length(c),1);
% connect all computers to all other computers
% send to rows, receive from columns
output_connections = zeros(length(c), length(c));
for row = 1:length(c)
for col = 1:length(c)
if col ~= row
output_connections(row, col) = 1;
end
end
end
% account for limited processing power, computer can send 10 tasks
% or compute 1 on its own (send is capped in calc_seeds)
% 10 is an arbitrary input
tasks_sent_per_one_computed = 10;
% calculate tasks to send and receive for now, and from tau ago
distribution_current = calc_sends(output_connections, X, Xdel(:, 1), compute_speed, r, tau, tasks_sent_per_one_computed);
distribution_previous = calc_sends(output_connections, Xdel(:, 1), Xdel(:, 2), compute_speed, r, tau, tasks_sent_per_one_computed);
for i = 1:length(c)
new_tasks_in = interp1(t_data, r(i,:), t);
work = min(X(i), c(i)); % tasks done per time
tasks_sent = sum(distribution_current(i, :));
tasks_received = sum(distribution_previous(:, i));
% factor in limited processing power
work = min(work, c(i) - round(tasks_sent/tasks_sent_per_one_computed));
% total
dX(i) = new_tasks_in - work - tasks_sent + tasks_received;
end
end
function distribution = calc_sends(output_connections, time1, time0, compute_speed, r, tau, tasks_sent_per_one_computed)
number_of_computers = length(output_connections(:,1));
distribution = zeros(number_of_computers, number_of_computers);
for i1 = 1:number_of_computers % loop through each computer
% get total tasks of self and computers able to be sent to with tasks <= self
total = time1(i1);
num_avail = 1;
targets = [];
for j = 1:length(output_connections)
if output_connections(i1,j) == 1
targets = [targets j];
end
end
for i2 = 1:length(targets) % loop through all available send locations
if time0(targets(i2)) <= time1(i1) % only include in average if <= self
total = total + time0(targets(i2));
num_avail = num_avail + 1;
end
end
% vary a to handle spikes of tasks efficienctly
a = min(1, (1 / (tau*length(r(:,1))))) * exp(min(max((time1(i1) - (total - time1(i1))) / 300, 0), 7));
% compute ideal spread of tasks
goal = total / num_avail;
% send appropriate tasks to each available target
for i2 = 1:length(targets)
if time0(targets(i2)) <= time1(i1) % only send to if <= self
distribution(i1,targets(i2)) = round(a * (goal - time0(targets(i2))));
end
end
% check if computer is trying to send <= the tasks it can just
% compute on its own, if so, replace with 0
if sum(distribution(i1,:)) <= compute_speed * a
distribution(i1,:) = 0;
end
while sum(distribution(i1,:)) > compute_speed * tasks_sent_per_one_computed
distribution(i1,:) = distribution(i1,:)-1;
%fprintf('Warning: computer %2.0f is hitting the bandwidth cap with %f.0 total tasks.\n', i1, time0(i1));
end
end
end