This commit is contained in:
Nicola Baldo
2011-05-12 16:02:16 +02:00
10 changed files with 631 additions and 209 deletions

View File

@@ -48,5 +48,13 @@ Adaptive Modulation and Coding
Round Robin scheduler performance
---------------------------------
This system test program creates different test cases with a single eNB and several UEs, all having the same Radio Bearer specification. In each test case, the UEs see the same SINR from the eNB; different test cases are implemented by using different distance among UEs and the eNB (i.e., therefore having different SINR values) and different numbers of UEs. The test consists on checking that the obtained throughput performance is equal among users and matches a reference throughput value obtained according to the SINR perceived within a given tolerance.
The test vector is obtained according to the values of transport block size reported in table 7.1.7.2.1-1 of 36.213, considering an equal distribution of the physical resource block among the users. The tolerance has been introduced in order to overcome the process of initialization and quantization of the resource allocation.
Proportional Fair scheduler performance
---------------------------------------
This system test program creates different test cases with a single eNB and several UEs, all having the same Radio Bearer specification. The tests are grouped in two categories in order to evaluate both the performance in terms of adaptation to channel condition and from fairness perspective.
Regarding the former, the UEs are placed in order to have the same SINR from the eNB in each specific test. Different test cases are implemented by using different SINR values and different numbers of UEs. The test consists on checking that the obtained throughput performance is equal among users is consistent with the definition of proportional fair scheduling, which implies that the bandwidht assigned is proportional to the ratio of the estimated throughput per TTI of each user. In detail, each TTI the PFS estimates the throughput of each UE for the next TTI according to the CQIs received; the ratio of this value respect to the global of all users represent the long term trend for the bandwidht allocated by the scheduler. In this specific case, this results in allocating proportionally the maximum bandwidht achievable (i.e., all PRB allocated to a single users) among the users in a time division fashion.
The second category of tests is aimed at verify the fairness behavior in presence of UEs with different SINRs (and therefore different estimated throughput from PFS). The test consists of checking whether the throughput obtained is fairly distributed among the users, that is the ratio of the estimated throughput per TTI (function of the SINR).

View File

@@ -73,7 +73,7 @@ int main (int argc, char *argv[])
EpsBearer bearer (q);
lena->ActivateEpsBearer (ueDevs, bearer);
Simulator::Stop (Seconds (0.005));
Simulator::Stop (Seconds (35));
lena->EnableMacTraces ();
lena->EnableRlcTraces ();

View File

@@ -92,7 +92,7 @@ TypeId LenaHelper::GetTypeId (void)
.AddConstructor<LenaHelper> ()
.AddAttribute ("Scheduler",
"The type of scheduler to be used for eNBs",
StringValue ("ns3::RrFfMacScheduler"),
StringValue ("ns3::PfFfMacScheduler"),
MakeStringAccessor (&LenaHelper::SetSchedulerType),
MakeStringChecker ())
.AddAttribute ("PropagationModel",
@@ -354,7 +354,7 @@ LenaHelper::EnableLogComponents (void)
LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);

View File

