traffic-control: Add usage of timestamp for latency calculation for PIE
This commit is contained in:
committed by
Tom Henderson
parent
b99295e119
commit
bdb5f393dd
@@ -29,7 +29,7 @@ and Takashi Hayakawa.
|
||||
|
||||
* ``PieQueueDisc::CalculateP ()``: This routine is called at a regular interval of `m_tUpdate` and updates the drop probability, which is required by ``PieQueueDisc::DropEarly()``
|
||||
|
||||
* ``PieQueueDisc::DoDequeue ()``: This routine calculates the average departure rate which is required for updating the drop probability in ``PieQueueDisc::CalculateP ()``
|
||||
* ``PieQueueDisc::DoDequeue ()``: This routine calulates `m_qDelay` using timestamp by default or optionally with `UseDqRateEstimator` enabled calculates the average departure rate which is required for updating the drop probability in ``PieQueueDisc::CalculateP ()``
|
||||
|
||||
References
|
||||
==========
|
||||
@@ -56,7 +56,7 @@ The key attributes that the PieQueue class holds include the following:
|
||||
* ``MaxBurstAllowance:`` Current max burst allowance in seconds before random drop. The default value is 0.1 seconds.
|
||||
* ``A:`` Value of alpha. The default value is 0.125.
|
||||
* ``B:`` Value of beta. The default value is 1.25.
|
||||
|
||||
* ``UseDequeueRateEstimator:`` Enable/Disable usage of Dequeue Rate Estimator (Default: false).
|
||||
Examples
|
||||
========
|
||||
|
||||
@@ -80,6 +80,7 @@ The PIE model is tested using :cpp:class:`PieQueueDiscTestSuite` class defined i
|
||||
* Test 3: same as test 2, but with higher QueueDelayReference
|
||||
* Test 4: same as test 2, but with reduced dequeue rate
|
||||
* Test 5: same dequeue rate as test 4, but with higher Tupdate
|
||||
* Test 6: same as test 2, but with UseDequeueRateEstimator enabled
|
||||
|
||||
The test suite can be run using the following commands:
|
||||
|
||||
|
||||
@@ -92,6 +92,11 @@ TypeId PieQueueDisc::GetTypeId (void)
|
||||
TimeValue (Seconds (0.1)),
|
||||
MakeTimeAccessor (&PieQueueDisc::m_maxBurst),
|
||||
MakeTimeChecker ())
|
||||
.AddAttribute ("UseDequeueRateEstimator",
|
||||
"Enable/Disable usage of Dequeue Rate Estimator",
|
||||
BooleanValue (false),
|
||||
MakeBooleanAccessor (&PieQueueDisc::m_useDqRateEstimator),
|
||||
MakeBooleanChecker ())
|
||||
;
|
||||
|
||||
return tid;
|
||||
@@ -122,7 +127,6 @@ PieQueueDisc::DoDispose (void)
|
||||
Time
|
||||
PieQueueDisc::GetQueueDelay (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_qDelay;
|
||||
}
|
||||
|
||||
@@ -236,17 +240,25 @@ void PieQueueDisc::CalculateP ()
|
||||
Time qDelay;
|
||||
double p = 0.0;
|
||||
bool missingInitFlag = false;
|
||||
if (m_avgDqRate > 0)
|
||||
|
||||
if (m_useDqRateEstimator)
|
||||
{
|
||||
qDelay = Time (Seconds (GetInternalQueue (0)->GetNBytes () / m_avgDqRate));
|
||||
if (m_avgDqRate > 0)
|
||||
{
|
||||
qDelay = Time (Seconds (GetInternalQueue (0)->GetNBytes () / m_avgDqRate));
|
||||
}
|
||||
else
|
||||
{
|
||||
qDelay = Time (Seconds (0));
|
||||
missingInitFlag = true;
|
||||
}
|
||||
m_qDelay = qDelay;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDelay = Time (Seconds (0));
|
||||
missingInitFlag = true;
|
||||
qDelay = m_qDelay;
|
||||
}
|
||||
|
||||
m_qDelay = qDelay;
|
||||
NS_LOG_DEBUG ("Queue delay while calculating probability: " << qDelay.GetMilliSeconds () << "ms");
|
||||
|
||||
if (m_burstAllowance.GetSeconds () > 0)
|
||||
{
|
||||
@@ -357,51 +369,62 @@ PieQueueDisc::DoDequeue ()
|
||||
|
||||
// if not in a measurement cycle and the queue has built up to dq_threshold,
|
||||
// start the measurement cycle
|
||||
|
||||
if ( (GetInternalQueue (0)->GetNBytes () >= m_dqThreshold) && (!m_inMeasurement) )
|
||||
if (m_useDqRateEstimator)
|
||||
{
|
||||
m_dqStart = now;
|
||||
m_dqCount = 0;
|
||||
m_inMeasurement = true;
|
||||
}
|
||||
|
||||
if (m_inMeasurement)
|
||||
{
|
||||
m_dqCount += pktSize;
|
||||
|
||||
// done with a measurement cycle
|
||||
if (m_dqCount >= m_dqThreshold)
|
||||
if ( (GetInternalQueue (0)->GetNBytes () >= m_dqThreshold) && (!m_inMeasurement) )
|
||||
{
|
||||
m_dqStart = now;
|
||||
m_dqCount = 0;
|
||||
m_inMeasurement = true;
|
||||
}
|
||||
|
||||
double tmp = now - m_dqStart;
|
||||
if (m_inMeasurement)
|
||||
{
|
||||
m_dqCount += pktSize;
|
||||
|
||||
if (tmp > 0)
|
||||
// done with a measurement cycle
|
||||
if (m_dqCount >= m_dqThreshold)
|
||||
{
|
||||
if (m_avgDqRate == 0)
|
||||
|
||||
double tmp = now - m_dqStart;
|
||||
|
||||
if (tmp > 0)
|
||||
{
|
||||
m_avgDqRate = m_dqCount / tmp;
|
||||
if (m_avgDqRate == 0)
|
||||
{
|
||||
m_avgDqRate = m_dqCount / tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_avgDqRate = (0.5 * m_avgDqRate) + (0.5 * (m_dqCount / tmp));
|
||||
}
|
||||
}
|
||||
NS_LOG_DEBUG ("Average Dequeue Rate after Dequeue: " << m_avgDqRate);
|
||||
|
||||
// restart a measurement cycle if there is enough data
|
||||
if (GetInternalQueue (0)->GetNBytes () > m_dqThreshold)
|
||||
{
|
||||
m_dqStart = now;
|
||||
m_dqCount = 0;
|
||||
m_inMeasurement = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_avgDqRate = (0.5 * m_avgDqRate) + (0.5 * (m_dqCount / tmp));
|
||||
m_dqCount = 0;
|
||||
m_inMeasurement = false;
|
||||
}
|
||||
}
|
||||
|
||||
// restart a measurement cycle if there is enough data
|
||||
if (GetInternalQueue (0)->GetNBytes () > m_dqThreshold)
|
||||
{
|
||||
m_dqStart = now;
|
||||
m_dqCount = 0;
|
||||
m_inMeasurement = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dqCount = 0;
|
||||
m_inMeasurement = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_qDelay = Time (Seconds (now - item->GetTimeStamp ().GetSeconds ()));
|
||||
|
||||
if (GetInternalQueue (0)->GetNBytes () == 0)
|
||||
{
|
||||
m_qDelay = Time (Seconds (0));
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#define BURST_RESET_TIMEOUT 1.5
|
||||
|
||||
class PieQueueDiscTestCase; // Forward declaration for unit test
|
||||
namespace ns3 {
|
||||
|
||||
class TraceContainer;
|
||||
@@ -105,6 +106,7 @@ protected:
|
||||
virtual void DoDispose (void);
|
||||
|
||||
private:
|
||||
friend class::PieQueueDiscTestCase; // Test code
|
||||
virtual bool DoEnqueue (Ptr<QueueDiscItem> item);
|
||||
virtual Ptr<QueueDiscItem> DoDequeue (void);
|
||||
virtual bool CheckConfig (void);
|
||||
@@ -140,6 +142,7 @@ private:
|
||||
double m_a; //!< Parameter to pie controller
|
||||
double m_b; //!< Parameter to pie controller
|
||||
uint32_t m_dqThreshold; //!< Minimum queue size in bytes before dequeue rate is measured
|
||||
bool m_useDqRateEstimator; //!< Enable/Disable usage of dequeue rate estimator for queue delay calculation
|
||||
|
||||
// ** Variables maintained by PIE
|
||||
double m_dropProb; //!< Variable used in calculation of drop probability
|
||||
|
||||
@@ -220,14 +220,8 @@ PieQueueDiscTestCase::RunPieTest (QueueSizeUnit mode)
|
||||
pktSize = 1000; // pktSize != 0 because DequeueThreshold always works in bytes
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
|
||||
true, "Verify that we can actually set the attribute MaxSize");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("A", DoubleValue (0.125)), true,
|
||||
"Verify that we can actually set the attribute A");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("B", DoubleValue (1.25)), true,
|
||||
"Verify that we can actually set the attribute B");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.03))), true,
|
||||
"Verify that we can actually set the attribute Tupdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Supdate", TimeValue (Seconds (0.0))), true,
|
||||
"Verify that we can actually set the attribute Supdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
|
||||
"Verify that we can actually set the attribute DequeueThreshold");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.02))), true,
|
||||
@@ -249,14 +243,8 @@ PieQueueDiscTestCase::RunPieTest (QueueSizeUnit mode)
|
||||
queue = CreateObject<PieQueueDisc> ();
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
|
||||
true, "Verify that we can actually set the attribute MaxSize");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("A", DoubleValue (0.125)), true,
|
||||
"Verify that we can actually set the attribute A");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("B", DoubleValue (1.25)), true,
|
||||
"Verify that we can actually set the attribute B");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.03))), true,
|
||||
"Verify that we can actually set the attribute Tupdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Supdate", TimeValue (Seconds (0.0))), true,
|
||||
"Verify that we can actually set the attribute Supdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
|
||||
"Verify that we can actually set the attribute DequeueThreshold");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.08))), true,
|
||||
@@ -278,14 +266,8 @@ PieQueueDiscTestCase::RunPieTest (QueueSizeUnit mode)
|
||||
queue = CreateObject<PieQueueDisc> ();
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
|
||||
true, "Verify that we can actually set the attribute MaxSize");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("A", DoubleValue (0.125)), true,
|
||||
"Verify that we can actually set the attribute A");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("B", DoubleValue (1.25)), true,
|
||||
"Verify that we can actually set the attribute B");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.03))), true,
|
||||
"Verify that we can actually set the attribute Tupdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Supdate", TimeValue (Seconds (0.0))), true,
|
||||
"Verify that we can actually set the attribute Supdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
|
||||
"Verify that we can actually set the attribute DequeueThreshold");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.02))), true,
|
||||
@@ -307,14 +289,8 @@ PieQueueDiscTestCase::RunPieTest (QueueSizeUnit mode)
|
||||
queue = CreateObject<PieQueueDisc> ();
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
|
||||
true, "Verify that we can actually set the attribute MaxSize");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("A", DoubleValue (0.125)), true,
|
||||
"Verify that we can actually set the attribute A");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("B", DoubleValue (1.25)), true,
|
||||
"Verify that we can actually set the attribute B");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.09))), true,
|
||||
"Verify that we can actually set the attribute Tupdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Supdate", TimeValue (Seconds (0.0))), true,
|
||||
"Verify that we can actually set the attribute Supdate");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
|
||||
"Verify that we can actually set the attribute DequeueThreshold");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.02))), true,
|
||||
@@ -330,6 +306,23 @@ PieQueueDiscTestCase::RunPieTest (QueueSizeUnit mode)
|
||||
uint32_t test5 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
|
||||
NS_TEST_EXPECT_MSG_LT (test5, test4, "Test 5 should have less unforced drops than test 4");
|
||||
NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
|
||||
|
||||
|
||||
// test 6: same as test 2, but with UseDequeueRateEstimator enabled
|
||||
queue = CreateObject<PieQueueDisc> ();
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
|
||||
true, "Verify that we can actually set the attribute MaxSize");
|
||||
NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseDequeueRateEstimator", BooleanValue (true)), true,
|
||||
"Verify that we can actually set the attribute UseTimestamp");
|
||||
queue->Initialize ();
|
||||
EnqueueWithDelay (queue, pktSize, 400);
|
||||
DequeueWithDelay (queue, 0.014, 400);
|
||||
Simulator::Stop (Seconds (8.0));
|
||||
Simulator::Run ();
|
||||
st = queue->GetStats ();
|
||||
uint32_t test6 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
|
||||
NS_TEST_EXPECT_MSG_NE (test6, 0, "There should be some unforced drops");
|
||||
NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user