Fixed throughput calculation

Fixed output format to be compliant with Requirements Document
This commit is contained in:
jnin
2011-04-04 18:17:17 +02:00
parent 59c4f97e80
commit cf4c8d6547
2 changed files with 133 additions and 53 deletions

View File

@@ -22,6 +22,8 @@
#include "ns3/string.h"
#include "ns3/nstime.h"
#include <ns3/log.h>
#include <vector>
#include <algorithm>
namespace ns3 {
@@ -30,7 +32,8 @@ NS_LOG_COMPONENT_DEFINE ("RlcStatsCalculator");
NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator);
RlcStatsCalculator::RlcStatsCalculator() :
m_outputFilename ("")
m_outputFilename (""),
m_firstWrite(true)
{
NS_LOG_FUNCTION (this);
@@ -53,6 +56,15 @@ RlcStatsCalculator::GetTypeId (void)
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 @@ void
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;
uint64StatsMap::iterator it = m_delay.find (pair);
if ( it == m_delay.end () )
if (Simulator::Now () > m_startTime )
{
m_delay[pair] = CreateObject <MinMaxAvgTotalCalculator<uint64_t> > ();
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<MinMaxAvgTotalCalculator<uint64_t> > ();
}
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<lteFlowId_t> 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<lteFlowId_t>::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 @@ RlcStatsCalculator::GetDelay (lteFlowId_t p)
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 @@ RlcStatsCalculator::GetThroughput (uint16_t rnti, uint8_t lcid)
return GetThroughput (p);
}
double
RlcStatsCalculator::GetPacketLossProbability (uint16_t rnti, uint8_t lcid)
{
lteFlowId_t p (rnti, lcid);
return GetPacketLossProbability (p);
}
} // namespace ns3

View File

@@ -35,6 +35,7 @@ namespace ns3 {
typedef std::map<lteFlowId_t, uint32_t> uint32Map;
typedef std::map<lteFlowId_t, uint64_t> uint64Map;
typedef std::map<lteFlowId_t, Ptr<MinMaxAvgTotalCalculator<uint64_t> > > uint64StatsMap;
typedef std::map<lteFlowId_t, double> doubleMap;
class RlcStatsCalculator : public Object
@@ -55,21 +56,42 @@ public:
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