@@ -27,6 +27,29 @@
namespace ns3 {
ImsiLcidPair::ImsiLcidPair ()
{
}
ImsiLcidPair::ImsiLcidPair (const uint64_t a, const uint8_t b)
: m_imsi(a),
m_lcId(b)
{
}
bool
operator == (const ImsiLcidPair &a, const ImsiLcidPair &b)
{
return ( (a.m_imsi == b.m_imsi) && (a.m_lcId == b.m_lcId) );
}
bool
operator < (const ImsiLcidPair& a, const ImsiLcidPair& b)
{
return ( (a.m_imsi < b.m_imsi) || ( (a.m_imsi == b.m_imsi) && (a.m_lcId < b.m_lcId) ) );
}
NS_LOG_COMPONENT_DEFINE ("RlcStatsCalculator");
NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator);
@@ -91,11 +114,12 @@ void
RlcStatsCalculator::UlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
{
NS_LOG_FUNCTION (this << "UlTxPDU" << imsi << rnti << (uint32_t) lcid << packetSize);
ImsiLcidPair p (imsi, lcid);
if (Simulator::Now () > m_startTime )
{
m_flowId[imsi] = LteFlowId_t (rnti, lcid);
m_ulTxPackets[imsi]++;
m_ulTxData[imsi] += packetSize;
m_flowId[p] = LteFlowId_t (rnti, lcid);
m_ulTxPackets[p]++;
m_ulTxData[p] += packetSize;
}
CheckEpoch ();
}
@@ -104,11 +128,12 @@ void
RlcStatsCalculator::DlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
{
NS_LOG_FUNCTION (this << "DlTxPDU" << imsi << rnti << (uint32_t) lcid << packetSize);
ImsiLcidPair p (imsi, lcid);
if (Simulator::Now () > m_startTime )
{
m_flowId[imsi] = LteFlowId_t (rnti, lcid);
m_dlTxPackets[imsi]++;
m_dlTxData[imsi] += packetSize;
m_flowId[p] = LteFlowId_t (rnti, lcid);
m_dlTxPackets[p]++;
m_dlTxData[p] += packetSize;
}
CheckEpoch ();
}
@@ -117,20 +142,23 @@ void
RlcStatsCalculator::UlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_FUNCTION (this << "UlRxPDU" << imsi << rnti << (uint32_t) lcid << packetSize << delay);
ImsiLcidPair p (imsi, lcid);
if (Simulator::Now () > m_startTime )
{
m_ulRxPackets[imsi]++;
m_ulRxData[imsi] += packetSize;
m_ulRxPackets[p]++;
m_ulRxData[p] += packetSize;
uint64StatsMap::iterator it = m_ulDelay.find(imsi);
Uint64StatsMap::iterator it = m_ulDelay.find(p);
if (it == m_ulDelay.end())
{
m_ulDelay[imsi] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
m_ulPduSize[imsi] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
NS_LOG_DEBUG (this << " Creating UL stats calculators for IMSI " << p.m_imsi << " and LCI " << (uint32_t) p.m_lcId );
m_ulDelay[p] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
m_ulPduSize[p] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
}
m_ulDelay[imsi]->Update (delay);
m_ulPduSize[imsi]->Update (packetSize);
m_ulDelay[p]->Update (delay);
m_ulPduSize[p]->Update (packetSize);
}
CheckEpoch ();
}
@@ -138,19 +166,21 @@ void
RlcStatsCalculator::DlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_FUNCTION (this << "DlRxPDU" << imsi << rnti << (uint32_t) lcid << packetSize << delay);
ImsiLcidPair p (imsi, lcid);
if (Simulator::Now () > m_startTime )
{
m_dlRxPackets[imsi]++;
m_dlRxData[imsi] += packetSize;
m_dlRxPackets[p]++;
m_dlRxData[p] += packetSize;
uint64StatsMap::iterator it = m_dlDelay.find(imsi);
Uint64StatsMap::iterator it = m_dlDelay.find(p);
if (it == m_dlDelay.end())
{
m_dlDelay[imsi] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
m_dlPduSize[imsi] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
NS_LOG_DEBUG (this << " Creating DL stats calculators for IMSI " << p.m_imsi << " and LCI " << (uint32_t) p.m_lcId );
m_dlDelay[p] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
m_dlPduSize[p] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
}
m_dlDelay[imsi]->Update(delay);
m_dlPduSize[imsi]->Update (packetSize);
m_dlDelay[p]->Update(delay);
m_dlPduSize[p]->Update (packetSize);
}
CheckEpoch ();
}
@@ -182,11 +212,11 @@ RlcStatsCalculator::ShowResults (void)
return;
}
m_firstWrite = false;
ulOutFile << "# start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
ulOutFile << "% start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
ulOutFile << "delay\tstdDev\tmin\tmax\t";
ulOutFile << "PduSize\tstdDev\tmin\tmax";
ulOutFile << std::endl;
dlOutFile << "# start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
dlOutFile << "% start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
dlOutFile << "delay\tstdDev\tmin\tmax\t";
dlOutFile << "PduSize\tstdDev\tmin\tmax";
dlOutFile << std::endl;
@@ -216,34 +246,36 @@ RlcStatsCalculator::ShowResults (void)
void
RlcStatsCalculator::WriteUlResults (std::ofstream& outFile)
{
// Get the unique IMSI list
std::vector<uint64_t> imsiVector;
for (uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it)
// Get the unique IMSI / LCID list
std::vector<ImsiLcidPair > pairVector;
for (Uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it)
{
if (find (imsiVector.begin (), imsiVector.end (), (*it).first ) == imsiVector.end () )
if (find (pairVector.begin (), pairVector.end (), (*it).first ) == pairVector.end () )
{
imsiVector.push_back ((*it).first);
pairVector.push_back ((*it).first);
}
}
Time endTime = m_startTime + m_epochDuration;
for (std::vector<uint64_t>::iterator imsi = imsiVector.begin(); imsi != imsiVector.end(); ++imsi)
for (std::vector<ImsiLcidPair>::iterator it = pairVector.begin(); it != pairVector.end(); ++it)
{
ImsiLcidPair p = *it;
outFile << m_startTime.GetNanoSeconds () / 1.0e9 << "\t";
outFile << endTime.GetNanoSeconds() / 1.0e9 << "\t";
outFile << (*imsi) << "\t";
outFile << m_flowId[*imsi].m_rnti << "\t";
outFile << (uint32_t) m_flowId[*imsi].m_lcId << "\t";
outFile << GetUlTxPackets (*imsi) << "\t";
outFile << GetUlTxData (*imsi) << "\t";
outFile << GetUlRxPackets (*imsi) << "\t";
outFile << GetUlRxData (*imsi) << "\t";
std::vector<double> stats = GetUlDelayStats (*imsi);
outFile << p.m_imsi << "\t";
outFile << m_flowId[p].m_rnti << "\t";
outFile << (uint32_t) m_flowId[p].m_lcId << "\t";
outFile << GetUlTxPackets (p.m_imsi, p.m_lcId) << "\t";
outFile << GetUlTxData (p.m_imsi, p.m_lcId) << "\t";
outFile << GetUlRxPackets (p.m_imsi, p.m_lcId) << "\t";
outFile << GetUlRxData (p.m_imsi, p.m_lcId) << "\t";
std::vector<double> stats = GetUlDelayStats (p.m_imsi, p.m_lcId);
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
{
outFile << (*it) * 1e-9 << "\t";
}
stats = GetUlPduSizeStats (*imsi);
stats = GetUlPduSizeStats (p.m_imsi, p.m_lcId);
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
{
outFile << (*it) << "\t";
@@ -258,33 +290,34 @@ void
RlcStatsCalculator::WriteDlResults (std::ofstream& outFile)
{
// Get the unique IMSI list
std::vector<uint64_t> imsiVector;
for (uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it)
std::vector<ImsiLcidPair > pairVector;
for (Uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it)
{
if (find (imsiVector.begin (), imsiVector.end (), (*it).first ) == imsiVector.end () )
if (find (pairVector.begin (), pairVector.end (), (*it).first ) == pairVector.end () )
{
imsiVector.push_back ((*it).first);
pairVector.push_back ((*it).first);
}
}
Time endTime = m_startTime + m_epochDuration;
for (std::vector<uint64_t>::iterator imsi = imsiVector.begin(); imsi != imsiVector.end(); ++imsi)
for (std::vector<ImsiLcidPair>::iterator pair = pairVector.begin(); pair != pairVector.end(); ++pair)
{
ImsiLcidPair p = *pair;
outFile << m_startTime.GetNanoSeconds () / 1.0e9 << "\t";
outFile << endTime.GetNanoSeconds() / 1.0e9 << "\t";
outFile << (*imsi) << "\t";
outFile << m_flowId[*imsi].m_rnti << "\t";
outFile << (uint32_t) m_flowId[*imsi].m_lcId << "\t";
outFile << GetDlTxPackets (*imsi) << "\t";
outFile << GetDlTxData (*imsi) << "\t";
outFile << GetDlRxPackets (*imsi) << "\t";
outFile << GetDlRxData (*imsi) << "\t";
std::vector<double> stats = GetDlDelayStats (*imsi);
outFile << p.m_imsi << "\t";
outFile << m_flowId[p].m_rnti << "\t";
outFile << (uint32_t) m_flowId[p].m_lcId << "\t";
outFile << GetDlTxPackets (p.m_imsi, p.m_lcId) << "\t";
outFile << GetDlTxData (p.m_imsi, p.m_lcId) << "\t";
outFile << GetDlRxPackets (p.m_imsi, p.m_lcId) << "\t";
outFile << GetDlRxData (p.m_imsi, p.m_lcId) << "\t";
std::vector<double> stats = GetDlDelayStats (p.m_imsi, p.m_lcId);
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
{
outFile << (*it) * 1e-9 << "\t";
}
stats = GetDlPduSizeStats (*imsi);
stats = GetDlPduSizeStats (p.m_imsi, p.m_lcId);
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
{
outFile << (*it) << "\t";
@@ -332,119 +365,132 @@ RlcStatsCalculator::StartEpoch (void)
}
uint32_t
RlcStatsCalculator::GetUlTxPackets (uint64_t imsi)
RlcStatsCalculator::GetUlTxPackets (uint64_t imsi, uint8_t lcid)
{
return m_ulTxPackets[imsi];
ImsiLcidPair p (imsi, lcid);
return m_ulTxPackets[p];
}
uint32_t
RlcStatsCalculator::GetUlRxPackets (uint64_t imsi)
RlcStatsCalculator::GetUlRxPackets (uint64_t imsi, uint8_t lcid)
{
return m_ulRxPackets[imsi];
ImsiLcidPair p (imsi, lcid);
return m_ulRxPackets[p];
}
uint64_t
RlcStatsCalculator::GetUlTxData (uint64_t imsi)
RlcStatsCalculator::GetUlTxData (uint64_t imsi, uint8_t lcid)
{
return m_ulTxData[imsi];
ImsiLcidPair p (imsi, lcid);
return m_ulTxData[p];
}
uint64_t
RlcStatsCalculator::GetUlRxData (uint64_t imsi)
RlcStatsCalculator::GetUlRxData (uint64_t imsi, uint8_t lcid)
{
return m_ulRxData[imsi];
ImsiLcidPair p (imsi, lcid);
return m_ulRxData[p];
}
double
RlcStatsCalculator::GetUlDelay (uint64_t imsi)
RlcStatsCalculator::GetUlDelay (uint64_t imsi, uint8_t lcid)
{
uint64StatsMap::iterator it = m_ulDelay.find (imsi);
ImsiLcidPair p (imsi, lcid);
Uint64StatsMap::iterator it = m_ulDelay.find (p);
if ( it == m_ulDelay.end () )
{
NS_LOG_ERROR("UL delay for " << imsi << " not found");
NS_LOG_ERROR("UL delay for " << imsi << " - " << lcid << " not found");
return 0;
}
return m_ulDelay[imsi]->getMean ();
return m_ulDelay[p]->getMean ();
}
std::vector<double>
RlcStatsCalculator::GetUlDelayStats (uint64_t imsi)
RlcStatsCalculator::GetUlDelayStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
std::vector<double> stats;
uint64StatsMap::iterator it = m_ulDelay.find (imsi);
Uint64StatsMap::iterator it = m_ulDelay.find (p);
if ( it == m_ulDelay.end () )
{
NS_LOG_ERROR("UL delay for " << imsi << " not found");
NS_LOG_ERROR("UL delay for " << imsi << " - " << lcid << " not found");
return stats;
}
stats.push_back(m_ulDelay[imsi]->getMean ());
stats.push_back(m_ulDelay[imsi]->getStddev ());
stats.push_back(m_ulDelay[imsi]->getMin ());
stats.push_back(m_ulDelay[imsi]->getMax ());
stats.push_back(m_ulDelay[p]->getMean ());
stats.push_back(m_ulDelay[p]->getStddev ());
stats.push_back(m_ulDelay[p]->getMin ());
stats.push_back(m_ulDelay[p]->getMax ());
return stats;
}
std::vector<double>
RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi)
RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
std::vector<double> stats;
uint32StatsMap::iterator it = m_ulPduSize.find (imsi);
Uint32StatsMap::iterator it = m_ulPduSize.find (p);
if ( it == m_ulPduSize.end () )
{
NS_LOG_ERROR("UL PDU Size for " << imsi << " not found");
NS_LOG_ERROR("UL PDU Size for " << imsi << " - " << lcid << " not found");
return stats;
}
stats.push_back (m_ulPduSize[imsi]->getMean ());
stats.push_back (m_ulPduSize[imsi]->getStddev ());
stats.push_back (m_ulPduSize[imsi]->getMin ());
stats.push_back (m_ulPduSize[imsi]->getMax ());
stats.push_back (m_ulPduSize[p]->getMean ());
stats.push_back (m_ulPduSize[p]->getStddev ());
stats.push_back (m_ulPduSize[p]->getMin ());
stats.push_back (m_ulPduSize[p]->getMax ());
return stats;
}
uint32_t
RlcStatsCalculator::GetDlTxPackets (uint64_t imsi)
RlcStatsCalculator::GetDlTxPackets (uint64_t imsi, uint8_t lcid)
{
return m_dlTxPackets[imsi];
ImsiLcidPair p (imsi, lcid);
return m_dlTxPackets[p];
}
uint32_t
RlcStatsCalculator::GetDlRxPackets (uint64_t imsi)
RlcStatsCalculator::GetDlRxPackets (uint64_t imsi, uint8_t lcid)
{
return m_dlRxPackets[imsi];
ImsiLcidPair p (imsi, lcid);
return m_dlRxPackets[p];
}
uint64_t
RlcStatsCalculator::GetDlTxData (uint64_t imsi)
RlcStatsCalculator::GetDlTxData (uint64_t imsi, uint8_t lcid)
{
return m_dlTxData[imsi];
ImsiLcidPair p (imsi, lcid);
return m_dlTxData[p];
}
uint64_t
RlcStatsCalculator::GetDlRxData (uint64_t imsi)
RlcStatsCalculator::GetDlRxData (uint64_t imsi, uint8_t lcid)
{
return m_dlRxData[imsi];
ImsiLcidPair p (imsi, lcid);
return m_dlRxData[p];
}
double
RlcStatsCalculator::GetDlDelay (uint64_t imsi)
RlcStatsCalculator::GetDlDelay (uint64_t imsi, uint8_t lcid)
{
uint64StatsMap::iterator it = m_dlDelay.find (imsi);
ImsiLcidPair p (imsi, lcid);
Uint64StatsMap::iterator it = m_dlDelay.find (p);
if ( it == m_dlDelay.end () )
{
NS_LOG_ERROR("DL delay for " << imsi << " not found");
return 0;
}
return m_dlDelay[imsi]->getMean ();
return m_dlDelay[p]->getMean ();
}
std::vector<double>
RlcStatsCalculator::GetDlDelayStats (uint64_t imsi)
RlcStatsCalculator::GetDlDelayStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
std::vector<double> stats;
uint64StatsMap::iterator it = m_dlDelay.find (imsi);
Uint64StatsMap::iterator it = m_dlDelay.find (p);
if ( it == m_dlDelay.end () )
{
@@ -452,18 +498,19 @@ RlcStatsCalculator::GetDlDelayStats (uint64_t imsi)
return stats;
}
stats.push_back(m_dlDelay[imsi]->getMean ());
stats.push_back(m_dlDelay[imsi]->getStddev ());
stats.push_back(m_dlDelay[imsi]->getMin ());
stats.push_back(m_dlDelay[imsi]->getMax ());
stats.push_back(m_dlDelay[p]->getMean ());
stats.push_back(m_dlDelay[p]->getStddev ());
stats.push_back(m_dlDelay[p]->getMin ());
stats.push_back(m_dlDelay[p]->getMax ());
return stats;
}
std::vector<double>
RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi)
RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi, uint8_t lcid)
{
ImsiLcidPair p (imsi, lcid);
std::vector<double> stats;
uint32StatsMap::iterator it = m_dlPduSize.find (imsi);
Uint32StatsMap::iterator it = m_dlPduSize.find (p);
if ( it == m_dlPduSize.end () )
{
@@ -471,10 +518,10 @@ RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi)
return stats;
}
stats.push_back(m_dlPduSize[imsi]->getMean ());
stats.push_back(m_dlPduSize[imsi]->getStddev ());
stats.push_back(m_dlPduSize[imsi]->getMin ());
stats.push_back(m_dlPduSize[imsi]->getMax ());
stats.push_back(m_dlPduSize[p]->getMean ());
stats.push_back(m_dlPduSize[p]->getStddev ());
stats.push_back(m_dlPduSize[p]->getMin ());
stats.push_back(m_dlPduSize[p]->getMax ());
return stats;
}

