queue_mgmt.tex
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:24k
源码类别:

通讯编程

开发平台:

Visual C++

  1. %
  2. % personal commentary:
  3. %        DRAFT DRAFT DRAFT
  4. %        - KFALL
  5. %
  6. chapter{Queue Management and Packet Scheduling}
  7. label{chap:qmgmt}
  8. Queues represent locations where packets may be held (or dropped).
  9. Packet scheduling refers to the decision process used to choose
  10. which packets should be serviced or dropped.
  11. Buffer management refers to any particular discipline used
  12. to regulate the occupancy of a particular queue.
  13. At present, support is included for drop-tail (FIFO) queueing,
  14. RED buffer management, CBQ (including a priority and round-robin scheduler), 
  15. and
  16. variants of Fair Queueing including, Fair Queueing (FQ),
  17. Stochastic Fair Queueing (SFQ), and Deficit Round-Robin (DRR).
  18. In the common case where a {em delay} element is downstream from
  19. a queue, the queue may be {em blocked} until it is re-enabled
  20. by its downstream neighbor.
  21. This is the mechanism by which transmission delay is simulated.
  22. In addition, queues may be forcibly blocked or unblocked at arbitrary
  23. times by their neighbors (which is used to implement multi-queue
  24. aggregate queues with inter-queue flow control).
  25. Packet drops are implemented in such a way that queues contain
  26. a ``drop destination''; that is, an object that receives all packets
  27. dropped by a queue.
  28. This can be useful to (for example) keep statistics on dropped packets.
  29. section{The C++ Queue Class}
  30. label{sec:qclass}
  31. The code{Queue} class is derived from a code{Connector} base class.
  32. It provides a base class used by particular types of (derived) queue classes,
  33. as well as a call-back function to implement blocking (see next section).
  34. The following definitions are provided in code{queue.h}:
  35. begin{program}
  36.         class Queue : public Connector {
  37.          public:
  38.                 virtual void enque(Packet*) = 0;
  39.                 virtual Packet* deque() = 0;
  40.                 void recv(Packet*, Handler*);
  41.                 void resume();
  42.                 int blocked();
  43.                 void unblock();
  44.                 void block();
  45.          protected:
  46.                 Queue();
  47.                 int command(int argc, const char*const* argv);
  48.                 int qlim_;         * maximum allowed pkts in queue */
  49.                 int blocked_;
  50.                 int unblock_on_resume_; * unblock q on idle? */
  51.                 QueueHandler qh_;
  52.         };
  53. end{program}
  54. The code{enque} and code{deque} functions are pure virtual, indicating
  55. the code{Queue} class is to be used as a base class;
  56. particular queues are derived
  57. from code{Queue} and implement these two functions as necessary.
  58. Particular queues do not, in general, override the code{recv} function
  59. because it invokes the
  60. the particular code{enque} and code{deque}.
  61. The code{Queue} class does not contain much internal state.
  62. Often these are
  63. href{special monitoring objects}{Chapter}{chap:trace}.
  64. The code{qlim_} member is constructed to dictate a bound on the maximum
  65. queue occupancy, but this is not enforced by the code{Queue} class itself; it
  66. must be used by the particular queue subclasses if they need this value.
  67. The code{blocked_} member is a boolean indicating whether the
  68. queue is able to send a packet immediately to its downstream neighbor.
  69. When a queue is blocked, it is able to enqueue packets but not send them.
  70. subsection{Queue blocking}
  71. label{sec:qblock}
  72. A queue may be either blocked or unblocked at any given time.
  73. Generally, a queue is blocked when a packet is in transit between it
  74. and its downstream neighbor (most of the time if the queue is occupied).
  75. A blocked queue will remain blocked as long as it downstream link is
  76. busy and the queue has at least one packet to send.
  77. A queue becomes unblocked only when its code{resume} function is
  78. invoked (by means of a downstream neighbor scheduling it via
  79. a callback), usually when no packets are queued.
  80. The callback is implemented by using the following class and
  81. methods:
  82. begin{program}
  83.         class QueueHandler : public Handler {
  84.         public:
  85.                 inline QueueHandler(Queue& q) : queue_(q) {}
  86.                 void handle(Event*); /* calls queue_.resume() */
  87.          private:
  88.                 Queue& queue_;
  89.         };
  90.         void QueueHandler::handle(Event*)
  91.         {
  92.                 queue_.resume();
  93.         }
  94.         Queue::Queue() : drop_(0), blocked_(0), qh_(*this)
  95.         {
  96.                 Tcl& tcl = Tcl::instance();
  97.                 bind("limit_", &qlim_);
  98.         }
  99.         void Queue::recv(Packet* p, Handler*)
  100.         {
  101.                 enque(p);
  102.                 if (!blocked_) {
  103.                         /*
  104.                          * We're not block.  Get a packet and send it on.
  105.                          * We perform an extra check because the queue
  106.                          * might drop the packet even if it was
  107.                          * previously empty!  (e.g., RED can do this.)
  108.                          */
  109.                         p = deque();
  110.                         if (p != 0) {
  111.                                 blocked_ = 1;
  112.                                 target_->recv(p, &qh_);
  113.                         }
  114.                 }
  115.         }
  116.         void Queue::resume()
  117.         {
  118.                 Packet* p = deque();
  119.                 if (p != 0)
  120.                         target_->recv(p, &qh_);
  121.                 else {
  122.                         if (unblock_on_resume_)
  123.                                 blocked_ = 0;
  124.                         else
  125.                                 blocked_ = 1;
  126.                 }
  127.         }
  128. end{program}
  129. The handler management here is somewhat subtle.
  130. When a new code{Queue} object is created,
  131. it includes a code{QueueHandler} object (code{qh_})
  132. which is initialized to contain a reference to the new code{Queue} object
  133. (code{Queue& QueueHandler::queue_}).
  134. This is performed by the code{Queue} constructor using the expression
  135. code{qh_(*this)}.
  136. When a Queue receives a packet it calls the subclass
  137. (i.e. queueing discipline-specific) version of
  138. the code{enque} function with the packet.
  139. If the queue is not blocked, it is allowed to send a packet and
  140. calls the specific code{deque} function which determines which
  141. packet to send, blocks the queue (because a packet is now in transit), and
  142. sends the packet to the queue's downstream neighbor.
  143. Note that any future packets received from upstream neighbors
  144. will arrive to a blocked queue.
  145. When a downstream neighbor wishes to cause the queue to become unblocked
  146. it schedules the QueueHandler's code{handle} function by
  147. passing code{&qh_} to the simulator scheduler.
  148. The code{handle} function invokes code{resume}, which
  149. will send the next-scheduled packet downstream (and leave the queue blocked),
  150. or unblock the queue when no packet is ready to be sent.
  151. This process is made more clear by also referring to the
  152. href{fcn[]{LinkDelay::recv} method}{Section}{sec:delayclass}.
  153. subsection{PacketQueue Class}
  154. label{sec:packetqclass}
  155. The code{Queue} class may implement buffer management and scheduling but
  156. do not implement the low-level operations on a particular queue.
  157. The code{PacketQueue} class is used for this purpose, and is defined as follows
  158. (see code{queue.h}):
  159. begin{program}
  160.         class PacketQueue {
  161.         public:
  162.                 PacketQueue();
  163.                 int length(); /* queue length in packets */
  164.                 void enque(Packet* p);
  165.                 Packet* deque();
  166.                 Packet* lookup(int n);
  167.                 /* remove a specific packet, which must be in the queue */
  168.                 void remove(Packet*);
  169.         protected:
  170.                 Packet* head_;
  171.                 Packet** tail_;
  172.                 int len_;               // packet count
  173.         };
  174. end{program}
  175. This class maintains a linked-list of packets, and is commonly
  176. used by particular scheduling and buffer management disciplines
  177. to hold an ordered set of packets.
  178. Particular scheduling or buffer management schemes may make
  179. use of several code{PacketQueue} objects.
  180. The code{PacketQueue} class maintains current counts of the number of
  181. packets held in the queue which is returned by the fcn[]{length} method.
  182. The code{enque} function places the specified packet at the end of
  183. the queue and updates the code{len_} member variable.
  184. The code{deque} function returns the packet at the head of the
  185. queue and removes it from the queue (and updates the counters), or
  186. returns NULL if the queue is empty.
  187. The code{lookup} function returns the $n$th packet from the head
  188. of the queue, or NULL otherwise.
  189. The code{remove} function deletes the packet stored in the given address
  190. from the queue (and updates the counters).
  191. It causes an abnormal program termination if the packet does not exist.
  192. section{Example: Drop Tail}
  193. label{sec:droptail}
  194. The following example illustrates the implementation of the
  195. code{Queue/DropTail} object,
  196. which implements FIFO scheduling and
  197. drop-on-overflow buffer management typical of most present-day
  198. Internet routers.
  199. The following definitions declare the class and its OTcl linkage:
  200. begin{program}
  201.         /*
  202.          * {cf A bounded, drop-tail queue}
  203.          */
  204.         class DropTail : public Queue {
  205.          protected:
  206.                 void enque(Packet*);
  207.                 Packet* deque();
  208.                 PacketQueue q_;
  209.         };
  210. end{program}
  211. The base class code{Queue},
  212. from which code{DropTail} is derived, provides most
  213. of the needed functionality.
  214. The drop-tail queue maintains exactly one FIFO queue, implemented
  215. by including an object of the code{PacketQueue} class.
  216. Drop-tail implements its own versions of code{enque} and code{deque}
  217. as follows:
  218. begin{program}
  219.         /*
  220.          * {cf drop-tail}
  221.          */
  222.         void DropTail::enque(Packet* p)
  223.         {
  224.                 q_.enque(p);
  225.                 if (q_.length() >= qlim_) {
  226.                         q_.remove(p);
  227.                         drop(p);
  228.                 }
  229.         }
  230.         Packet* DropTail::deque()
  231.         {
  232.                 return (q_.deque());
  233.         }
  234. end{program}
  235. Here, the code{enque} function first stores the packet in the
  236. internal packet queue (which has no size restrictions), and then
  237. checks the size of the packet queue versus code{qlim_}.
  238. Drop-on-overflow is implemented by dropping the packet most recently
  239. added to the packet queue if the limit is reached or exceeded.
  240. emph{Note:} in the implementation of code{enque} above, 
  241.  setting code{qlim_} to code{n} actually means a queue size of code{n-1}.
  242. Simple FIFO scheduling is implemented in the code{deque} function
  243. by always returning the first packet in the packet queue.
  244. section{Different types of Queue objects}
  245. label{sec:queueobjects}
  246. A queue object is a general class of object capable of holding and
  247. possibly marking or discarding packets as they travel through the
  248. simulated topology. Configuration Parameters used for queue objects are:
  249. begin{description}
  250. item[limit_] The queue size in packets. 
  251. item[blocked_] Set to false by default, this is true if the queue is
  252. blocked (unable to send a packet to its downstream neighbor). 
  253. item[unblock_on_resume_] Set to true by default, indicates a queue
  254. should unblock itself at the time the last packet packet sent has been
  255. transmitted (but not necessarily received). 
  256. end{description}
  257. Other queue objects derived from the base class Queue are drop-tail, FQ,
  258. SFQ, DRR, RED and CBQ queue objects. Each are described as follows:
  259. begin{itemize}
  260. item Drop-tail objects:
  261. Drop-tail objects are a subclass of Queue objects that implement simple
  262. FIFO queue. There are no methods, configuration parameter, or state
  263. variables that are specific to drop-tail objects. 
  264. item FQ objects:
  265. FQ objects are a subclass of Queue objects that implement Fair queuing.
  266. There are no methods that are specific to FQ objects. 
  267. Configuration Parameters are:
  268. begin{description}
  269. item[secsPerByte_] 
  270. end{description}
  271. There are no state variables associated with this object. 
  272. item SFQ objects:
  273. SFQ objects are a subclass of Queue objects that implement Stochastic Fair
  274. queuing. There are no methods that are specific to SFQ objects. 
  275. Configuration Parameters are:
  276. begin{description}
  277. item[maxqueue_]
  278. item[buckets_]
  279. end{description}
  280. There are no state variables associated with this object. 
  281. item DRR objects:
  282. DRR objects are a subclass of Queue objects that implement deficit round
  283. robin scheduling. These objects implement deficit round robin scheduling
  284. amongst different flows ( A particular flow is one which has packets with
  285. the same node and port id OR packets which have the same node id alone).
  286. Also unlike other multi-queue objects, this queue object implements a
  287. single shared buffer space for its different flows. Configuration
  288. Parameters are:
  289. begin{description}
  290. item[buckets_] Indicates the total number of buckets to be used for
  291. hashing each of the flows. 
  292. item[blimit_] Indicates the shared buffer size in bytes. 
  293. item[quantum_] Indicates (in bytes) how much each flow can send during
  294. its turn. 
  295. item[mask_] mask_, when set to 1, means that a particular flow consists
  296. of packets having the same node id (and possibly different port ids),
  297. otherwise a flow consists of packets having the same node and port ids. 
  298. end{description}
  299. item RED objects:
  300. RED objects are a subclass of Queue objects that implement random
  301. early-detection gateways. The object can be configured to either drop or
  302. ``mark'' packets. There are no methods that are specific to RED objects. 
  303. Configuration Parameters are:
  304. begin{description}
  305. item[bytes_] Set to "true" to enable ``byte-mode'' RED, where the size
  306. of arriving packets affect the likelihood of marking (dropping) packets. 
  307. item[queue-in-bytes_]
  308. Set to "true" to measure the average queue size in bytes rather than
  309. packets. Enabling this option also causes thresh_ and maxthresh_ to be
  310. automatically scaled by mean_pktsize_ (see below). 
  311. item[thresh_]
  312. The minimum threshold for the average queue size in packets. 
  313. item[maxthresh_]
  314. The maximum threshold for the average queue size in packets. 
  315. item[mean_pktsize_]
  316. A rough estimate of the average packet size in bytes. Used in updating the
  317. calculated average queue size after an idle period. 
  318. item[q_weight_]
  319. The queue weight, used in the exponential-weighted moving average for
  320. calculating the average queue size. 
  321. item[wait_]
  322. Set to true to maintain an interval between dropped packets. 
  323. item[linterm_]
  324. As the average queue size varies between "thresh_" and "maxthresh_", the
  325. packet dropping probability varies between 0 and "1/linterm". 
  326. item[setbit_]
  327. Set to "true" to mark packets by setting the congestion indication bit in
  328. packet headers rather than drop packets. 
  329. item[drop-tail_]
  330. Set to true to use drop-tail rather than randomdrop when the queue
  331. overflows or the average queue size exceeds "maxthresh_". For a further
  332. explanation of these variables, see [2]. 
  333. end{description}
  334. None of the state variables of the RED implementation are accessible. 
  335. item CBQ objects:
  336. CBQ objects are a subclass of Queue objects that implement class-based
  337. queueing. 
  338. code{$cbq insert <class>}\
  339. Insert traffic class class into the link-sharing structure associated with
  340. link object cbq. 
  341. code{$cbq bind <cbqclass> <id1> [$id2]}\
  342. Cause packets containing flow id id1 (or those in the range id1 to
  343. id2 inclusive) to be associated with the traffic class cbqclass. 
  344. code{$cbq algorithm <alg>}\
  345. Select the CBQ internal algorithm. <alg> may be set to one of:
  346. "ancestor-only", "top-level", or "formal". 
  347. item CBQ/WRR objects:
  348. CBQ/WRR objects are a subclass of CBQ objects that implement weighted
  349. round-robin scheduling among classes of the same priority level. In
  350. contrast, CBQ objects implement packet-by-packet round-robin scheduling
  351. among classes of the same priority level. Configuration Parameters are:
  352. begin{description}
  353. item[maxpkt_] The maximum size of a packet in bytes. This is used only
  354. by CBQ/WRR objects in computing maximum bandwidth allocations for the
  355. weighted round-robin scheduler. 
  356. end{description}
  357. end{itemize}
  358. textsc{CBQclass Objects}\
  359. CBQClass objects implement the traffic classes associated with CBQ
  360. objects. 
  361. code{$cbqclass setparams <parent> <okborrow> <allot> <maxidle> <prio> <level>}\
  362. Sets several of the configuration parameters for the CBQ traffic class
  363. (see below). 
  364. code{$cbqclass parent <cbqcl|none>}\
  365. specify the parent of this class in the link-sharing tree. The parent may
  366. be specified as ``none'' to indicate this class is a root. 
  367. code{$cbqclass newallot <a>}\
  368. Change the link allocation of this class to the specified amount (in range
  369. 0.0 to 1.0). Note that only the specified class is affected. 
  370. code{$cbqclass install-queue <q>}\
  371. Install a Queue object into the compound CBQ or CBQ/WRR link structure.
  372. When a CBQ object is initially created, it includes no internal queue
  373. (only a packet classifier and scheduler).
  374. Configuration Parameters are:
  375. begin{description}
  376. item[okborrow_] is a boolean indicating the class is permitted to borrow
  377. bandwidth from its parent. 
  378. item[allot_] is the maximum fraction of link bandwidth allocated to the
  379. class expressed as a real number between 0.0 and 1.0. 
  380. item[maxidle_] is the maximum amount of time a class may be required to
  381. have its packets queued before they are permitted to be forwarded 
  382. item[priority_]
  383. is the class' priority level with respect to other classes. This value may
  384. range from 0 to 10, and more than one class may exist at the same
  385. priority. Priority 0 is the highest priority. 
  386. item[level_]
  387. is the level of this class in the link-sharing tree. Leaf nodes in the
  388. tree are considered to be at level 1; their parents are at level 2, etc. 
  389. item[extradelay_]
  390. increase the delay experienced by a delayed class by the specified time 
  391. end{description}
  392. textsc{Queue-monitor objects}\
  393. QueueMonitor Objects are used to monitor a set of packet and byte arrival,
  394. departure and drop counters. It also includes support for aggregate
  395. statistics such as average queue size, etc.
  396. code{$queuemonitor}\
  397. reset all the cumulative counters described below (arrivals, departures,
  398. and drops) to zero. Also, reset the integrators and delay sampler, if
  399. defined. 
  400. code{$queuemonitor set-delay-samples <delaySamp_>}\
  401. Set up the Samples object delaySamp_ to record statistics about queue
  402. delays. delaySamp_ is a handle to a Samples object i.e the Samples object
  403. should have already been created. 
  404. code{$queuemonitor get-bytes-integrator}\
  405. Returns an Integrator object that can be used to find the integral of the
  406. queue size in bytes. 
  407. code{$queuemonitor get-pkts-integrator}\
  408. Returns an Integrator object that can be used to find the integral of the
  409. queue size in packets.
  410. code{$queuemonitor get-delay-samples}\
  411. Returns a Samples object delaySamp_ to record statistics about queue
  412. delays.
  413. \
  414. There are no configuration parameters specific to this object. 
  415. \
  416. State Variables are:
  417. begin{description}
  418. item[size_] Instantaneous queue size in bytes. 
  419. item[pkts_] Instantaneous queue size in packets. 
  420. item[parrivals_] Running total of packets that have arrived. 
  421. item[barrivals_] Running total of bytes contained in packets that have
  422. arrived. 
  423. item[pdepartures_] Running total of packets that have departed (not
  424. dropped). 
  425. item[bdepartures_] Running total of bytes contained in packets that have
  426. departed (not dropped). 
  427. item[pdrops_] Total number of packets dropped. 
  428. item[bdrops_] Total number of bytes dropped. 
  429. item[bytesInt_] Integrator object that computes the integral of the
  430. queue size in bytes. The sum_ variable of this object has the running sum
  431. (integral) of the queue size in bytes. 
  432. item[pktsInt_] Integrator object that computes the integral of the queue
  433. size in packets. The sum_ variable of this object has the running sum
  434. (integral) of the queue size in packets. 
  435. end{description}
  436. textsc{QUEUEMONITOR/ED Objects}\
  437. This derived object is capable of differentiating regular packet drops
  438. from early drops. Some queues distinguish regular drops (e.g. drops due to
  439. buffer exhaustion) from other drops (e.g. random drops in RED queues).
  440. Under some circumstances, it is useful to distinguish these two types of
  441. drops. 
  442. \
  443. State Variables are:
  444. begin{description}
  445. item[epdrops_] The number of packets that have been dropped ``early''. 
  446. item[ebdrops_] The number of bytes comprising packets that have been
  447. dropped ``early''. 
  448. end{description}
  449. Note: because this class is a subclass of QueueMonitor, objects of this
  450. type also have fields such as pdrops_ and bdrops_. These fields describe
  451. the total number of dropped packets and bytes, including both early and
  452. non-early drops. 
  453. textsc{QueueMonitor/ED/Flowmon Objects}\
  454. These objects may be used in the place of a conventional QueueMonitor
  455. object when wishing to collect per-flow counts and statistics in addition
  456. to the aggregate counts and statistics provided by the basic QueueMonitor. 
  457. code{$fmon classifier <cl>}\
  458. This inserts (read) the specified classifier into (from) the flow monitor
  459. object. This is used to map incoming packets to which flows they are
  460. associated with. 
  461. code{$fmon dump}\
  462. Dump the current per-flow counters and statistics to the I/O channel
  463. specified in a previous attach operation. 
  464. code{$fmon flows}\
  465. Return a character string containing the names of all flow objects known
  466. by this flow monitor. Each of these objects are of type
  467. QueueMonitor/ED/Flow. 
  468. code{$fmon attach <chan>}\
  469. Attach a tcl I/O channel to the flow monitor. Flow statistics are written
  470. to the channel when the dump operation is executed. 
  471. Configuration Parameters are:
  472. begin{description}
  473. item[enable_in_] Set to true by default, indicates that per-flow
  474. arrival state should be kept by the flow monitor. If set to false, only
  475. the aggregate arrival information is kept. 
  476. item[enable_out_]
  477. Set to true by default, indicates that per-flow departure state should be
  478. kept by the flow monitor. If set to false, only the aggregate departure
  479. information is kept. 
  480. item[enable_drop_]
  481. Set to true by default, indicates that per-flow drop state should be kept
  482. by the flow monitor. If set to false, only the aggregate drop information
  483. is kept. 
  484. item[enable_edrop_]
  485. Set to true by default, indicates that per-flow early drop state should be
  486. kept by the flow monitor. If set to false, only the aggregate early drop
  487. information is kept. 
  488. end{description}
  489. textsc{QueueMonitor/ED/Flow Objects}\
  490. These objects contain per-flow counts and statistics managed by a
  491. QueueMonitor/ED/Flowmon object. They are generally created in an OTcl
  492. callback procedure when a flow monitor is given a packet it cannot map on
  493. to a known flow. Note that the flow monitor's classifier is responsible
  494. for mapping packets to flows in some arbitrary way. Thus, depending on the
  495. type of classifier used, not all of the state variables may be relevant
  496. (e.g. one may classify packets based only on flow id, in which case the
  497. source and destination addresses may not be significant). 
  498. State Variables are:
  499. begin{description}
  500. item[src_] The source address of packets belonging to this flow. 
  501. item[dst_] The destination address of packets belonging to this flow. 
  502. item[flowid_] The flow id of packets belonging to this flow. 
  503. end{description}
  504. section{Commands at a glance}
  505. label{sec:queuecommand}
  506. Following is a list of queue commands used in simulation scripts:
  507. begin{flushleft}
  508. code{$ns_ queue-limit <n1> <n2> <limit>}\
  509. This sets a limit on the maximum buffer size of the queue in the link between
  510. nodes <n1> and <n2>.
  511. code{$ns_ trace-queue <n1> <n2> <optional:file>}\
  512. This sets up trace objects to log events in the queue. If tracefile is not
  513. passed, it uses code{traceAllFile_} to write the events.
  514. code{$ns_ namtrace-queue <n1> <n2> <optional:file>}\
  515. Similar to trace-queue above, this sets up nam-tracing in the queue.
  516. code{$ns_ monitor-queue <n1> <n2> <optional:qtrace> <optional:sampleinterval>}\
  517. This command inserts objects that allows us to monitor the queue size. This
  518. returns a handle to the object that may be queried to determine the average
  519. queue size. The default value for sampleinterval is 0.1.
  520. end{flushleft}
  521. % JoBS contributed by Nicolas Christin <nicolas@cs.virginia.edu>
  522. input{jobs}
  523. endinput