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 Wed May 26 11:25:43 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 @@ -237,8 +193,8 @@ // 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_minstrelTable = MinstrelRate(GetNSupported (station)); + m_sampleTable = SampleRate(GetNSupported (station), std::vector (m_sampleCol)); InitSampleTable (station); RateInit (station); station->m_initialized = true; @@ -305,30 +261,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 +297,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 +330,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; } @@ -416,12 +372,12 @@ CheckInit (station); - 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) @@ -441,7 +397,7 @@ 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) @@ -492,7 +448,7 @@ 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 @@ -573,7 +529,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) @@ -615,7 +571,7 @@ { /// 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 +580,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; } } @@ -688,19 +644,19 @@ /// go find max throughput, second maximum throughput, high probability succ for (uint32_t i =0; i < GetNSupported (station); 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; } } @@ -709,10 +665,10 @@ /// find the second highest max for (uint32_t i =0; i < GetNSupported (station); 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; } } @@ -739,18 +695,18 @@ for (uint32_t i = 0; i < GetNSupported (station); 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; } } @@ -778,11 +734,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); } - station->m_sampleTable[newIndex][col] = i; + m_sampleTable[newIndex][col] = i; } } @@ -798,7 +754,7 @@ { 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; } @@ -811,7 +767,7 @@ for (uint32_t i=0; i < GetNSupported (station); i++) { - std::cout << "index(" << i << ") = " << station->m_minstrelTable[i].perfectTxTime<< "\n"; + std::cout << "index(" << i << ") = " << m_minstrelTable[i].perfectTxTime<< "\n"; } } diff -r e4a750adf12c src/devices/wifi/minstrel-wifi-manager.h --- a/src/devices/wifi/minstrel-wifi-manager.h Mon May 24 10:52:58 2010 -0700 +++ b/src/devices/wifi/minstrel-wifi-manager.h Wed May 26 11:25:43 2010 -0700 @@ -40,6 +40,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 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)