wifi: Extend the wifi-eht-network example

Add an option to print the average per-station throughput over
intermediate intervals of the specified duration
This commit is contained in:
Stefano Avallone
2022-12-20 22:41:57 +01:00
parent 2101962980
commit 6192009878

View File

@@ -45,6 +45,7 @@
#include <array>
#include <functional>
#include <numeric>
// This is a simple example in order to show how to configure an IEEE 802.11be Wi-Fi network.
//
@@ -68,6 +69,78 @@ using namespace ns3;
NS_LOG_COMPONENT_DEFINE("eht-wifi-network");
/**
* \param udp true if UDP is used, false if TCP is used
* \param serverApp a container of server applications
* \param payloadSize the size in bytes of the packets
* \return the bytes received by each server application
*/
std::vector<uint64_t>
GetRxBytes(bool udp, const ApplicationContainer& serverApp, uint32_t payloadSize)
{
std::vector<uint64_t> rxBytes(serverApp.GetN(), 0);
if (udp)
{
for (uint32_t i = 0; i < serverApp.GetN(); i++)
{
rxBytes[i] = payloadSize * DynamicCast<UdpServer>(serverApp.Get(i))->GetReceived();
}
}
else
{
for (uint32_t i = 0; i < serverApp.GetN(); i++)
{
rxBytes[i] = DynamicCast<PacketSink>(serverApp.Get(i))->GetTotalRx();
}
}
return rxBytes;
};
/**
* Print average throughput over an intermediate time interval.
* \param rxBytes a vector of the amount of bytes received by each server application
* \param udp true if UDP is used, false if TCP is used
* \param serverApp a container of server applications
* \param payloadSize the size in bytes of the packets
* \param tputInterval the duration of an intermediate time interval
* \param simulationTime the simulation time in seconds
*/
void
PrintIntermediateTput(std::vector<uint64_t>& rxBytes,
bool udp,
const ApplicationContainer& serverApp,
uint32_t payloadSize,
Time tputInterval,
double simulationTime)
{
auto newRxBytes = GetRxBytes(udp, serverApp, payloadSize);
Time now = Simulator::Now();
std::cout << "[" << (now - tputInterval).As(Time::S) << " - " << now.As(Time::S)
<< "] Per-STA Throughput (Mbit/s):";
for (std::size_t i = 0; i < newRxBytes.size(); i++)
{
std::cout << "\t\t(" << i << ") "
<< (newRxBytes[i] - rxBytes[i]) * 8. / tputInterval.GetMicroSeconds(); // Mbit/s
}
std::cout << std::endl;
rxBytes.swap(newRxBytes);
if (now < Seconds(simulationTime) - NanoSeconds(1))
{
Simulator::Schedule(Min(tputInterval, Seconds(simulationTime) - now - NanoSeconds(1)),
&PrintIntermediateTput,
rxBytes,
udp,
serverApp,
payloadSize,
tputInterval,
simulationTime);
}
}
int
main(int argc, char* argv[])
{
@@ -89,6 +162,7 @@ main(int argc, char* argv[])
int mcs{-1}; // -1 indicates an unset value
uint32_t payloadSize =
700; // must fit in the max TX duration when transmitting at MCS 0 over an RU of 26 tones
Time tputInterval{0}; // interval for detailed throughput measurement
double minExpectedThroughput{0};
double maxExpectedThroughput{0};
Time accessReqInterval{0};
@@ -134,6 +208,7 @@ main(int argc, char* argv[])
accessReqInterval);
cmd.AddValue("mcs", "if set, limit testing to a specific MCS (0-11)", mcs);
cmd.AddValue("payloadSize", "The application payload size in bytes", payloadSize);
cmd.AddValue("tputInterval", "duration of intervals for throughput measurement", tputInterval);
cmd.AddValue("minExpectedThroughput",
"if set, simulation fails if the lowest throughput is below this value",
minExpectedThroughput);
@@ -420,6 +495,21 @@ main(int argc, char* argv[])
}
}
// cumulative number of bytes received by each server application
std::vector<uint64_t> cumulRxBytes(nStations, 0);
if (tputInterval.IsStrictlyPositive())
{
Simulator::Schedule(Seconds(1) + tputInterval,
&PrintIntermediateTput,
cumulRxBytes,
udp,
serverApp,
payloadSize,
tputInterval,
simulationTime + 1);
}
Simulator::Schedule(Seconds(0), &Ipv4GlobalRoutingHelper::PopulateRoutingTables);
Simulator::Stop(Seconds(simulationTime + 1));
@@ -430,22 +520,8 @@ main(int argc, char* argv[])
// the check that the throughput cannot decrease by introducing a scaling factor (or
// tolerance)
double tolerance = 0.10;
uint64_t rxBytes = 0;
if (udp)
{
for (uint32_t i = 0; i < serverApp.GetN(); i++)
{
rxBytes +=
payloadSize * DynamicCast<UdpServer>(serverApp.Get(i))->GetReceived();
}
}
else
{
for (uint32_t i = 0; i < serverApp.GetN(); i++)
{
rxBytes += DynamicCast<PacketSink>(serverApp.Get(i))->GetTotalRx();
}
}
cumulRxBytes = GetRxBytes(udp, serverApp, payloadSize);
uint64_t rxBytes = std::accumulate(cumulRxBytes.cbegin(), cumulRxBytes.cend(), 0);
double throughput = (rxBytes * 8) / (simulationTime * 1000000.0); // Mbit/s
Simulator::Destroy();