chunks: react to congestion marks
Change-Id: I96efe1bc3ec7a54080c76676892114f2c79003ed
refs: #4289
diff --git a/tools/chunks/catchunks/ndncatchunks.cpp b/tools/chunks/catchunks/ndncatchunks.cpp
index 2242a83..822194a 100644
--- a/tools/chunks/catchunks/ndncatchunks.cpp
+++ b/tools/chunks/catchunks/ndncatchunks.cpp
@@ -26,6 +26,7 @@
* @author Davide Pesavento
* @author Weiwei Liu
* @author Klaus Schneider
+ * @author Chavoosh Ghasemi
*/
#include "aimd-statistics-collector.hpp"
@@ -58,7 +59,7 @@
// congestion control parameters, CWA refers to conservative window adaptation,
// i.e. only reduce window size at most once per RTT
- bool disableCwa(false), resetCwndToInit(false);
+ bool disableCwa(false), resetCwndToInit(false), ignoreCongMarks(false);
double aiStep(1.0), mdCoef(0.5), alpha(0.125), beta(0.25),
minRto(200.0), maxRto(4000.0);
int initCwnd(1), initSsthresh(std::numeric_limits<int>::max()), k(4);
@@ -104,7 +105,11 @@
"log file for AIMD rtt statistics")
("aimd-disable-cwa", po::bool_switch(&disableCwa),
"disable Conservative Window Adaptation, "
- "i.e. reduce window on each timeout (instead of at most once per RTT)")
+ "i.e. reduce window on each congestion event (timeout or congestion mark) "
+ "instead of at most once per RTT")
+ ("aimd-ignore-cong-marks", po::bool_switch(&ignoreCongMarks),
+ "disable reaction to congestion marks, "
+ "the default is to decrease the window after receiving a congestion mark")
("aimd-reset-cwnd-to-init", po::bool_switch(&resetCwndToInit),
"reset cwnd to initial cwnd when loss event occurs, default is "
"resetting to ssthresh")
@@ -253,6 +258,7 @@
optionsPipeline.initSsthresh = static_cast<double>(initSsthresh);
optionsPipeline.aiStep = aiStep;
optionsPipeline.mdCoef = mdCoef;
+ optionsPipeline.ignoreCongMarks = ignoreCongMarks;
auto aimdPipeline = make_unique<PipelineInterestsAimd>(face, *rttEstimator, optionsPipeline);
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.cpp b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
index b979a51..61ed8f3 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.cpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
@@ -33,6 +33,8 @@
namespace chunks {
namespace aimd {
+constexpr double PipelineInterestsAimd::MIN_SSTHRESH;
+
PipelineInterestsAimd::PipelineInterestsAimd(Face& face, RttEstimator& rttEstimator,
const Options& options)
: PipelineInterests(face)
@@ -46,6 +48,7 @@
, m_nInFlight(0)
, m_nLossEvents(0)
, m_nRetransmitted(0)
+ , m_nCongMarks(0)
, m_cwnd(m_options.initCwnd)
, m_ssthresh(m_options.initSsthresh)
, m_hasFailure(false)
@@ -244,7 +247,30 @@
m_nInFlight--;
}
- increaseWindow();
+ // upon finding congestion mark, decrease the window size
+ // without retransmitting any packet
+ if (data.getCongestionMark() > 0) {
+ m_nCongMarks++;
+ if (!m_options.ignoreCongMarks) {
+ if (m_options.disableCwa || m_highData > m_recPoint) {
+ m_recPoint = m_highInterest; // react to only one congestion event (timeout or congestion mark)
+ // per RTT (conservative window adaptation)
+ decreaseWindow();
+
+ if (m_options.isVerbose) {
+ std::cerr << "Received congestion mark, value = " << data.getCongestionMark()
+ << ", new cwnd = " << m_cwnd << std::endl;
+ }
+ }
+ }
+ else {
+ increaseWindow();
+ }
+ }
+ else {
+ increaseWindow();
+ }
+
onData(data);
if (segInfo.state == SegmentState::FirstTimeSent ||
@@ -324,7 +350,7 @@
m_nLossEvents++;
if (m_options.isVerbose) {
- std::cerr << "Packet loss event, cwnd = " << m_cwnd
+ std::cerr << "Packet loss event, new cwnd = " << m_cwnd
<< ", ssthresh = " << m_ssthresh << std::endl;
}
}
@@ -382,7 +408,7 @@
PipelineInterestsAimd::decreaseWindow()
{
// please refer to RFC 5681, Section 3.1 for the rationale behind it
- m_ssthresh = std::max(2.0, m_cwnd * m_options.mdCoef); // multiplicative decrease
+ m_ssthresh = std::max(MIN_SSTHRESH, m_cwnd * m_options.mdCoef); // multiplicative decrease
m_cwnd = m_options.resetCwndToInit ? m_options.initCwnd : m_ssthresh;
afterCwndChange(time::steady_clock::now() - getStartTime(), m_cwnd);
@@ -411,7 +437,8 @@
std::cerr << "Total # of packet loss events: " << m_nLossEvents << "\n"
<< "Packet loss rate: "
<< static_cast<double>(m_nLossEvents) / static_cast<double>(m_nReceived) << "\n"
- << "Total # of retransmitted segments: " << m_nRetransmitted << "\n";
+ << "Total # of retransmitted segments: " << m_nRetransmitted << "\n"
+ << "Total # of received congestion marks: " << m_nCongMarks << "\n";
}
std::ostream&
@@ -444,6 +471,7 @@
<< "\tMultiplicative decrease factor = " << options.mdCoef << "\n"
<< "\tRTO check interval = " << options.rtoCheckInterval << "\n"
<< "\tMax retries on timeout or Nack = " << options.maxRetriesOnTimeoutOrNack << "\n"
+ << "\tReaction to congestion marks " << (options.ignoreCongMarks ? "disabled" : "enabled") << "\n"
<< "\tConservative Window Adaptation " << (options.disableCwa ? "disabled" : "enabled") << "\n"
<< "\tResetting cwnd to " << (options.resetCwndToInit ? "initCwnd" : "ssthresh") << " upon loss event\n";
return os;
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.hpp b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
index 5aedbfb..bbc9940 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.hpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
@@ -56,6 +56,7 @@
time::milliseconds rtoCheckInterval{10}; ///< interval for checking retransmission timer
bool disableCwa = false; ///< disable Conservative Window Adaptation
bool resetCwndToInit = false; ///< reduce cwnd to initCwnd when loss event occurs
+ bool ignoreCongMarks = false; ///< disable window decrease after congestion marks
};
/**
@@ -187,6 +188,7 @@
printSummary() const final;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+ static constexpr double MIN_SSTHRESH = 2.0;
const Options m_options;
RttEstimator& m_rttEstimator;
Scheduler m_scheduler;
@@ -200,6 +202,7 @@
int64_t m_nInFlight; ///< # of segments in flight
int64_t m_nLossEvents; ///< # of loss events occurred
int64_t m_nRetransmitted; ///< # of segments retransmitted
+ int64_t m_nCongMarks; ///< # of data packets with congestion mark
double m_cwnd; ///< current congestion window size (in segments)
double m_ssthresh; ///< current slow start threshold