Fixed Bug 802 and Bug 919
This commit is contained in:
@@ -44,54 +44,10 @@ NS_LOG_COMPONENT_DEFINE ("MinstrelWifiManager");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* A struct to contain all information related to a data rate
|
||||
*/
|
||||
struct RateInfo
|
||||
{
|
||||
/**
|
||||
* Perfect transmission time calculation, or frame calculation
|
||||
* Given a bit rate and a packet length n bytes
|
||||
*/
|
||||
Time perfectTxTime;
|
||||
|
||||
|
||||
uint32_t retryCount; ///< retry limit
|
||||
uint32_t adjustedRetryCount; ///< adjust the retry limit for this rate
|
||||
uint32_t numRateAttempt; ///< how many number of attempts so far
|
||||
uint32_t numRateSuccess; ///< number of successful pkts
|
||||
uint32_t prob; ///< (# pkts success )/(# total pkts)
|
||||
|
||||
/**
|
||||
* EWMA calculation
|
||||
* ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100
|
||||
*/
|
||||
uint32_t ewmaProb;
|
||||
|
||||
uint32_t prevNumRateAttempt; ///< from last rate
|
||||
uint32_t prevNumRateSuccess; ///< from last rate
|
||||
uint64_t successHist; ///< aggregate of all successes
|
||||
uint64_t attemptHist; ///< aggregate of all attempts
|
||||
uint32_t throughput; ///< throughput of a rate
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure for a Minstrel Rate table
|
||||
* A vector of a struct RateInfo
|
||||
*/
|
||||
typedef std::vector<struct RateInfo> MinstrelRate;
|
||||
|
||||
/**
|
||||
* Data structure for a Sample Rate table
|
||||
* A vector of a vector uint32_t
|
||||
*/
|
||||
typedef std::vector<std::vector<uint32_t> > SampleRate;
|
||||
|
||||
struct MinstrelWifiRemoteStation : public WifiRemoteStation
|
||||
{
|
||||
Time m_nextStatsUpdate; ///< 10 times every second
|
||||
MinstrelRate m_minstrelTable; ///< minstrel table
|
||||
SampleRate m_sampleTable; ///< sample table
|
||||
|
||||
/**
|
||||
* To keep track of the current position in the our random sample table
|
||||
@@ -164,7 +120,9 @@ MinstrelWifiManager::GetTypeId (void)
|
||||
}
|
||||
|
||||
MinstrelWifiManager::MinstrelWifiManager ()
|
||||
{}
|
||||
{
|
||||
m_nsupported = 0;
|
||||
}
|
||||
|
||||
MinstrelWifiManager::~MinstrelWifiManager ()
|
||||
{}
|
||||
@@ -232,13 +190,14 @@ MinstrelWifiManager::DoCreateStation (void) const
|
||||
void
|
||||
MinstrelWifiManager::CheckInit(MinstrelWifiRemoteStation *station)
|
||||
{
|
||||
if (!station->m_initialized)
|
||||
if (!station->m_initialized && GetNSupported (station) > 1)
|
||||
{
|
||||
// Note: we appear to be doing late initialization of the table
|
||||
// to make sure that the set of supported rates has been initialized
|
||||
// before we perform our own initialization.
|
||||
station->m_minstrelTable = MinstrelRate(GetNSupported (station));
|
||||
station->m_sampleTable = SampleRate(GetNSupported (station), std::vector<uint32_t> (m_sampleCol));
|
||||
m_nsupported = GetNSupported (station);
|
||||
m_minstrelTable = MinstrelRate(m_nsupported);
|
||||
m_sampleTable = SampleRate(m_nsupported, std::vector<uint32_t> (m_sampleCol));
|
||||
InitSampleTable (station);
|
||||
RateInit (station);
|
||||
station->m_initialized = true;
|
||||
@@ -296,6 +255,10 @@ MinstrelWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
*/
|
||||
|
||||
CheckInit(station);
|
||||
if (!station->m_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
station->m_longRetry++;
|
||||
|
||||
@@ -305,30 +268,30 @@ MinstrelWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
if (!station->m_isSampling)
|
||||
{
|
||||
/// use best throughput rate
|
||||
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
|
||||
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
|
||||
{
|
||||
; ///< there's still a few retries left
|
||||
}
|
||||
|
||||
/// use second best throughput rate
|
||||
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = station->m_maxTpRate2;
|
||||
}
|
||||
|
||||
/// use best probability rate
|
||||
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = station->m_maxProbRate;
|
||||
}
|
||||
|
||||
/// use lowest base rate
|
||||
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = 0;
|
||||
}
|
||||
@@ -341,30 +304,30 @@ MinstrelWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
if (station->m_sampleRateSlower)
|
||||
{
|
||||
/// use best throughput rate
|
||||
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
|
||||
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
|
||||
{
|
||||
; ///< there are a few retries left
|
||||
}
|
||||
|
||||
/// use random rate
|
||||
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = station->m_sampleRate;
|
||||
}
|
||||
|
||||
/// use max probability rate
|
||||
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount ))
|
||||
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount ))
|
||||
{
|
||||
station->m_txrate = station->m_maxProbRate;
|
||||
}
|
||||
|
||||
/// use lowest base rate
|
||||
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_sampleRate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = 0;
|
||||
}
|
||||
@@ -374,30 +337,30 @@ MinstrelWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
else
|
||||
{
|
||||
/// use random rate
|
||||
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount)
|
||||
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount)
|
||||
{
|
||||
; ///< keep using it
|
||||
}
|
||||
|
||||
/// use the best rate
|
||||
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = station->m_maxTpRate;
|
||||
}
|
||||
|
||||
/// use the best probability rate
|
||||
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = station->m_maxProbRate;
|
||||
}
|
||||
|
||||
/// use the lowest base rate
|
||||
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
|
||||
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
|
||||
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount +
|
||||
m_minstrelTable[station->m_sampleRate].adjustedRetryCount))
|
||||
{
|
||||
station->m_txrate = 0;
|
||||
}
|
||||
@@ -415,16 +378,20 @@ MinstrelWifiManager::DoReportDataOk (WifiRemoteStation *st,
|
||||
station->m_sampleRateSlower=false;
|
||||
|
||||
CheckInit (station);
|
||||
if (!station->m_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
station->m_minstrelTable[station->m_txrate].numRateSuccess++;
|
||||
station->m_minstrelTable[station->m_txrate].numRateAttempt++;
|
||||
m_minstrelTable[station->m_txrate].numRateSuccess++;
|
||||
m_minstrelTable[station->m_txrate].numRateAttempt++;
|
||||
|
||||
UpdateRetry (station);
|
||||
|
||||
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
|
||||
m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
|
||||
station->m_packetCount++;
|
||||
|
||||
if (GetNSupported (station) >= 1)
|
||||
if (m_nsupported >= 1)
|
||||
{
|
||||
station->m_txrate = FindRate (station);
|
||||
}
|
||||
@@ -441,10 +408,10 @@ MinstrelWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st)
|
||||
|
||||
UpdateRetry (station);
|
||||
|
||||
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
|
||||
m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry;
|
||||
station->m_err++;
|
||||
|
||||
if (GetNSupported (station) >= 1)
|
||||
if (m_nsupported >= 1)
|
||||
{
|
||||
station->m_txrate = FindRate (station);
|
||||
}
|
||||
@@ -468,7 +435,7 @@ MinstrelWifiManager::DoGetDataMode (WifiRemoteStation *st,
|
||||
CheckInit (station);
|
||||
|
||||
/// start the rate at half way
|
||||
station->m_txrate = GetNSupported (station) / 2;
|
||||
station->m_txrate = m_nsupported / 2;
|
||||
}
|
||||
UpdateStats (station);
|
||||
return GetSupported (station, station->m_txrate);
|
||||
@@ -492,11 +459,11 @@ uint32_t
|
||||
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station)
|
||||
{
|
||||
uint32_t bitrate;
|
||||
bitrate = station->m_sampleTable[station->m_index][station->m_col];
|
||||
bitrate = m_sampleTable[station->m_index][station->m_col];
|
||||
station->m_index++;
|
||||
|
||||
/// bookeeping for m_index and m_col variables
|
||||
if (station->m_index > (GetNSupported (station) - 2))
|
||||
if (station->m_index > (m_nsupported - 2))
|
||||
{
|
||||
station->m_index =0;
|
||||
station->m_col++;
|
||||
@@ -558,7 +525,7 @@ MinstrelWifiManager::FindRate (MinstrelWifiRemoteStation *station)
|
||||
}
|
||||
|
||||
/// error check
|
||||
if (idx >= GetNSupported (station) || idx < 0)
|
||||
if (idx >= m_nsupported || idx < 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("ALERT!!! ERROR");
|
||||
}
|
||||
@@ -573,7 +540,7 @@ MinstrelWifiManager::FindRate (MinstrelWifiRemoteStation *station)
|
||||
|
||||
/// is this rate slower than the current best rate
|
||||
station->m_sampleRateSlower =
|
||||
(station->m_minstrelTable[idx].perfectTxTime > station->m_minstrelTable[station->m_maxTpRate].perfectTxTime);
|
||||
(m_minstrelTable[idx].perfectTxTime > m_minstrelTable[station->m_maxTpRate].perfectTxTime);
|
||||
|
||||
/// using the best rate instead
|
||||
if (station->m_sampleRateSlower)
|
||||
@@ -604,6 +571,10 @@ MinstrelWifiManager::UpdateStats (MinstrelWifiRemoteStation *station)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!station->m_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
NS_LOG_DEBUG ("Updating stats="<<this);
|
||||
|
||||
station->m_nextStatsUpdate = Simulator::Now () + m_updateStats;
|
||||
@@ -611,11 +582,11 @@ MinstrelWifiManager::UpdateStats (MinstrelWifiRemoteStation *station)
|
||||
Time txTime;
|
||||
uint32_t tempProb;
|
||||
|
||||
for (uint32_t i =0; i < GetNSupported (station); i++)
|
||||
for (uint32_t i =0; i < m_nsupported; i++)
|
||||
{
|
||||
|
||||
/// calculate the perfect tx time for this rate
|
||||
txTime = station->m_minstrelTable[i].perfectTxTime;
|
||||
txTime = m_minstrelTable[i].perfectTxTime;
|
||||
|
||||
/// just for initialization
|
||||
if (txTime.GetMicroSeconds () == 0)
|
||||
@@ -624,61 +595,61 @@ MinstrelWifiManager::UpdateStats (MinstrelWifiRemoteStation *station)
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("m_txrate=" << station->m_txrate <<
|
||||
"\t attempt=" << station->m_minstrelTable[i].numRateAttempt <<
|
||||
"\t success=" << station->m_minstrelTable[i].numRateSuccess);
|
||||
"\t attempt=" << m_minstrelTable[i].numRateAttempt <<
|
||||
"\t success=" << m_minstrelTable[i].numRateSuccess);
|
||||
|
||||
/// if we've attempted something
|
||||
if (station->m_minstrelTable[i].numRateAttempt)
|
||||
if (m_minstrelTable[i].numRateAttempt)
|
||||
{
|
||||
/**
|
||||
* calculate the probability of success
|
||||
* assume probability scales from 0 to 18000
|
||||
*/
|
||||
tempProb = (station->m_minstrelTable[i].numRateSuccess * 18000) / station->m_minstrelTable[i].numRateAttempt;
|
||||
tempProb = (m_minstrelTable[i].numRateSuccess * 18000) / m_minstrelTable[i].numRateAttempt;
|
||||
|
||||
/// bookeeping
|
||||
station->m_minstrelTable[i].successHist += station->m_minstrelTable[i].numRateSuccess;
|
||||
station->m_minstrelTable[i].attemptHist += station->m_minstrelTable[i].numRateAttempt;
|
||||
station->m_minstrelTable[i].prob = tempProb;
|
||||
m_minstrelTable[i].successHist += m_minstrelTable[i].numRateSuccess;
|
||||
m_minstrelTable[i].attemptHist += m_minstrelTable[i].numRateAttempt;
|
||||
m_minstrelTable[i].prob = tempProb;
|
||||
|
||||
/// ewma probability (cast for gcc 3.4 compatibility)
|
||||
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100);
|
||||
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100);
|
||||
|
||||
station->m_minstrelTable[i].ewmaProb = tempProb;
|
||||
m_minstrelTable[i].ewmaProb = tempProb;
|
||||
|
||||
/// calculating throughput
|
||||
station->m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
|
||||
m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds());
|
||||
|
||||
}
|
||||
|
||||
/// bookeeping
|
||||
station->m_minstrelTable[i].prevNumRateAttempt = station->m_minstrelTable[i].numRateAttempt;
|
||||
station->m_minstrelTable[i].prevNumRateSuccess = station->m_minstrelTable[i].numRateSuccess;
|
||||
station->m_minstrelTable[i].numRateSuccess = 0;
|
||||
station->m_minstrelTable[i].numRateAttempt = 0;
|
||||
m_minstrelTable[i].prevNumRateAttempt = m_minstrelTable[i].numRateAttempt;
|
||||
m_minstrelTable[i].prevNumRateSuccess = m_minstrelTable[i].numRateSuccess;
|
||||
m_minstrelTable[i].numRateSuccess = 0;
|
||||
m_minstrelTable[i].numRateAttempt = 0;
|
||||
|
||||
/// Sample less often below 10% and above 95% of success
|
||||
if ((station->m_minstrelTable[i].ewmaProb > 17100) || (station->m_minstrelTable[i].ewmaProb < 1800))
|
||||
if ((m_minstrelTable[i].ewmaProb > 17100) || (m_minstrelTable[i].ewmaProb < 1800))
|
||||
{
|
||||
/**
|
||||
* retry count denotes the number of retries permitted for each rate
|
||||
* # retry_count/2
|
||||
*/
|
||||
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount >> 1;
|
||||
if (station->m_minstrelTable[i].adjustedRetryCount > 2)
|
||||
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount >> 1;
|
||||
if (m_minstrelTable[i].adjustedRetryCount > 2)
|
||||
{
|
||||
station->m_minstrelTable[i].adjustedRetryCount = 2 ;
|
||||
m_minstrelTable[i].adjustedRetryCount = 2 ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount;
|
||||
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount;
|
||||
}
|
||||
|
||||
/// if it's 0 allow one retry limit
|
||||
if (station->m_minstrelTable[i].adjustedRetryCount == 0)
|
||||
if (m_minstrelTable[i].adjustedRetryCount == 0)
|
||||
{
|
||||
station->m_minstrelTable[i].adjustedRetryCount = 1;
|
||||
m_minstrelTable[i].adjustedRetryCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,33 +657,33 @@ MinstrelWifiManager::UpdateStats (MinstrelWifiRemoteStation *station)
|
||||
uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0;
|
||||
|
||||
/// go find max throughput, second maximum throughput, high probability succ
|
||||
for (uint32_t i =0; i < GetNSupported (station); i++)
|
||||
for (uint32_t i =0; i < m_nsupported; i++)
|
||||
{
|
||||
NS_LOG_DEBUG ("throughput" << station->m_minstrelTable[i].throughput <<
|
||||
"\n ewma" << station->m_minstrelTable[i].ewmaProb);
|
||||
NS_LOG_DEBUG ("throughput" << m_minstrelTable[i].throughput <<
|
||||
"\n ewma" << m_minstrelTable[i].ewmaProb);
|
||||
|
||||
if (max_tp < station->m_minstrelTable[i].throughput)
|
||||
if (max_tp < m_minstrelTable[i].throughput)
|
||||
{
|
||||
index_max_tp = i;
|
||||
max_tp = station->m_minstrelTable[i].throughput;
|
||||
max_tp = m_minstrelTable[i].throughput;
|
||||
}
|
||||
|
||||
if (max_prob < station->m_minstrelTable[i].ewmaProb)
|
||||
if (max_prob < m_minstrelTable[i].ewmaProb)
|
||||
{
|
||||
index_max_prob = i;
|
||||
max_prob = station->m_minstrelTable[i].ewmaProb;
|
||||
max_prob = m_minstrelTable[i].ewmaProb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
max_tp = 0;
|
||||
/// find the second highest max
|
||||
for (uint32_t i =0; i < GetNSupported (station); i++)
|
||||
for (uint32_t i =0; i < m_nsupported; i++)
|
||||
{
|
||||
if ((i != index_max_tp) && (max_tp < station->m_minstrelTable[i].throughput))
|
||||
if ((i != index_max_tp) && (max_tp < m_minstrelTable[i].throughput))
|
||||
{
|
||||
index_max_tp2 = i;
|
||||
max_tp = station->m_minstrelTable[i].throughput;
|
||||
max_tp = m_minstrelTable[i].throughput;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,20 +708,20 @@ MinstrelWifiManager::RateInit (MinstrelWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_DEBUG ("RateInit="<<station);
|
||||
|
||||
for (uint32_t i = 0; i < GetNSupported (station); i++)
|
||||
for (uint32_t i = 0; i < m_nsupported; i++)
|
||||
{
|
||||
station->m_minstrelTable[i].numRateAttempt = 0;
|
||||
station->m_minstrelTable[i].numRateSuccess = 0;
|
||||
station->m_minstrelTable[i].prob = 0;
|
||||
station->m_minstrelTable[i].ewmaProb = 0;
|
||||
station->m_minstrelTable[i].prevNumRateAttempt = 0;
|
||||
station->m_minstrelTable[i].prevNumRateSuccess = 0;
|
||||
station->m_minstrelTable[i].successHist = 0;
|
||||
station->m_minstrelTable[i].attemptHist = 0;
|
||||
station->m_minstrelTable[i].throughput = 0;
|
||||
station->m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i));
|
||||
station->m_minstrelTable[i].retryCount = 1;
|
||||
station->m_minstrelTable[i].adjustedRetryCount = 1;
|
||||
m_minstrelTable[i].numRateAttempt = 0;
|
||||
m_minstrelTable[i].numRateSuccess = 0;
|
||||
m_minstrelTable[i].prob = 0;
|
||||
m_minstrelTable[i].ewmaProb = 0;
|
||||
m_minstrelTable[i].prevNumRateAttempt = 0;
|
||||
m_minstrelTable[i].prevNumRateSuccess = 0;
|
||||
m_minstrelTable[i].successHist = 0;
|
||||
m_minstrelTable[i].attemptHist = 0;
|
||||
m_minstrelTable[i].throughput = 0;
|
||||
m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i));
|
||||
m_minstrelTable[i].retryCount = 1;
|
||||
m_minstrelTable[i].adjustedRetryCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,7 +733,7 @@ MinstrelWifiManager::InitSampleTable (MinstrelWifiRemoteStation *station)
|
||||
station->m_col = station->m_index = 0;
|
||||
|
||||
/// for off-seting to make rates fall between 0 and numrates
|
||||
uint32_t numSampleRates = GetNSupported (station);
|
||||
uint32_t numSampleRates = m_nsupported;
|
||||
|
||||
uint32_t newIndex;
|
||||
for (uint32_t col = 0; col < m_sampleCol; col++)
|
||||
@@ -778,11 +749,11 @@ MinstrelWifiManager::InitSampleTable (MinstrelWifiRemoteStation *station)
|
||||
newIndex = (i + (uint32_t)uv.GetValue ()) % numSampleRates;
|
||||
|
||||
/// this loop is used for filling in other uninitilized places
|
||||
while (station->m_sampleTable[newIndex][col] != 0)
|
||||
while (m_sampleTable[newIndex][col] != 0)
|
||||
{
|
||||
newIndex = (newIndex + 1)%GetNSupported (station);
|
||||
newIndex = (newIndex + 1) % m_nsupported;
|
||||
}
|
||||
station->m_sampleTable[newIndex][col] = i;
|
||||
m_sampleTable[newIndex][col] = i;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -793,12 +764,12 @@ MinstrelWifiManager::PrintSampleTable (MinstrelWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_DEBUG ("PrintSampleTable="<<station);
|
||||
|
||||
uint32_t numSampleRates = GetNSupported (station);
|
||||
uint32_t numSampleRates = m_nsupported;
|
||||
for (uint32_t i = 0; i < numSampleRates; i++)
|
||||
{
|
||||
for (uint32_t j = 0; j < m_sampleCol; j++)
|
||||
{
|
||||
std::cout << station->m_sampleTable[i][j] << "\t";
|
||||
std::cout << m_sampleTable[i][j] << "\t";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -809,9 +780,9 @@ MinstrelWifiManager::PrintTable (MinstrelWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_DEBUG ("PrintTable="<<station);
|
||||
|
||||
for (uint32_t i=0; i < GetNSupported (station); i++)
|
||||
for (uint32_t i=0; i < m_nsupported; i++)
|
||||
{
|
||||
std::cout << "index(" << i << ") = " << station->m_minstrelTable[i].perfectTxTime<< "\n";
|
||||
std::cout << "index(" << i << ") = " << m_minstrelTable[i].perfectTxTime<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,50 @@ namespace ns3 {
|
||||
|
||||
class MinstrelWifiRemoteStation;
|
||||
|
||||
/**
|
||||
* A struct to contain all information related to a data rate
|
||||
*/
|
||||
struct RateInfo
|
||||
{
|
||||
/**
|
||||
* Perfect transmission time calculation, or frame calculation
|
||||
* Given a bit rate and a packet length n bytes
|
||||
*/
|
||||
Time perfectTxTime;
|
||||
|
||||
|
||||
uint32_t retryCount; ///< retry limit
|
||||
uint32_t adjustedRetryCount; ///< adjust the retry limit for this rate
|
||||
uint32_t numRateAttempt; ///< how many number of attempts so far
|
||||
uint32_t numRateSuccess; ///< number of successful pkts
|
||||
uint32_t prob; ///< (# pkts success )/(# total pkts)
|
||||
|
||||
/**
|
||||
* EWMA calculation
|
||||
* ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100
|
||||
*/
|
||||
uint32_t ewmaProb;
|
||||
|
||||
uint32_t prevNumRateAttempt; ///< from last rate
|
||||
uint32_t prevNumRateSuccess; ///< from last rate
|
||||
uint64_t successHist; ///< aggregate of all successes
|
||||
uint64_t attemptHist; ///< aggregate of all attempts
|
||||
uint32_t throughput; ///< throughput of a rate
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure for a Minstrel Rate table
|
||||
* A vector of a struct RateInfo
|
||||
*/
|
||||
typedef std::vector<struct RateInfo> MinstrelRate;
|
||||
|
||||
/**
|
||||
* Data structure for a Sample Rate table
|
||||
* A vector of a vector uint32_t
|
||||
*/
|
||||
typedef std::vector<std::vector<uint32_t> > SampleRate;
|
||||
|
||||
|
||||
|
||||
class MinstrelWifiManager : public WifiRemoteStationManager
|
||||
{
|
||||
@@ -101,6 +145,9 @@ private:
|
||||
|
||||
|
||||
typedef std::vector<std::pair<Time,WifiMode> > TxTime;
|
||||
MinstrelRate m_minstrelTable; ///< minstrel table
|
||||
SampleRate m_sampleTable; ///< sample table
|
||||
|
||||
|
||||
TxTime m_calcTxTime; ///< to hold all the calculated TxTime for all modes
|
||||
Time m_updateStats; ///< how frequent do we calculate the stats(1/10 seconds)
|
||||
@@ -109,6 +156,7 @@ private:
|
||||
uint32_t m_segmentSize; ///< largest allowable segment size
|
||||
uint32_t m_sampleCol; ///< number of sample columns
|
||||
uint32_t m_pktLen; ///< packet length used for calculate mode TxTime
|
||||
uint32_t m_nsupported; ///< modes supported
|
||||
};
|
||||
|
||||
}// namespace ns3
|
||||
|
||||
1
test.py
1
test.py
@@ -148,6 +148,7 @@ example_tests = [
|
||||
("wireless/multirate --totalTime=0.3s --rateManager=ns3::AmrrWifiManager", "True", "True"),
|
||||
("wireless/multirate --totalTime=0.3s --rateManager=ns3::CaraWifiManager", "True", "True"),
|
||||
("wireless/multirate --totalTime=0.3s --rateManager=ns3::IdealWifiManager", "True", "True"),
|
||||
("wireless/multirate --totalTime=0.3s --rateManager=ns3::MinstrelWifiManager", "True", "True"),
|
||||
("wireless/multirate --totalTime=0.3s --rateManager=ns3::OnoeWifiManager", "True", "True"),
|
||||
("wireless/multirate --totalTime=0.3s --rateManager=ns3::RraaWifiManager", "True", "True"),
|
||||
("wireless/simple-wifi-frame-aggregation", "True", "True"),
|
||||
|
||||
Reference in New Issue
Block a user