|
13 | 13 | # GNU General Public License for more details. |
14 | 14 |
|
15 | 15 | ## ToDo: |
| 16 | +## * 86% of runs are ending with q>0 |
| 17 | +## - new approach: add a 2nd pass through the while loop |
| 18 | +## starting after the longest empty period found in the 1st while loop |
| 19 | +## Still use the same 1st pass to find the minphase shift, as best approx |
16 | 20 | ## * Check whether code completes properly at each t_max limit |
17 | 21 | ## - q = 0 prior to last event (investigate bug-causes of non-zero cases) |
18 | 22 | ## - qt_mode plot cases where q!=0 at t_max |
|
36 | 40 | # with implicit denominators lambdas, betas & phis, resp. |
37 | 41 | # (except after setup, when beta is cast to double and downscaled), |
38 | 42 | lambdas = 16; # no. of divisions of capacity share, lambda, if lambdaSum=1 |
39 | | -betas = 64; # no. of divisions of normalized burst delay, beta, if betaSum=1 |
| 43 | +betas = 400; # no. of divisions of normalized burst delay, beta, if betaSum=1 |
40 | 44 | phis = 8; # no. of divisions of phase shift, phi, in 360deg |
41 | 45 | smidgen = 0.123456789; # To avoid unrealistic degree of exact phase lock |
42 | 46 |
|
|
45 | 49 | # set qt_mode to false(1) to scan parameter space and produce marking statistics |
46 | 50 | qt_mode = false(1); |
47 | 51 | if (qt_mode) |
48 | | - i_lambda = 11; # index of lambda to plot if in qt_mode |
49 | | - i_beta = 39; # index of beta to plot if in qt_mode |
50 | | - i_phi = 4; # index of phi to plot if in qt_mode |
| 52 | + i_lambda = 1; # index of lambda to plot if in qt_mode |
| 53 | + i_beta = 2; # index of beta to plot if in qt_mode |
| 54 | + i_phi = 1; # index of phi to plot if in qt_mode |
51 | 55 | endif |
52 | 56 |
|
53 | 57 | savepre = [mfilename()]; |
|
149 | 153 | i_phi = 1 : phis; |
150 | 154 | endif |
151 | 155 |
|
| 156 | +## Debug; ToDo: Remove once fixed |
| 157 | +i_bug = 0; |
152 | 158 | for (i = i_lambda) |
153 | 159 | if (!qt_mode) |
154 | 160 | printf("%d%%\n", double(i)/double(lambdaSum)*100); |
|
190 | 196 | # k : index of phi |
191 | 197 | for (k = i_phi) |
192 | 198 | clear qt_out; |
193 | | - ## Debug; ToDo: Remove once fixed |
194 | | - i_bug = 0; |
195 | 199 |
|
196 | 200 | # Variable definitions |
197 | 201 | # t : current time |
|
224 | 228 | t_delta = t_delta0 : ti(i,j,i_rare) : t_max(i,j); |
225 | 229 | # Replace with vector of phase shifts from previous freq burst |
226 | 230 | t_delta = rem(t_delta, ti(i,j,i_freq)); |
227 | | - t_delta_min = min(t_delta); |
228 | | - clear t_delta; |
| 231 | + ## ToDo: Try this |
| 232 | + # Assume a standing queue drained at the average arrival rate. |
| 233 | + # Create vector of no. of freq bursts betw each rare burst. |
| 234 | + # Calc the vector of changes in the queue betw each freq burst just before |
| 235 | + # each rare burst. |
| 236 | + # Convert this to a running sum. |
| 237 | + ## ToDo: add extra steps here |
| 238 | + # Check whether the min is at the freq or the next rare. |
| 239 | + t_delta(2,:) = ceil((ti(i,j,i_rare) - t_delta(1,:)) / ti(i,j,i_freq)); |
| 240 | + drain_freq = ti(i,j,i_freq) * double(lambdaSum) / lambdas; # drain in a freq interval |
| 241 | + t_delta(3,:) = beta(i_rare,j) + t_delta(2,:) .* (beta(i_freq,j) - drain_freq); |
| 242 | + t_delta(4,:) = cumsum(t_delta(3,:)); |
| 243 | + t_delta(5,:) = t_delta(4,:) + beta(i_freq,j) - t_delta(1,:) * double(lambdaSum) / lambdas; |
| 244 | + [t_delta_min4, i_4] = min(t_delta(4,:)); |
| 245 | + [t_delta_min5, i_5] = min(t_delta(5,:)); |
| 246 | + ## t_delta_min = min(t_delta); |
229 | 247 | # Whether q=0 at the start or end of the min phase shift from freq to rare |
230 | 248 | # depends on whether the freq burst is large enough to keep the queue |
231 | 249 | # busy over t_delta_min. |
232 | 250 | # In each case, i_next_burst and i_head are pointed to the flow that |
233 | 251 | # bursts at the origin and the time until the next burst for each flow, |
234 | 252 | # t_burst[2], is set. |
235 | | - if (t_delta_min < beta(i_freq,j)) |
| 253 | + if (t_delta_min4 < t_delta_min5) |
236 | 254 | # q=0 at freq burst before min phase shift |
237 | | - i_next_burst = i_head = i_freq; |
238 | 255 | t_burst(i_freq) = 0; |
239 | | - t_burst(i_rare) = t_delta_min; |
| 256 | + t_burst(i_rare) = t_delta(1,i_4); |
| 257 | + if (t_burst(i_rare) <= 0) # <= for robustness |
| 258 | + [~, i_head] = min(beta(:,j)); |
| 259 | + else |
| 260 | + i_head = i_freq; |
| 261 | + endif |
| 262 | + i_next_burst = i_head; |
240 | 263 | else |
241 | 264 | # q=0 at rare burst after min phase shift |
242 | | - i_next_burst = i_head = i_rare; |
243 | 265 | t_burst(i_rare) = 0; |
244 | | - t_burst(i_freq) = ti(i,j,i_freq) - t_delta_min; |
245 | | - endif |
246 | | - # Tie-break when bursts coincide: take smaller first |
247 | | - if (t_delta_min <= 0) # <= to be robust |
248 | | - [~, i_next_burst] = min(beta(:,j)); |
249 | | - i_head = i_next_burst; |
250 | | - t_burst(i_rare) = t_burst(i_freq) = 0; |
| 266 | + t_burst(i_freq) = ti(i,j,i_freq) - t_delta(1,i_5); ## ToDo: >= 0? |
| 267 | + i_next_burst = i_head = i_rare; |
251 | 268 | endif |
252 | 269 | t_next_burst = 0; |
| 270 | +## ToDo: Remove |
| 271 | +## clear t_delta; |
| 272 | +## clear t_delta_min4; |
| 273 | +## clear t_delta_min5; |
253 | 274 |
|
254 | 275 | # #2 time scan |
255 | 276 | t = 0; |
|
262 | 283 | # * qt_out(:,2:3) : resulting per flow queue contribution at that time; |
263 | 284 | # * qt_out(:,4) : which flow is at the head of the q; 0:1 means q(1:2); |
264 | 285 | # * qt_out(:,5) : whether queue is above threshold (q>=1) after t. |
265 | | - while (t <= t_max(i,j)) |
| 286 | + while (t < t_max(i,j)) |
266 | 287 |
|
267 | 288 | # The contributions from each flow to the queue are piecewise linear |
268 | 289 | # between 'events', where an 'event' is a discontinuity in one of the |
|
279 | 300 | ) |
280 | 301 | # Combined queue has fallen below threshold before any other event |
281 | 302 | t += q_xs; |
282 | | - if (t > t_max(i,j)) |
283 | | - break |
284 | | - endif |
| 303 | +## if (t > t_max(i,j)) |
| 304 | +## break |
| 305 | +## endif |
285 | 306 | # Add to p_e |
286 | 307 | p(k, i_head, 2) += q_xs; |
287 | 308 | q(i_head) -= q_xs; |
|
307 | 328 | if ((q(i_head) > 0) && (t_next_empty <= t_next_burst)) |
308 | 329 | # q(i_head) has emptied (defer any simultaneous burst to next event) |
309 | 330 | t = t_next_empty; |
310 | | - if (t > t_max(i,j)) |
311 | | - break |
312 | | - endif |
| 331 | +## if (t > t_max(i,j)) |
| 332 | +## break |
| 333 | +## endif |
313 | 334 | if (ott) |
314 | 335 | # Altho head flow has emptied, tail is over threshold |
315 | 336 | # so add time since previous event to p_e |
|
339 | 360 | q_xs = sum(q) - 1; |
340 | 361 | endif |
341 | 362 | t = t_next_burst; |
342 | | - if (t > t_max(i,j)) |
| 363 | +## if (t > t_max(i,j)) |
| 364 | +## break |
| 365 | +## endif |
| 366 | + qt_mode && (qt_out(++i_event,:) = [t, q(1), q(2), i_head-1, ott]); |
| 367 | + ## ToDo: more elegantly, increment t to pre-determined matrix |
| 368 | + if (t >= t_max(i,j) - 8*eps(t_max(1,j))) |
343 | 369 | break |
344 | 370 | endif |
345 | | - qt_mode && (qt_out(++i_event,:) = [t, q(1), q(2), i_head-1, ott]); |
346 | 371 | # Add burst to tail |
347 | 372 | # but first check whether combined queue rises above threshold |
348 | 373 | delta_q = beta(i_next_burst,j); |
|
362 | 387 | qt_mode && (qt_out(++i_event,:) = [t, q(1), q(2), i_head-1, ott]); |
363 | 388 | # Prepare for next burst |
364 | 389 | # Set t_burst for next burst from this flow |
| 390 | + ## ToDo: increment a pointer along a range for precision |
365 | 391 | t_burst(i_next_burst) += ti(i,j,i_next_burst); |
366 | 392 | # Calc arrival time and flow id of next burst, handling tie if nec. |
367 | 393 | [t_next_burst, i_next_burst] = min(t_burst); |
|
0 commit comments