# HG changeset patch # User jnin # Date 1301933837 -7200 # Node ID c92f27568aeffe267411266acd38753447b58601 # Parent 50dd9246e7808aa6748e3aa8435b95392b3d0e69 Fixed throughput calculation Fixed output format to be compliant with Requirements Document diff -r 50dd9246e780 -r c92f27568aef src/lte/helper/rlc-stats-calculator.cc --- a/src/lte/helper/rlc-stats-calculator.cc Fri Apr 01 12:02:18 2011 +0200 +++ b/src/lte/helper/rlc-stats-calculator.cc Mon Apr 04 18:17:17 2011 +0200 @@ -22,6 +22,8 @@ #include "ns3/string.h" #include "ns3/nstime.h" #include +#include +#include namespace ns3 { @@ -30,7 +32,8 @@ NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator); RlcStatsCalculator::RlcStatsCalculator() : - m_outputFilename ("") + m_outputFilename (""), + m_firstWrite(true) { NS_LOG_FUNCTION (this); @@ -53,6 +56,15 @@ StringValue ("RlcStats.csv"), MakeStringAccessor (&RlcStatsCalculator::SetOutputFilename), MakeStringChecker ()) + .AddAttribute ("StartTime", + "Start time of the on going epoch.", + TimeValue ( Seconds(0.) ), + MakeTimeAccessor (&RlcStatsCalculator::m_startTime), + MakeTimeChecker ()) + .AddAttribute("EpochDuration", + "Epoch duration.", TimeValue(Seconds(0.25)), + MakeTimeAccessor(&RlcStatsCalculator::m_epochDuration), + MakeTimeChecker()) ; return tid; } @@ -67,81 +79,117 @@ RlcStatsCalculator::TxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize) { NS_LOG_FUNCTION (this << "TxPDU" << rnti << (uint32_t) lcid << packetSize); - lteFlowId_t pair (rnti, lcid); - - m_txPackets[pair]++; + if (Simulator::Now () > m_startTime ) + { + lteFlowId_t pair (rnti, lcid); + m_txPackets[pair]++; + } + CheckEpoch (); } void RlcStatsCalculator::RxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) { NS_LOG_FUNCTION (this << "RxPDU" << rnti << (uint32_t) lcid << packetSize << delay); - lteFlowId_t pair (rnti, lcid); - - m_rxPackets [pair]++; - m_rxData [pair] += packetSize; + if (Simulator::Now () > m_startTime ) + { + lteFlowId_t pair(rnti, lcid); + m_rxPackets[pair]++; + m_rxData[pair] += packetSize; + m_throughput[pair] = 8 * m_rxData[pair] / 1.0e9 * (Simulator::Now().GetNanoSeconds() - m_startTime.GetNanoSeconds()); - uint64StatsMap::iterator it = m_delay.find (pair); - if ( it == m_delay.end () ) - { - m_delay[pair] = CreateObject > (); + uint64StatsMap::iterator it = m_delay.find(pair); + if (it == m_delay.end()) + { + m_delay[pair] = CreateObject > (); + } + m_delay[pair]->Update(delay); } - m_delay[pair]->Update (delay); + CheckEpoch (); } void RlcStatsCalculator::ShowResults (void) { uint32Map::iterator it; - uint64Map::iterator itData; - uint64StatsMap::iterator itDelay; + NS_LOG_FUNCTION (this << m_outputFilename.c_str ()); NS_LOG_INFO ("Write Rlc Stats in: " << m_outputFilename.c_str ()); std::ofstream m_outFile; - m_outFile.open (m_outputFilename.c_str ()); - if (! m_outFile.is_open ()) - { - NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ()); - return; - } + if ( m_firstWrite == true ) + { + m_outFile.open (m_outputFilename.c_str ()); + if (! m_outFile.is_open ()) + { + NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ()); + return; + } + m_firstWrite = false; + m_outFile << "# startTime, endTime, RNTI, LCID, throughput (bps), delay (s), PDU loss ratio (%)" << std::endl; + } + else + { + m_outFile.open (m_outputFilename.c_str (), std::ios_base::app); + if (! m_outFile.is_open ()) + { + NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ()); + return; + } + } - m_outFile << "# Parameter, RNTI, LCID, value" << std::endl; + + + // Get all the unique lteFlowIds in the calculator + std::vector lteFlowIds; for ( it = m_txPackets.begin(); it != m_txPackets.end(); ++it) { - m_outFile << "TxPackets, " << (*it).first.m_rnti << ", " - << (uint32_t) (*it).first.m_lcId << ", " - << (*it).second << std::endl; - } - for ( it = m_rxPackets.begin(); it != m_rxPackets.end(); ++it) - { - m_outFile << "RxPackets, " << (*it).first.m_rnti << ", " - << (uint32_t) (*it).first.m_lcId << ", " - << (*it).second << std::endl; - } - for ( itData = m_rxData.begin(); itData != m_rxData.end(); ++itData) - { - m_outFile << "RxData, " << (*itData).first.m_rnti << ", " - << (uint32_t) (*itData).first.m_lcId << ", " - << (*itData).second << std::endl; - } - for ( itData = m_rxData.begin(); itData != m_rxData.end(); ++itData) - { - m_outFile << "Throughput, " << (*itData).first.m_rnti << ", " - << (uint32_t) (*itData).first.m_lcId << ", " - << GetThroughput ((*itData).first) << std::endl; - } - for ( itDelay = m_delay.begin (); itDelay != m_delay.end (); ++itDelay) - { - m_outFile << "Delay, " << (*itDelay).first.m_rnti << ", " - << (uint32_t) (*itDelay).first.m_lcId << ", " - << GetDelay ((*itDelay).first) << std::endl; + if (find (lteFlowIds.begin (), lteFlowIds.end (), (*it).first ) == lteFlowIds.end () ) + { + lteFlowIds.push_back ((*it).first); + } } + std::vector::iterator itFlow; + Time endTime = m_startTime + m_epochDuration; + for ( itFlow = lteFlowIds.begin(); itFlow != lteFlowIds.end(); ++itFlow) + { + m_outFile << m_startTime.GetNanoSeconds () / 1.0e9 << " " << endTime.GetNanoSeconds() / 1.0e9; + m_outFile << " " << (*itFlow).m_rnti << " " << (uint32_t) (*itFlow).m_lcId << " " << GetThroughput (*itFlow); + m_outFile << " " << GetDelay(*itFlow) << " " << GetPacketLossProbability (*itFlow) << std::endl; + } m_outFile.close (); } +void +RlcStatsCalculator::ResetResults (void) +{ + m_txPackets.erase (m_txPackets.begin (), m_txPackets.end () ); + m_rxPackets.erase (m_rxPackets.begin (), m_rxPackets.end () ); + m_rxData.erase (m_rxData.begin (), m_rxData.end () ); + m_throughput.erase (m_throughput.begin (), m_throughput.end () ); + m_delay.erase (m_delay.begin (), m_delay.end () ); +} + +void +RlcStatsCalculator::CheckEpoch (void) +{ + if ( Simulator::Now () > m_startTime + m_epochDuration ) + { + ShowResults(); + ResetResults(); + StartEpoch(); + } + +} + +void +RlcStatsCalculator::StartEpoch (void) +{ + m_startTime += m_epochDuration; +} + uint32_t RlcStatsCalculator::GetTxPackets (lteFlowId_t p) { @@ -174,10 +222,13 @@ double RlcStatsCalculator::GetThroughput (lteFlowId_t p) { - // TODO: Fix throughput calculation with the correct time - // NOTE: At this moment, Simulator::Now() is not available anymore - //return (double) m_rxData[p] / Simulator::Now().GetSeconds(); - return 0; + return m_throughput[p]; +} + +double +RlcStatsCalculator::GetPacketLossProbability (lteFlowId_t p) +{ + return (GetTxPackets (p) - GetRxPackets (p)) / (double) GetTxPackets (p); } uint32_t @@ -215,4 +266,11 @@ return GetThroughput (p); } +double +RlcStatsCalculator::GetPacketLossProbability (uint16_t rnti, uint8_t lcid) +{ + lteFlowId_t p (rnti, lcid); + return GetPacketLossProbability (p); +} + } // namespace ns3 diff -r 50dd9246e780 -r c92f27568aef src/lte/helper/rlc-stats-calculator.h --- a/src/lte/helper/rlc-stats-calculator.h Fri Apr 01 12:02:18 2011 +0200 +++ b/src/lte/helper/rlc-stats-calculator.h Mon Apr 04 18:17:17 2011 +0200 @@ -35,6 +35,7 @@ typedef std::map uint32Map; typedef std::map uint64Map; typedef std::map > > uint64StatsMap; +typedef std::map doubleMap; class RlcStatsCalculator : public Object @@ -55,21 +56,42 @@ uint64_t GetRxData (lteFlowId_t p); uint64_t GetDelay (lteFlowId_t p); double GetThroughput (lteFlowId_t p); + double GetPacketLossProbability (lteFlowId_t p); uint32_t GetTxPackets (uint16_t rnti, uint8_t lcid); uint32_t GetRxPackets (uint16_t rnti, uint8_t lcid); uint64_t GetRxData (uint16_t rnti, uint8_t lcid); uint64_t GetDelay (uint16_t rnti, uint8_t lcid); double GetThroughput (uint16_t rnti, uint8_t lcid); + double GetPacketLossProbability (uint16_t rnti, uint8_t lcid); private: void ShowResults (void); + void ResetResults (void); + + void StartEpoch (void); + void CheckEpoch (void); + std::string m_outputFilename; std::ofstream m_outFile; uint32Map m_txPackets; uint32Map m_rxPackets; uint64Map m_rxData; + doubleMap m_throughput; uint64StatsMap m_delay; + + /** + * Start time of the on going epoch + */ + Time m_startTime; + + /** + * Epoch duration + */ + Time m_epochDuration; + + bool m_firstWrite; + }; } // namespace ns3