-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathns-scheduler.patch
305 lines (290 loc) · 10.3 KB
/
ns-scheduler.patch
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
diff -urN ns-2.31/common/scheduler.cc ns-2.31-scheduler-doc/common/scheduler.cc
--- ns-2.31/common/scheduler.cc 2006-02-21 07:20:18.000000000 -0800
+++ ns-2.31-scheduler-doc/common/scheduler.cc 2007-11-11 22:39:02.000000000 -0800
@@ -581,6 +581,17 @@
} class_calendar_sched;
CalendarScheduler::CalendarScheduler() : cal_clock_(clock_) {
+ bind("adjust_new_width_interval_", &adjust_new_width_interval_);
+ bind("min_bin_width_", &min_bin_width_);
+ if (adjust_new_width_interval_) {
+ avg_gap_ = -2;
+ last_time_ = -2;
+ gap_num_ = 0;
+ head_search_ = 0;
+ insert_search_ = 0;
+ round_num_ = 0;
+ time_to_newwidth = adjust_new_width_interval_;
+ }
reinit(4, 1.0, cal_clock_);
}
@@ -595,47 +606,46 @@
CalendarScheduler::insert(Event* e)
{
int i;
- if (cal_clock_ > e->time_) {
+ double newtime = e->time_;
+ if (cal_clock_ > newtime) {
// may happen in RT scheduler
- cal_clock_ = e->time_;
+ cal_clock_ = newtime;
i = lastbucket_ = CALENDAR_HASH(cal_clock_);
} else
- i = CALENDAR_HASH(e->time_);
+ i = CALENDAR_HASH(newtime);
- Event *head = buckets_[i].list_;
- Event *before=0;
+ Bucket* current=(&buckets_[i]);
+ Event *head = current->list_;
+ Event *after=0;
if (!head) {
- buckets_[i].list_ = e;
+ current->list_ = e;
e->next_ = e->prev_ = e;
++stat_qsize_;
- ++buckets_[i].count_;
+ ++(current->count_);
} else {
- bool newhead;
- if (e->time_ >= head->prev_->time_) {
- // insert at the tail
- before = head;
- newhead = false;
+ insert_search_++;
+ if (newtime < head->time_) {
+ // e-> head -> ...
+ e->next_ = head;
+ e->prev_ = head->prev_;
+ e->prev_->next_ = e;
+ head->prev_ = e;
+ current->list_ = e;
+ ++stat_qsize_;
+ ++(current->count_);
} else {
- // insert event in time sorted order, FIFO for sim-time events
- for (before = head; e->time_ >= before->time_; before = before->next_)
- ;
- newhead = (before == head);
- }
-
- e->next_ = before;
- e->prev_ = before->prev_;
- before->prev_ = e;
- e->prev_->next_ = e;
- if (newhead) {
- buckets_[i].list_ = e;
- //assert(e->time_ <= e->next_->time_);
- }
- //assert(e->prev_ != e);
- if (e->prev_->time_ != e->time_) {
- // unique timing
- ++stat_qsize_;
- ++buckets_[i].count_;
+ for (after = head->prev_; newtime < after->time_; after = after->prev_) { insert_search_++; };
+ //...-> after -> e -> ...
+ e->next_ = after->next_;
+ e->prev_ = after;
+ e->next_->prev_ = e;
+ after->next_ = e;
+ if (after->time_ < newtime) {
+ //unique timing
+ ++stat_qsize_;
+ ++(current->count_);
+ }
}
}
++qsize_;
@@ -710,6 +720,7 @@
Event *e, *min_e = NULL;
#define CAL_DEQUEUE(x) \
do { \
+ head_search_++; \
if ((e = buckets_[i].list_) != NULL) { \
diff = e->time_ - cal_clock_; \
if (diff < diff##x##_) { \
@@ -769,6 +780,34 @@
if (!e)
return 0;
+ if (adjust_new_width_interval_) {
+ if (last_time_< 0) last_time_ = e->time_;
+ else
+ {
+ gap_num_ ++;
+ if (gap_num_ >= qsize_ ) {
+ double tt_gap_ = e->time_ - last_time_;
+ avg_gap_ = tt_gap_ / gap_num_;
+ gap_num_ = 0;
+ last_time_ = e->time_;
+ round_num_ ++;
+ if ((round_num_ > 20) &&
+ (( head_search_> (insert_search_<<1))
+ ||( insert_search_> (head_search_<<1)) ))
+ {
+ resize(nbuckets_, cal_clock_);
+ round_num_ = 0;
+ } else {
+ if (round_num_ > 100) {
+ round_num_ = 0;
+ head_search_ = 0;
+ insert_search_ = 0;
+ }
+ }
+ }
+ }
+ };
+
int l = lastbucket_;
// update stats and unlink
@@ -828,10 +867,32 @@
void
CalendarScheduler::resize(int newsize, double start)
{
- double bwidth = newwidth(newsize);
-
- if (newsize < 4)
- newsize = 4;
+ double bwidth;
+ if (newsize == nbuckets_) {
+ /* we resize for bwidth*/
+ if (head_search_) bwidth = head_search_; else bwidth = 1;
+ if (insert_search_) bwidth = bwidth / insert_search_;
+ bwidth = sqrt (bwidth) * width_;
+ if (bwidth < min_bin_width_) {
+ if (time_to_newwidth>0) {
+ time_to_newwidth --;
+ head_search_ = 0;
+ insert_search_ = 0;
+ round_num_ = 0;
+ return; //failed to adjust bwidth
+ } else {
+ // We have many (adjust_new_width_interval_) times failure in adjusting bwidth.
+ // should do a reshuffle with newwidth
+ bwidth = newwidth(newsize);
+ }
+ };
+ //snoopy queue calculation
+ } else {
+ /* we resize for size */
+ bwidth = newwidth(newsize);
+ if (newsize < 4)
+ newsize = 4;
+ }
Bucket *oldb = buckets_;
int oldn = nbuckets_;
@@ -856,13 +917,20 @@
} while (e != tail);
}
}
- delete [] oldb;
+ head_search_ = 0;
+ insert_search_ = 0;
+ round_num_ = 0;
+ delete [] oldb;
}
// take samples from the most populated bucket.
double
CalendarScheduler::newwidth(int newsize)
{
+ if (adjust_new_width_interval_) {
+ time_to_newwidth = adjust_new_width_interval_;
+ if (avg_gap_ > 0) return avg_gap_*4.0;
+ }
int i;
int max_bucket = 0; // index of the fullest bucket
for (i = 1; i < nbuckets_; ++i) {
diff -urN ns-2.31/common/scheduler.h ns-2.31-scheduler-doc/common/scheduler.h
--- ns-2.31/common/scheduler.h 2005-07-26 18:13:42.000000000 -0700
+++ ns-2.31-scheduler-doc/common/scheduler.h 2007-11-11 22:39:02.000000000 -0800
@@ -154,6 +154,16 @@
const Event* head();
protected:
+ double min_bin_width_; // minimum bin width for Calendar Queue
+ unsigned int adjust_new_width_interval_; // The interval (in unit of resize time) for adjustment of bin width. A zero value disables automatic bin width adjustment
+ unsigned time_to_newwidth; // how many time we failed to adjust the width based on snoopy-queue
+ long unsigned head_search_;
+ long unsigned insert_search_;
+ int round_num_;
+ long int gap_num_; //the number of gap samples in this window (in process of calculation)
+ double last_time_; //the departure time of first event in this window
+ double avg_gap_; //the average gap in last window (finished calculation)
+
double width_;
double diff0_, diff1_, diff2_; /* wrap-around checks */
diff -urN ns-2.31/doc/ns.bib ns-2.31-scheduler-doc/doc/ns.bib
--- ns-2.31/doc/ns.bib 2003-12-13 22:52:40.000000000 -0800
+++ ns-2.31-scheduler-doc/doc/ns.bib 2007-11-11 22:40:56.000000000 -0800
@@ -998,6 +998,25 @@
crossref = "McCaXX:wb"
}
+@InProceedings{Tan00SNOOPyQueue,
+ author = "Kah Leong Tan and Li-Jin Thng",
+ title = "SNOOPy Calendar Queue",
+ booktitle = "Proceedings of the 32nd conference on Winter simulation Orlando, Florida",
+ pages = {487-495},
+ year = 2000
+}
+
+@InProceedings{WeiCao06NSLinuxTCP,
+ author = "Xiaoliang (David) Wei and Pei Cao",
+ title = "{NS-2 TCP-Linux: an NS-2 TCP implementation with congestion control algorithms from Linux}",
+ booktitle = "{WNS2 '06: Proceeding from the 2006 workshop on ns-2: the IP network simulator}",
+ year = {2006},
+ pages = {9},
+ publisher = {ACM Press},
+ address = {New York, NY, USA},
+}
+
+
@string{usc = "University of Southern California"}
@string{usc-isi = "USC/Information Sciences Institute"}
@string{ieee-computer = "{IEEE} Computer"};
diff -urN ns-2.31/doc/sim.tex ns-2.31-scheduler-doc/doc/sim.tex
--- ns-2.31/doc/sim.tex 2003-04-03 12:36:52.000000000 -0800
+++ ns-2.31-scheduler-doc/doc/sim.tex 2007-11-11 22:39:02.000000000 -0800
@@ -151,6 +151,38 @@
The implementation of Calendar queues in \ns~v2
was contributed by David Wetherall (presently at MIT/LCS).
+The calendar queue scheduler since \ns~v2.33 is improved by the following
+three algorithms:
+\begin{itemize}
+ \item A heuristic improvement that changes the linear search direction
+in enqueue operations. The original implementation searches the events in
+a bucket in \emph{chronological order} to find the in-order spot for the event
+that is being inserted.
+The new implementation searches the bucket in \emph{reverse chronological order}
+because the event being inserted is usually later than most of the events that are
+already in the bucket.
+ \item A new bucket width estimation that uses the average interval of
+\emph{dequeued events} as the estimation of bucket width. It is stated in
+\cite{Brow88:Calendar} that the optimal bucket width should be the \emph{average inverval of all events in the future}.
+The original implementation uses the average interval of \emph{future events currently in the most crowded bucket}
+as the estimation. This estimation is unstable because it is very likely
+that many future events will be inserted into the bucket after this estimation, significantly changing the
+averaged event interval in the bucket. The new implementation uses the observed event interval
+in the past, which will not change, to estimate the event interval in future.
+ \item SNOOPy Calendar Queue: a Calendar queue variant that dynamically
+tunes the bucket width according to the cost trade-off between enqueue
+operation and dequeue operation.
+The SNOOPy queue improvement is described in \cite{Tan00SNOOPyQueue}.
+In this implementation, there is one tcl parameter {\tt adjust\_new\_width\_interval\_ }
+specifying the interval with which the SNOOPy queue should re-calculate the bucket width.
+Setting this parameter to 0 turns off the SNOOPy queue algorithm and degrades the scheduler
+back to the original Calendar Queue. In general, normal simulation users are
+not expected to change this parameter.
+\end{itemize}
+The details of these improvements are described in \cite{WeiCao06NSLinuxTCP}.
+
+The implementation of these three improvements was contributed by Xiaoliang (David) Wei at Caltech/NetLab.
+
\subsection{The Real-Time Scheduler}
\label{sec:rtsched}
diff -urN ns-2.31/tcl/lib/ns-default.tcl ns-2.31-scheduler-doc/tcl/lib/ns-default.tcl
--- ns-2.31/tcl/lib/ns-default.tcl 2006-10-22 22:33:16.000000000 -0700
+++ ns-2.31-scheduler-doc/tcl/lib/ns-default.tcl 2007-11-11 22:39:35.000000000 -0800
@@ -72,6 +72,9 @@
Scheduler/RealTime set maxslop_ 0.010; # max allowed slop b4 error (sec)
+Scheduler/Calendar set adjust_new_width_interval_ 10; # the interval (in unit of resize times) we recalculate bin width. 0 means disable dynamic adjustment
+Scheduler/Calendar set min_bin_width_ 1e-18; # the lower bound for the bin_width
+
#
# Queues and associated
#