View File

@@ -32,47 +32,219 @@
namespace ns3 {
typedef std::map<uint64_t, uint32_t> uint32Map;
typedef std::map<uint64_t, uint64_t> uint64Map;
typedef std::map<uint64_t, Ptr<MinMaxAvgTotalCalculator<uint32_t> > > uint32StatsMap;
typedef std::map<uint64_t, Ptr<MinMaxAvgTotalCalculator<uint64_t> > > uint64StatsMap;
typedef std::map<uint64_t, double> doubleMap;
typedef std::map<uint64_t, LteFlowId_t> flowIdMap;
struct ImsiLcidPair
{
uint64_t m_imsi;
uint8_t m_lcId;
public:
ImsiLcidPair ();
ImsiLcidPair (const uint64_t a, const uint8_t b);
friend bool operator == (const ImsiLcidPair &a, const ImsiLcidPair &b);
friend bool operator < (const ImsiLcidPair &a, const ImsiLcidPair &b);
};
typedef std::map<ImsiLcidPair, uint32_t> Uint32Map;
typedef std::map<ImsiLcidPair, uint64_t> Uint64Map;
typedef std::map<ImsiLcidPair, Ptr<MinMaxAvgTotalCalculator<uint32_t> > > Uint32StatsMap;
typedef std::map<ImsiLcidPair, Ptr<MinMaxAvgTotalCalculator<uint64_t> > > Uint64StatsMap;
typedef std::map<ImsiLcidPair, double> DoubleMap;
typedef std::map<ImsiLcidPair, LteFlowId_t> FlowIdMap;
/**
* Calculation of statistics from the RLC layer for uplink and downlink, the data is dumped into a file periodically. Metrics considered are:
* - Number of transmitted PDUs
* - Number of received PDUs
* - Number of transmitted bytes
* - Number of received bytes
* - Average, min, max and standard deviation of RLC to RLC delay
* - Average, min, max and standard deviation of RLC PDU size
*/
class RlcStatsCalculator : public Object
{
public:
RlcStatsCalculator();
virtual
~RlcStatsCalculator();
/**
* Class constructor
*/
RlcStatsCalculator ();
/**
* Class destructor
*/
virtual ~RlcStatsCalculator ();
/**
* Inherited from ns3::Object
*/
static TypeId GetTypeId (void);
/**
* Set the name of the file where the uplink statistics will be stored.
*
* \param outputFilename string with the name of the file
*/
void SetUlOutputFilename (std::string outputFilename);
/**
* Set the name of the file where the downlink statistics will be stored.
*
* \param outputFilename string with the name of the file
*/
void SetDlOutputFilename (std::string outputFilename);
/**
* Notifies the stats calculator that an uplink transmission has occurred.
* @param imsi IMSI of the UE who transmitted the PDU
* @param rnti C-RNTI of the UE who transmitted the PDU
* @param lcid LCID through which the PDU has been transmitted
* @param packetSize size of the PDU in bytes
*/
void UlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize);
/**
* Notifies the stats calculator that an uplink reception has occurred.
* @param imsi IMSI of the UE who received the PDU
* @param rnti C-RNTI of the UE who received the PDU
* @param lcid LCID through which the PDU has been received
* @param packetSize size of the PDU in bytes
* @param delay RLC to RLC delay in nanoseconds
*/
void UlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay);
/**
* Notifies the stats calculator that an downlink transmission has occurred.
* @param imsi IMSI of the UE who is receiving the PDU
* @param rnti C-RNTI of the UE who is receiving the PDU
* @param lcid LCID through which the PDU has been transmitted
* @param packetSize size of the PDU in bytes
*/
void DlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize);
/**
* Notifies the stats calculator that an downlink reception has occurred.
* @param imsi IMSI of the UE who received the PDU
* @param rnti C-RNTI of the UE who received the PDU
* @param lcid LCID through which the PDU has been transmitted
* @param packetSize size of the PDU in bytes
* @param delay RLC to RLC delay in nanoseconds
*/
void DlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay);
uint32_t GetUlTxPackets (uint64_t imsi);
uint32_t GetUlRxPackets (uint64_t imsi);
uint64_t GetUlTxData (uint64_t imsi);
uint64_t GetUlRxData (uint64_t imsi);
double GetUlDelay (uint64_t imsi);
std::vector<double> GetUlDelayStats (uint64_t imsi);
std::vector<double> GetUlPduSizeStats (uint64_t imsi);
/**
* Gets the number of transmitted uplink packets.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of transmitted uplink packets
*/
uint32_t GetUlTxPackets (uint64_t imsi, uint8_t lcid);
/**
* Gets the number of received uplink packets.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of received uplink packets
*/
uint32_t GetUlRxPackets (uint64_t imsi, uint8_t lcid);
uint32_t GetDlTxPackets (uint64_t imsi);
uint32_t GetDlRxPackets (uint64_t imsi);
uint64_t GetDlTxData (uint64_t imsi);
uint64_t GetDlRxData (uint64_t imsi);
double GetDlDelay (uint64_t imsi);
std::vector<double> GetDlDelayStats (uint64_t imsi);
std::vector<double> GetDlPduSizeStats (uint64_t imsi);
/**
* Gets the number of transmitted uplink data bytes.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of transmitted data bytes
*/
uint64_t GetUlTxData (uint64_t imsi, uint8_t lcid);
/**
* Gets the number of received uplink data bytes.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of received data bytes
*/
uint64_t GetUlRxData (uint64_t imsi, uint8_t lcid);
/**
* Gets the uplink RLC to RLC delay
* @param imsi IMSI of the UE
* @param lcid LCID
* @return RLC to RLC delay in seconds
*/
double GetUlDelay (uint64_t imsi, uint8_t lcid);
/**
* Gets the uplink RLC to RLC statistics: average, min, max and standard deviation.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return RLC to RLC delay statistics average, min, max and standard deviation in seconds
*/
std::vector<double> GetUlDelayStats (uint64_t imsi, uint8_t lcid);
/**
* Gets the uplink PDU size statistics: average, min, max and standard deviation.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return PDU size statistics average, min, max and standard deviation in seconds
*/
std::vector<double> GetUlPduSizeStats (uint64_t imsi, uint8_t lcid);
/**
* Gets the number of transmitted downlink data bytes.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of transmitted data bytes
*/
uint32_t GetDlTxPackets (uint64_t imsi, uint8_t lcid);
/**
* Gets the number of received downlink data bytes.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of received data bytes
*/
uint32_t GetDlRxPackets (uint64_t imsi, uint8_t lcid);
/**
* Gets the number of transmitted downlink data bytes.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of transmitted data bytes
*/
uint64_t GetDlTxData (uint64_t imsi, uint8_t lcid);
/**
* Gets the number of received downlink data bytes.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return number of received data bytes
*/
uint64_t GetDlRxData (uint64_t imsi, uint8_t lcid);
/**
* Gets the downlink RLC to RLC delay
* @param imsi IMSI of the UE
* @param lcid LCID
* @return RLC to RLC delay in seconds
*/
double GetDlDelay (uint64_t imsi, uint8_t lcid);
/**
* Gets the downlink RLC to RLC statistics: average, min, max and standard deviation.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return RLC to RLC delay statistics average, min, max and standard deviation in seconds
*/
std::vector<double> GetDlDelayStats (uint64_t imsi, uint8_t lcid);
/**
* Gets the downlink PDU size statistics: average, min, max and standard deviation.
* @param imsi IMSI of the UE
* @param lcid LCID
* @return PDU size statistics average, min, max and standard deviation in seconds
*/
std::vector<double> GetDlPduSizeStats (uint64_t imsi, uint8_t lcid);
private:
void ShowResults (void);
@@ -83,23 +255,23 @@ private:
void StartEpoch (void);
void CheckEpoch (void);
flowIdMap m_flowId;
FlowIdMap m_flowId;
std::string m_dlOutputFilename;
uint32Map m_dlTxPackets;
uint32Map m_dlRxPackets;
uint64Map m_dlTxData;
uint64Map m_dlRxData;
uint64StatsMap m_dlDelay;
uint32StatsMap m_dlPduSize;
Uint32Map m_dlTxPackets;
Uint32Map m_dlRxPackets;
Uint64Map m_dlTxData;
Uint64Map m_dlRxData;
Uint64StatsMap m_dlDelay;
Uint32StatsMap m_dlPduSize;
std::string m_ulOutputFilename;
uint32Map m_ulTxPackets;
uint32Map m_ulRxPackets;
uint64Map m_ulTxData;
uint64Map m_ulRxData;
uint64StatsMap m_ulDelay;
uint32StatsMap m_ulPduSize;
Uint32Map m_ulTxPackets;
Uint32Map m_ulRxPackets;
Uint64Map m_ulTxData;
Uint64Map m_ulRxData;
Uint64StatsMap m_ulDelay;
Uint32StatsMap m_ulPduSize;
/**
* Start time of the on going epoch

View File

@@ -191,6 +191,17 @@ LteUeRrc::GetRnti ()
return m_rnti;
}
std::vector<uint8_t>
LteUeRrc::GetLcIdVector ()
{
std::vector<uint8_t> v;
for (std::map<uint8_t, Ptr<LteRlc> >::iterator it = m_rlcMap.begin(); it != m_rlcMap.end(); ++it)
{
v.push_back(it->first);
}
return v;
}
} // namespace ns3

View File

@@ -122,6 +122,12 @@ public:
*/
uint16_t GetRnti ();
/**
*
* @return a vector with the allocated LCID
*/
std::vector<uint8_t> GetLcIdVector ();
private:
// forwarded from CMAC SAP user
void DoLcConfigCompleted ();

