|
44 |
|
44 |
|
45 |
namespace ns3 { |
45 |
namespace ns3 { |
46 |
|
46 |
|
47 |
/** |
|
|
48 |
* A struct to contain all information related to a data rate |
49 |
*/ |
50 |
struct RateInfo |
51 |
{ |
52 |
/** |
53 |
* Perfect transmission time calculation, or frame calculation |
54 |
* Given a bit rate and a packet length n bytes |
55 |
*/ |
56 |
Time perfectTxTime; |
57 |
|
58 |
|
59 |
uint32_t retryCount; ///< retry limit |
60 |
uint32_t adjustedRetryCount; ///< adjust the retry limit for this rate |
61 |
uint32_t numRateAttempt; ///< how many number of attempts so far |
62 |
uint32_t numRateSuccess; ///< number of successful pkts |
63 |
uint32_t prob; ///< (# pkts success )/(# total pkts) |
64 |
|
65 |
/** |
66 |
* EWMA calculation |
67 |
* ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100 |
68 |
*/ |
69 |
uint32_t ewmaProb; |
70 |
|
71 |
uint32_t prevNumRateAttempt; ///< from last rate |
72 |
uint32_t prevNumRateSuccess; ///< from last rate |
73 |
uint64_t successHist; ///< aggregate of all successes |
74 |
uint64_t attemptHist; ///< aggregate of all attempts |
75 |
uint32_t throughput; ///< throughput of a rate |
76 |
}; |
77 |
|
78 |
/** |
79 |
* Data structure for a Minstrel Rate table |
80 |
* A vector of a struct RateInfo |
81 |
*/ |
82 |
typedef std::vector<struct RateInfo> MinstrelRate; |
83 |
|
84 |
/** |
85 |
* Data structure for a Sample Rate table |
86 |
* A vector of a vector uint32_t |
87 |
*/ |
88 |
typedef std::vector<std::vector<uint32_t> > SampleRate; |
89 |
|
47 |
|
90 |
struct MinstrelWifiRemoteStation : public WifiRemoteStation |
48 |
struct MinstrelWifiRemoteStation : public WifiRemoteStation |
91 |
{ |
49 |
{ |
92 |
Time m_nextStatsUpdate; ///< 10 times every second |
50 |
Time m_nextStatsUpdate; ///< 10 times every second |
93 |
MinstrelRate m_minstrelTable; ///< minstrel table |
|
|
94 |
SampleRate m_sampleTable; ///< sample table |
95 |
|
51 |
|
96 |
/** |
52 |
/** |
97 |
* To keep track of the current position in the our random sample table |
53 |
* To keep track of the current position in the our random sample table |
|
237 |
// Note: we appear to be doing late initialization of the table |
193 |
// Note: we appear to be doing late initialization of the table |
238 |
// to make sure that the set of supported rates has been initialized |
194 |
// to make sure that the set of supported rates has been initialized |
239 |
// before we perform our own initialization. |
195 |
// before we perform our own initialization. |
240 |
station->m_minstrelTable = MinstrelRate(GetNSupported (station)); |
196 |
m_nsupported = GetNSupported (station); |
241 |
station->m_sampleTable = SampleRate(GetNSupported (station), std::vector<uint32_t> (m_sampleCol)); |
197 |
m_minstrelTable = MinstrelRate(m_nsupported); |
|
|
198 |
m_sampleTable = SampleRate(m_nsupported, std::vector<uint32_t> (m_sampleCol)); |
242 |
InitSampleTable (station); |
199 |
InitSampleTable (station); |
243 |
RateInit (station); |
200 |
RateInit (station); |
244 |
station->m_initialized = true; |
201 |
station->m_initialized = true; |
|
305 |
if (!station->m_isSampling) |
262 |
if (!station->m_isSampling) |
306 |
{ |
263 |
{ |
307 |
/// use best throughput rate |
264 |
/// use best throughput rate |
308 |
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount) |
265 |
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount) |
309 |
{ |
266 |
{ |
310 |
; ///< there's still a few retries left |
267 |
; ///< there's still a few retries left |
311 |
} |
268 |
} |
312 |
|
269 |
|
313 |
/// use second best throughput rate |
270 |
/// use second best throughput rate |
314 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
271 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
315 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
272 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
316 |
{ |
273 |
{ |
317 |
station->m_txrate = station->m_maxTpRate2; |
274 |
station->m_txrate = station->m_maxTpRate2; |
318 |
} |
275 |
} |
319 |
|
276 |
|
320 |
/// use best probability rate |
277 |
/// use best probability rate |
321 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
278 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
322 |
station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
279 |
m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
323 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
280 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
324 |
{ |
281 |
{ |
325 |
station->m_txrate = station->m_maxProbRate; |
282 |
station->m_txrate = station->m_maxProbRate; |
326 |
} |
283 |
} |
327 |
|
284 |
|
328 |
/// use lowest base rate |
285 |
/// use lowest base rate |
329 |
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
286 |
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
330 |
station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
287 |
m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
331 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
288 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
332 |
{ |
289 |
{ |
333 |
station->m_txrate = 0; |
290 |
station->m_txrate = 0; |
334 |
} |
291 |
} |
|
341 |
if (station->m_sampleRateSlower) |
298 |
if (station->m_sampleRateSlower) |
342 |
{ |
299 |
{ |
343 |
/// use best throughput rate |
300 |
/// use best throughput rate |
344 |
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount) |
301 |
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount) |
345 |
{ |
302 |
{ |
346 |
; ///< there are a few retries left |
303 |
; ///< there are a few retries left |
347 |
} |
304 |
} |
348 |
|
305 |
|
349 |
/// use random rate |
306 |
/// use random rate |
350 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
307 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
351 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
308 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
352 |
{ |
309 |
{ |
353 |
station->m_txrate = station->m_sampleRate; |
310 |
station->m_txrate = station->m_sampleRate; |
354 |
} |
311 |
} |
355 |
|
312 |
|
356 |
/// use max probability rate |
313 |
/// use max probability rate |
357 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
314 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
358 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
315 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
359 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount )) |
316 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount )) |
360 |
{ |
317 |
{ |
361 |
station->m_txrate = station->m_maxProbRate; |
318 |
station->m_txrate = station->m_maxProbRate; |
362 |
} |
319 |
} |
363 |
|
320 |
|
364 |
/// use lowest base rate |
321 |
/// use lowest base rate |
365 |
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
322 |
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
366 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
323 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
367 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
324 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
368 |
{ |
325 |
{ |
369 |
station->m_txrate = 0; |
326 |
station->m_txrate = 0; |
370 |
} |
327 |
} |
|
374 |
else |
331 |
else |
375 |
{ |
332 |
{ |
376 |
/// use random rate |
333 |
/// use random rate |
377 |
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount) |
334 |
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount) |
378 |
{ |
335 |
{ |
379 |
; ///< keep using it |
336 |
; ///< keep using it |
380 |
} |
337 |
} |
381 |
|
338 |
|
382 |
/// use the best rate |
339 |
/// use the best rate |
383 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
340 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
384 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
341 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
385 |
{ |
342 |
{ |
386 |
station->m_txrate = station->m_maxTpRate; |
343 |
station->m_txrate = station->m_maxTpRate; |
387 |
} |
344 |
} |
388 |
|
345 |
|
389 |
/// use the best probability rate |
346 |
/// use the best probability rate |
390 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
347 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
391 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
348 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
392 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
349 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
393 |
{ |
350 |
{ |
394 |
station->m_txrate = station->m_maxProbRate; |
351 |
station->m_txrate = station->m_maxProbRate; |
395 |
} |
352 |
} |
396 |
|
353 |
|
397 |
/// use the lowest base rate |
354 |
/// use the lowest base rate |
398 |
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
355 |
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
399 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
356 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
400 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
357 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
401 |
{ |
358 |
{ |
402 |
station->m_txrate = 0; |
359 |
station->m_txrate = 0; |
403 |
} |
360 |
} |
|
416 |
|
373 |
|
417 |
CheckInit (station); |
374 |
CheckInit (station); |
418 |
|
375 |
|
419 |
station->m_minstrelTable[station->m_txrate].numRateSuccess++; |
376 |
m_minstrelTable[station->m_txrate].numRateSuccess++; |
420 |
station->m_minstrelTable[station->m_txrate].numRateAttempt++; |
377 |
m_minstrelTable[station->m_txrate].numRateAttempt++; |
421 |
|
378 |
|
422 |
UpdateRetry (station); |
379 |
UpdateRetry (station); |
423 |
|
380 |
|
424 |
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
381 |
m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
425 |
station->m_packetCount++; |
382 |
station->m_packetCount++; |
426 |
|
383 |
|
427 |
if (GetNSupported (station) >= 1) |
384 |
if (m_nsupported >= 1) |
428 |
{ |
385 |
{ |
429 |
station->m_txrate = FindRate (station); |
386 |
station->m_txrate = FindRate (station); |
430 |
} |
387 |
} |
|
441 |
|
398 |
|
442 |
UpdateRetry (station); |
399 |
UpdateRetry (station); |
443 |
|
400 |
|
444 |
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
401 |
m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
445 |
station->m_err++; |
402 |
station->m_err++; |
446 |
|
403 |
|
447 |
if (GetNSupported (station) >= 1) |
404 |
if (m_nsupported >= 1) |
448 |
{ |
405 |
{ |
449 |
station->m_txrate = FindRate (station); |
406 |
station->m_txrate = FindRate (station); |
450 |
} |
407 |
} |
|
468 |
CheckInit (station); |
425 |
CheckInit (station); |
469 |
|
426 |
|
470 |
/// start the rate at half way |
427 |
/// start the rate at half way |
471 |
station->m_txrate = GetNSupported (station) / 2; |
428 |
station->m_txrate = m_nsupported / 2; |
472 |
} |
429 |
} |
473 |
UpdateStats (station); |
430 |
UpdateStats (station); |
474 |
return GetSupported (station, station->m_txrate); |
431 |
return GetSupported (station, station->m_txrate); |
|
492 |
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station) |
449 |
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station) |
493 |
{ |
450 |
{ |
494 |
uint32_t bitrate; |
451 |
uint32_t bitrate; |
495 |
bitrate = station->m_sampleTable[station->m_index][station->m_col]; |
452 |
bitrate = m_sampleTable[station->m_index][station->m_col]; |
496 |
station->m_index++; |
453 |
station->m_index++; |
497 |
|
454 |
|
498 |
/// bookeeping for m_index and m_col variables |
455 |
/// bookeeping for m_index and m_col variables |
499 |
if (station->m_index > (GetNSupported (station) - 2)) |
456 |
if (station->m_index > (m_nsupported - 2)) |
500 |
{ |
457 |
{ |
501 |
station->m_index =0; |
458 |
station->m_index =0; |
502 |
station->m_col++; |
459 |
station->m_col++; |
|
558 |
} |
515 |
} |
559 |
|
516 |
|
560 |
/// error check |
517 |
/// error check |
561 |
if (idx >= GetNSupported (station) || idx < 0) |
518 |
if (idx >= m_nsupported || idx < 0) |
562 |
{ |
519 |
{ |
563 |
NS_LOG_DEBUG ("ALERT!!! ERROR"); |
520 |
NS_LOG_DEBUG ("ALERT!!! ERROR"); |
564 |
} |
521 |
} |
|
573 |
|
530 |
|
574 |
/// is this rate slower than the current best rate |
531 |
/// is this rate slower than the current best rate |
575 |
station->m_sampleRateSlower = |
532 |
station->m_sampleRateSlower = |
576 |
(station->m_minstrelTable[idx].perfectTxTime > station->m_minstrelTable[station->m_maxTpRate].perfectTxTime); |
533 |
(m_minstrelTable[idx].perfectTxTime > m_minstrelTable[station->m_maxTpRate].perfectTxTime); |
577 |
|
534 |
|
578 |
/// using the best rate instead |
535 |
/// using the best rate instead |
579 |
if (station->m_sampleRateSlower) |
536 |
if (station->m_sampleRateSlower) |
|
611 |
Time txTime; |
568 |
Time txTime; |
612 |
uint32_t tempProb; |
569 |
uint32_t tempProb; |
613 |
|
570 |
|
614 |
for (uint32_t i =0; i < GetNSupported (station); i++) |
571 |
for (uint32_t i =0; i < m_nsupported; i++) |
615 |
{ |
572 |
{ |
616 |
|
573 |
|
617 |
/// calculate the perfect tx time for this rate |
574 |
/// calculate the perfect tx time for this rate |
618 |
txTime = station->m_minstrelTable[i].perfectTxTime; |
575 |
txTime = m_minstrelTable[i].perfectTxTime; |
619 |
|
576 |
|
620 |
/// just for initialization |
577 |
/// just for initialization |
621 |
if (txTime.GetMicroSeconds () == 0) |
578 |
if (txTime.GetMicroSeconds () == 0) |
|
624 |
} |
581 |
} |
625 |
|
582 |
|
626 |
NS_LOG_DEBUG ("m_txrate=" << station->m_txrate << |
583 |
NS_LOG_DEBUG ("m_txrate=" << station->m_txrate << |
627 |
"\t attempt=" << station->m_minstrelTable[i].numRateAttempt << |
584 |
"\t attempt=" << m_minstrelTable[i].numRateAttempt << |
628 |
"\t success=" << station->m_minstrelTable[i].numRateSuccess); |
585 |
"\t success=" << m_minstrelTable[i].numRateSuccess); |
629 |
|
586 |
|
630 |
/// if we've attempted something |
587 |
/// if we've attempted something |
631 |
if (station->m_minstrelTable[i].numRateAttempt) |
588 |
if (m_minstrelTable[i].numRateAttempt) |
632 |
{ |
589 |
{ |
633 |
/** |
590 |
/** |
634 |
* calculate the probability of success |
591 |
* calculate the probability of success |
635 |
* assume probability scales from 0 to 18000 |
592 |
* assume probability scales from 0 to 18000 |
636 |
*/ |
593 |
*/ |
637 |
tempProb = (station->m_minstrelTable[i].numRateSuccess * 18000) / station->m_minstrelTable[i].numRateAttempt; |
594 |
tempProb = (m_minstrelTable[i].numRateSuccess * 18000) / m_minstrelTable[i].numRateAttempt; |
638 |
|
595 |
|
639 |
/// bookeeping |
596 |
/// bookeeping |
640 |
station->m_minstrelTable[i].successHist += station->m_minstrelTable[i].numRateSuccess; |
597 |
m_minstrelTable[i].successHist += m_minstrelTable[i].numRateSuccess; |
641 |
station->m_minstrelTable[i].attemptHist += station->m_minstrelTable[i].numRateAttempt; |
598 |
m_minstrelTable[i].attemptHist += m_minstrelTable[i].numRateAttempt; |
642 |
station->m_minstrelTable[i].prob = tempProb; |
599 |
m_minstrelTable[i].prob = tempProb; |
643 |
|
600 |
|
644 |
/// ewma probability (cast for gcc 3.4 compatibility) |
601 |
/// ewma probability (cast for gcc 3.4 compatibility) |
645 |
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100); |
602 |
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100); |
646 |
|
603 |
|
647 |
station->m_minstrelTable[i].ewmaProb = tempProb; |
604 |
m_minstrelTable[i].ewmaProb = tempProb; |
648 |
|
605 |
|
649 |
/// calculating throughput |
606 |
/// calculating throughput |
650 |
station->m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds()); |
607 |
m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds()); |
651 |
|
608 |
|
652 |
} |
609 |
} |
653 |
|
610 |
|
654 |
/// bookeeping |
611 |
/// bookeeping |
655 |
station->m_minstrelTable[i].prevNumRateAttempt = station->m_minstrelTable[i].numRateAttempt; |
612 |
m_minstrelTable[i].prevNumRateAttempt = m_minstrelTable[i].numRateAttempt; |
656 |
station->m_minstrelTable[i].prevNumRateSuccess = station->m_minstrelTable[i].numRateSuccess; |
613 |
m_minstrelTable[i].prevNumRateSuccess = m_minstrelTable[i].numRateSuccess; |
657 |
station->m_minstrelTable[i].numRateSuccess = 0; |
614 |
m_minstrelTable[i].numRateSuccess = 0; |
658 |
station->m_minstrelTable[i].numRateAttempt = 0; |
615 |
m_minstrelTable[i].numRateAttempt = 0; |
659 |
|
616 |
|
660 |
/// Sample less often below 10% and above 95% of success |
617 |
/// Sample less often below 10% and above 95% of success |
661 |
if ((station->m_minstrelTable[i].ewmaProb > 17100) || (station->m_minstrelTable[i].ewmaProb < 1800)) |
618 |
if ((m_minstrelTable[i].ewmaProb > 17100) || (m_minstrelTable[i].ewmaProb < 1800)) |
662 |
{ |
619 |
{ |
663 |
/** |
620 |
/** |
664 |
* retry count denotes the number of retries permitted for each rate |
621 |
* retry count denotes the number of retries permitted for each rate |
665 |
* # retry_count/2 |
622 |
* # retry_count/2 |
666 |
*/ |
623 |
*/ |
667 |
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount >> 1; |
624 |
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount >> 1; |
668 |
if (station->m_minstrelTable[i].adjustedRetryCount > 2) |
625 |
if (m_minstrelTable[i].adjustedRetryCount > 2) |
669 |
{ |
626 |
{ |
670 |
station->m_minstrelTable[i].adjustedRetryCount = 2 ; |
627 |
m_minstrelTable[i].adjustedRetryCount = 2 ; |
671 |
} |
628 |
} |
672 |
} |
629 |
} |
673 |
else |
630 |
else |
674 |
{ |
631 |
{ |
675 |
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount; |
632 |
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount; |
676 |
} |
633 |
} |
677 |
|
634 |
|
678 |
/// if it's 0 allow one retry limit |
635 |
/// if it's 0 allow one retry limit |
679 |
if (station->m_minstrelTable[i].adjustedRetryCount == 0) |
636 |
if (m_minstrelTable[i].adjustedRetryCount == 0) |
680 |
{ |
637 |
{ |
681 |
station->m_minstrelTable[i].adjustedRetryCount = 1; |
638 |
m_minstrelTable[i].adjustedRetryCount = 1; |
682 |
} |
639 |
} |
683 |
} |
640 |
} |
684 |
|
641 |
|
|
686 |
uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0; |
643 |
uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0; |
687 |
|
644 |
|
688 |
/// go find max throughput, second maximum throughput, high probability succ |
645 |
/// go find max throughput, second maximum throughput, high probability succ |
689 |
for (uint32_t i =0; i < GetNSupported (station); i++) |
646 |
for (uint32_t i =0; i < m_nsupported; i++) |
690 |
{ |
647 |
{ |
691 |
NS_LOG_DEBUG ("throughput" << station->m_minstrelTable[i].throughput << |
648 |
NS_LOG_DEBUG ("throughput" << m_minstrelTable[i].throughput << |
692 |
"\n ewma" << station->m_minstrelTable[i].ewmaProb); |
649 |
"\n ewma" << m_minstrelTable[i].ewmaProb); |
693 |
|
650 |
|
694 |
if (max_tp < station->m_minstrelTable[i].throughput) |
651 |
if (max_tp < m_minstrelTable[i].throughput) |
695 |
{ |
652 |
{ |
696 |
index_max_tp = i; |
653 |
index_max_tp = i; |
697 |
max_tp = station->m_minstrelTable[i].throughput; |
654 |
max_tp = m_minstrelTable[i].throughput; |
698 |
} |
655 |
} |
699 |
|
656 |
|
700 |
if (max_prob < station->m_minstrelTable[i].ewmaProb) |
657 |
if (max_prob < m_minstrelTable[i].ewmaProb) |
701 |
{ |
658 |
{ |
702 |
index_max_prob = i; |
659 |
index_max_prob = i; |
703 |
max_prob = station->m_minstrelTable[i].ewmaProb; |
660 |
max_prob = m_minstrelTable[i].ewmaProb; |
704 |
} |
661 |
} |
705 |
} |
662 |
} |
706 |
|
663 |
|
707 |
|
664 |
|
708 |
max_tp = 0; |
665 |
max_tp = 0; |
709 |
/// find the second highest max |
666 |
/// find the second highest max |
710 |
for (uint32_t i =0; i < GetNSupported (station); i++) |
667 |
for (uint32_t i =0; i < m_nsupported; i++) |
711 |
{ |
668 |
{ |
712 |
if ((i != index_max_tp) && (max_tp < station->m_minstrelTable[i].throughput)) |
669 |
if ((i != index_max_tp) && (max_tp < m_minstrelTable[i].throughput)) |
713 |
{ |
670 |
{ |
714 |
index_max_tp2 = i; |
671 |
index_max_tp2 = i; |
715 |
max_tp = station->m_minstrelTable[i].throughput; |
672 |
max_tp = m_minstrelTable[i].throughput; |
716 |
} |
673 |
} |
717 |
} |
674 |
} |
718 |
|
675 |
|
|
737 |
{ |
694 |
{ |
738 |
NS_LOG_DEBUG ("RateInit="<<station); |
695 |
NS_LOG_DEBUG ("RateInit="<<station); |
739 |
|
696 |
|
740 |
for (uint32_t i = 0; i < GetNSupported (station); i++) |
697 |
for (uint32_t i = 0; i < m_nsupported; i++) |
741 |
{ |
698 |
{ |
742 |
station->m_minstrelTable[i].numRateAttempt = 0; |
699 |
m_minstrelTable[i].numRateAttempt = 0; |
743 |
station->m_minstrelTable[i].numRateSuccess = 0; |
700 |
m_minstrelTable[i].numRateSuccess = 0; |
744 |
station->m_minstrelTable[i].prob = 0; |
701 |
m_minstrelTable[i].prob = 0; |
745 |
station->m_minstrelTable[i].ewmaProb = 0; |
702 |
m_minstrelTable[i].ewmaProb = 0; |
746 |
station->m_minstrelTable[i].prevNumRateAttempt = 0; |
703 |
m_minstrelTable[i].prevNumRateAttempt = 0; |
747 |
station->m_minstrelTable[i].prevNumRateSuccess = 0; |
704 |
m_minstrelTable[i].prevNumRateSuccess = 0; |
748 |
station->m_minstrelTable[i].successHist = 0; |
705 |
m_minstrelTable[i].successHist = 0; |
749 |
station->m_minstrelTable[i].attemptHist = 0; |
706 |
m_minstrelTable[i].attemptHist = 0; |
750 |
station->m_minstrelTable[i].throughput = 0; |
707 |
m_minstrelTable[i].throughput = 0; |
751 |
station->m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i)); |
708 |
m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i)); |
752 |
station->m_minstrelTable[i].retryCount = 1; |
709 |
m_minstrelTable[i].retryCount = 1; |
753 |
station->m_minstrelTable[i].adjustedRetryCount = 1; |
710 |
m_minstrelTable[i].adjustedRetryCount = 1; |
754 |
} |
711 |
} |
755 |
} |
712 |
} |
756 |
|
713 |
|
|
762 |
station->m_col = station->m_index = 0; |
719 |
station->m_col = station->m_index = 0; |
763 |
|
720 |
|
764 |
/// for off-seting to make rates fall between 0 and numrates |
721 |
/// for off-seting to make rates fall between 0 and numrates |
765 |
uint32_t numSampleRates = GetNSupported (station); |
722 |
uint32_t numSampleRates = m_nsupported; |
766 |
|
723 |
|
767 |
uint32_t newIndex; |
724 |
uint32_t newIndex; |
768 |
for (uint32_t col = 0; col < m_sampleCol; col++) |
725 |
for (uint32_t col = 0; col < m_sampleCol; col++) |
|
778 |
newIndex = (i + (uint32_t)uv.GetValue ()) % numSampleRates; |
735 |
newIndex = (i + (uint32_t)uv.GetValue ()) % numSampleRates; |
779 |
|
736 |
|
780 |
/// this loop is used for filling in other uninitilized places |
737 |
/// this loop is used for filling in other uninitilized places |
781 |
while (station->m_sampleTable[newIndex][col] != 0) |
738 |
while (m_sampleTable[newIndex][col] != 0) |
782 |
{ |
739 |
{ |
783 |
newIndex = (newIndex + 1)%GetNSupported (station); |
740 |
newIndex = (newIndex + 1) % m_nsupported; |
784 |
} |
741 |
} |
785 |
station->m_sampleTable[newIndex][col] = i; |
742 |
m_sampleTable[newIndex][col] = i; |
786 |
|
743 |
|
787 |
} |
744 |
} |
788 |
} |
745 |
} |
|
793 |
{ |
750 |
{ |
794 |
NS_LOG_DEBUG ("PrintSampleTable="<<station); |
751 |
NS_LOG_DEBUG ("PrintSampleTable="<<station); |
795 |
|
752 |
|
796 |
uint32_t numSampleRates = GetNSupported (station); |
753 |
uint32_t numSampleRates = m_nsupported; |
797 |
for (uint32_t i = 0; i < numSampleRates; i++) |
754 |
for (uint32_t i = 0; i < numSampleRates; i++) |
798 |
{ |
755 |
{ |
799 |
for (uint32_t j = 0; j < m_sampleCol; j++) |
756 |
for (uint32_t j = 0; j < m_sampleCol; j++) |
800 |
{ |
757 |
{ |
801 |
std::cout << station->m_sampleTable[i][j] << "\t"; |
758 |
std::cout << m_sampleTable[i][j] << "\t"; |
802 |
} |
759 |
} |
803 |
std::cout << std::endl; |
760 |
std::cout << std::endl; |
804 |
} |
761 |
} |
|
809 |
{ |
766 |
{ |
810 |
NS_LOG_DEBUG ("PrintTable="<<station); |
767 |
NS_LOG_DEBUG ("PrintTable="<<station); |
811 |
|
768 |
|
812 |
for (uint32_t i=0; i < GetNSupported (station); i++) |
769 |
for (uint32_t i=0; i < m_nsupported; i++) |
813 |
{ |
770 |
{ |
814 |
std::cout << "index(" << i << ") = " << station->m_minstrelTable[i].perfectTxTime<< "\n"; |
771 |
std::cout << "index(" << i << ") = " << m_minstrelTable[i].perfectTxTime<< "\n"; |
815 |
} |
772 |
} |
816 |
} |
773 |
} |
817 |
|
774 |
|