diff -r e4a750adf12c src/devices/wifi/minstrel-wifi-manager.cc --- a/src/devices/wifi/minstrel-wifi-manager.cc Mon May 24 10:52:58 2010 -0700 +++ b/src/devices/wifi/minstrel-wifi-manager.cc Thu May 27 13:16:56 2010 -0700 @@ -44,54 +44,10 @@ 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 MinstrelRate; - -/** - * Data structure for a Sample Rate table - * A vector of a vector uint32_t - */ -typedef std::vector > 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::MinstrelWifiManager () -{} +{ + m_nsupported = 0; +} MinstrelWifiManager::~MinstrelWifiManager () {} @@ -232,13 +190,14 @@ 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 (m_sampleCol)); + m_nsupported = GetNSupported (station); + m_minstrelTable = MinstrelRate(m_nsupported); + m_sampleTable = SampleRate(m_nsupported, std::vector (m_sampleCol)); InitSampleTable (station); RateInit (station); station->m_initialized = true; @@ -296,6 +255,10 @@ */ CheckInit(station); + if (!station->m_initialized) + { + return; + } station->m_longRetry++; @@ -305,30 +268,30 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } /// error check - if (idx >= GetNSupported (station) || idx < 0) + if (idx >= m_nsupported || idx < 0) { NS_LOG_DEBUG ("ALERT!!! ERROR"); } @@ -573,7 +540,7 @@ /// 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 @@ return; } + if (!station->m_initialized) + { + return; + } NS_LOG_DEBUG ("Updating stats="<m_nextStatsUpdate = Simulator::Now () + m_updateStats; @@ -611,11 +582,11 @@ 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 @@ } 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(((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100); + tempProb = static_cast(((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 @@ 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 @@ { NS_LOG_DEBUG ("RateInit="<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 @@ 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 @@ 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 @@ { NS_LOG_DEBUG ("PrintSampleTable="<m_sampleTable[i][j] << "\t"; + std::cout << m_sampleTable[i][j] << "\t"; } std::cout << std::endl; } @@ -809,9 +780,9 @@ { NS_LOG_DEBUG ("PrintTable="< MinstrelRate; + +/** + * Data structure for a Sample Rate table + * A vector of a vector uint32_t + */ +typedef std::vector > SampleRate; + class MinstrelWifiManager : public WifiRemoteStationManager @@ -101,6 +145,9 @@ typedef std::vector > 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 @@ 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 diff -r e4a750adf12c test.py --- a/test.py Mon May 24 10:52:58 2010 -0700 +++ b/test.py Thu May 27 13:16:56 2010 -0700 @@ -148,6 +148,7 @@ ("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"),