View File

@@ -35,6 +35,7 @@
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lena-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
@@ -48,68 +49,74 @@ LenaTestPfFfMacSchedulerSuite::LenaTestPfFfMacSchedulerSuite ()
: TestSuite ("lte-test-pf-ff-mac-scheduler", SYSTEM)
{
SetVerbose (true);
NS_LOG_INFO ("creating LenaPfFfMacSchedulerTestCase");
NS_LOG_INFO ("creating LenaTestPfFfMacSchedulerSuite");
std::vector<uint16_t> dist;
dist.push_back (0); // User 0 distance
std::vector<uint16_t> estThrPf;
estThrPf.push_back (0); // User 0 estimated TTI throughput from PF
AddTestCase (new LenaPfFfMacSchedulerTestCase2 (1,dist,estThrPf));
// DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec
// 3 users -> 2196000 among 3 users -> 732000 bytes/sec
// 6 users -> 2196000 among 6 users -> 366000 bytes/sec
// 12 users -> 2196000 among 12 users -> 183000 bytes/sec
// 15 users -> 2196000 among 15 users -> 146400 bytes/sec
AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,0,2196000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,0,732000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,0,366000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,0,183000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,0,146400));
// DISTANCE 6000 -> MCS 24 -> Itbs 22 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 22 -> 1572 -> 1572000 bytes/sec
// 3 users -> 1572000 among 3 users -> 524000 bytes/sec
// 6 users -> 1572000 among 6 users -> 262000 bytes/sec
// 12 users -> 1572000 among 12 users -> 131000 bytes/sec
// 15 users -> 1572000 among 15 users -> 104800 bytes/sec
AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,6000,1572000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,6000,524000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,6000,262000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,6000,131000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,6000,104800));
// DISTANCE 9000 -> MCS 10 -> Itbs 9 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 9 -> 469 -> 469000 bytes/sec
// 3 users -> 469000 among 3 users -> 156333 bytes/sec
// 6 users -> 469000 among 6 users -> 78166 bytes/sec
// 12 users -> 469000 among 12 users -> 39083 bytes/sec
// 15 users -> 469000 among 15 users -> 31266 bytes/sec
AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,9000,469000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,9000,156333));
AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,9000,78166));
AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,9000,39083));
AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,9000,31266));
// DISTANCE 15000 -> MCS 4 -> Itbs 4 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 4 -> 217 -> 217000 bytes/sec
// 3 users -> 217000 among 3 users -> 72333 bytes/sec
// 6 users -> 217000 among 6 users -> 36166 bytes/sec
// 12 users -> 217000 among 12 users -> 18083 bytes/sec
// 15 users -> 217000 among 15 users -> 14466 bytes/sec
AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,15000,217000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,15000,72333));
AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,15000,36166));
AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,15000,18083));
AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,15000,14466));
// DISTANCE 20000 -> MCS 2 -> Itbs 2 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 2 -> 133 -> 133000 bytes/sec
// 3 users -> 217000 among 3 users -> 44333 bytes/sec
// 6 users -> 217000 among 6 users -> 22166 bytes/sec
// 12 users -> 217000 among 12 users -> 11083 bytes/sec
// 15 users -> 217000 among 15 users -> 8866 bytes/sec
AddTestCase (new LenaPfFfMacSchedulerTestCase (1,0,20000,133000));
AddTestCase (new LenaPfFfMacSchedulerTestCase (3,0,20000,44333));
AddTestCase (new LenaPfFfMacSchedulerTestCase (6,0,20000,22166));
AddTestCase (new LenaPfFfMacSchedulerTestCase (12,0,20000,11083));
AddTestCase (new LenaPfFfMacSchedulerTestCase (15,0,20000,8866));
// // DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// // 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec
// // 3 users -> 2196000 among 3 users -> 732000 bytes/sec
// // 6 users -> 2196000 among 6 users -> 366000 bytes/sec
// // 12 users -> 2196000 among 12 users -> 183000 bytes/sec
// // 15 users -> 2196000 among 15 users -> 146400 bytes/sec
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,0,2196000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,0,732000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,0,366000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,0,183000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,0,146400));
//
// // DISTANCE 6000 -> MCS 24 -> Itbs 22 (from table 7.1.7.2.1-1 of 36.213)
// // 1 user -> 24 PRB at Itbs 22 -> 1572 -> 1572000 bytes/sec
// // 3 users -> 1572000 among 3 users -> 524000 bytes/sec
// // 6 users -> 1572000 among 6 users -> 262000 bytes/sec
// // 12 users -> 1572000 among 12 users -> 131000 bytes/sec
// // 15 users -> 1572000 among 15 users -> 104800 bytes/sec
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,6000,1572000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,6000,524000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,6000,262000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,6000,131000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,6000,104800));
//
// // DISTANCE 9000 -> MCS 10 -> Itbs 9 (from table 7.1.7.2.1-1 of 36.213)
// // 1 user -> 24 PRB at Itbs 9 -> 469 -> 469000 bytes/sec
// // 3 users -> 469000 among 3 users -> 156333 bytes/sec
// // 6 users -> 469000 among 6 users -> 78166 bytes/sec
// // 12 users -> 469000 among 12 users -> 39083 bytes/sec
// // 15 users -> 469000 among 15 users -> 31266 bytes/sec
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,9000,469000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,9000,156333));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,9000,78166));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,9000,39083));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,9000,31266));
//
// // DISTANCE 15000 -> MCS 4 -> Itbs 4 (from table 7.1.7.2.1-1 of 36.213)
// // 1 user -> 24 PRB at Itbs 4 -> 217 -> 217000 bytes/sec
// // 3 users -> 217000 among 3 users -> 72333 bytes/sec
// // 6 users -> 217000 among 6 users -> 36166 bytes/sec
// // 12 users -> 217000 among 12 users -> 18083 bytes/sec
// // 15 users -> 217000 among 15 users -> 14466 bytes/sec
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,15000,217000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,15000,72333));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,15000,36166));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,15000,18083));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,15000,14466));
//
// // DISTANCE 20000 -> MCS 2 -> Itbs 2 (from table 7.1.7.2.1-1 of 36.213)
// // 1 user -> 24 PRB at Itbs 2 -> 133 -> 133000 bytes/sec
// // 3 users -> 217000 among 3 users -> 44333 bytes/sec
// // 6 users -> 217000 among 6 users -> 22166 bytes/sec
// // 12 users -> 217000 among 12 users -> 11083 bytes/sec
// // 15 users -> 217000 among 15 users -> 8866 bytes/sec
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,20000,133000));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,20000,44333));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,20000,22166));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,20000,11083));
// AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,20000,8866));
@@ -118,21 +125,28 @@ LenaTestPfFfMacSchedulerSuite::LenaTestPfFfMacSchedulerSuite ()
static LenaTestPfFfMacSchedulerSuite lenaTestPfFfMacSchedulerSuite;
LenaPfFfMacSchedulerTestCase::LenaPfFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRef)
// --------------- T E S T - C A S E # 1 ------------------------------
LenaPfFfMacSchedulerTestCase1::LenaPfFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRef)
: TestCase ("Proportional Fair (PF) Mac Scheduler Test Case"),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_thrRef (thrRef)
{
// 0 mt -> mcs 28
// 6000 mt -> mcs 24
// 12000 mt -> mcs 6
}
LenaPfFfMacSchedulerTestCase::~LenaPfFfMacSchedulerTestCase ()
LenaPfFfMacSchedulerTestCase1::~LenaPfFfMacSchedulerTestCase1 ()
{
}
void
LenaPfFfMacSchedulerTestCase::DoRun (void)
LenaPfFfMacSchedulerTestCase1::DoRun (void)
{
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
@@ -159,7 +173,7 @@ LenaPfFfMacSchedulerTestCase::DoRun (void)
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestPfFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL);
@@ -226,10 +240,17 @@ LenaPfFfMacSchedulerTestCase::DoRun (void)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)-> GetObject<LteUeNetDevice> ()->GetImsi ();
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi));
// get the lcId
uint8_t lcId = ueDevs.Get (i)-> GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at(0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRef);
}
/**
* Check that the assignation is done in a "proportional fair" manner among users
* with equal SINRs: the bandwidht should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*/
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRef, m_thrRef * tolerance, " Unfair Throughput!");
@@ -240,3 +261,142 @@ LenaPfFfMacSchedulerTestCase::DoRun (void)
}
// --------------- T E S T - C A S E # 2 ------------------------------
LenaPfFfMacSchedulerTestCase2::LenaPfFfMacSchedulerTestCase2 (uint16_t nUser, std::vector<uint16_t> dist, std::vector<uint16_t> estThrPf)
: TestCase ("Proportional Fair (PF) Mac Scheduler Test Case"),
m_nUser (nUser),
m_dist (dist),
m_estThrPf (estThrPf)
{
}
LenaPfFfMacSchedulerTestCase2::~LenaPfFfMacSchedulerTestCase2 ()
{
}
void
LenaPfFfMacSchedulerTestCase2::DoRun (void)
{
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestPfFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
SetVerbose (true);
Ptr<LenaHelper> lena = CreateObject<LenaHelper> ();
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lena->SetSchedulerType ("ns3::PfFfMacScheduler");
enbDevs = lena->InstallEnbDevice (enbNodes);
ueDevs = lena->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lena->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lena->ActivateEpsBearer (ueDevs, bearer);
// position nodes
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
}
lena->EnableDlRlcTraces();
double simulationTime = 2.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RlcStatsCalculator> rlcStats = lena->GetRlcStats ();
rlcStats->SetAttribute("EpochDuration", TimeValue(Seconds(simulationTime)));
Simulator::Run ();
NS_LOG_INFO("Test with " << m_nUser << " user(s)");
std::vector <uint64_t> dlDataRxed;
double totalData = 0;
double totalEstThrPf = 0;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)-> GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)-> GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at(0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
totalData += (double)dlDataRxed.at (i);
NS_LOG_INFO ("\tUser " << i << "dist" << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_nUser);
totalEstThrPf += m_estThrPf.at (i);
}
/**
* Check that the assignation is done in a "proportional fair" manner among users
* with different SINRs: the bandwidht should be distributed according to the
* ratio of the estimated throughput per TTI of each user.
*/
for (int i = 0; i < m_nUser; i++)
{
double thrRatio = (double)dlDataRxed.at (i) / totalData;
double estThrRatio = (double)m_estThrPf.at (i) / totalEstThrPf;
NS_TEST_ASSERT_MSG_EQ_TOL (estThrRatio, thrRatio, tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}

View File

@@ -37,11 +37,11 @@ using namespace ns3;
* is equal among users is consistent with the definition of proportional
* fair scheduling
*/
class LenaPfFfMacSchedulerTestCase : public TestCase
class LenaPfFfMacSchedulerTestCase1 : public TestCase
{
public:
LenaPfFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRef);
virtual ~LenaPfFfMacSchedulerTestCase ();
LenaPfFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRef);
virtual ~LenaPfFfMacSchedulerTestCase1 ();
private:
virtual void DoRun (void);
@@ -52,6 +52,21 @@ class LenaPfFfMacSchedulerTestCase : public TestCase
};
class LenaPfFfMacSchedulerTestCase2 : public TestCase
{
public:
LenaPfFfMacSchedulerTestCase2 (uint16_t nUser, std::vector<uint16_t> dist, std::vector<uint16_t> estThrPf);
virtual ~LenaPfFfMacSchedulerTestCase2 ();
private:
virtual void DoRun (void);
uint16_t m_nUser;
std::vector<uint16_t> m_dist;
std::vector<uint16_t> m_estThrPf;
};
class LenaTestPfFfMacSchedulerSuite : public TestSuite
{

View File

@@ -35,6 +35,7 @@
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lena-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
@@ -235,7 +236,9 @@ LenaRrFfMacSchedulerTestCase::DoRun (void)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)-> GetObject<LteUeNetDevice> ()->GetImsi ();
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi));
// get the lcId
uint8_t lcId = ueDevs.Get (i)-> GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector().at(0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRef);
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRef, m_thrRef * tolerance, " Unfair Throughput!");
}