Журнал NS3 Точность по времени - PullRequest
0 голосов
/ 10 февраля 2020

Я использую NS3.20, чтобы найти метки времени отправки пакета от узла к другому узлу в топологии FAT-TREE с помощью команды

NS_LOG= "*=level_info|prefix_func|prefix_time|prefix_node" ./waf --run scratch/fat-tree &> save-log.txt

После поиска нескольких выбранных строк, содержащих информацию о pkt 196. Выходные данные имеют вид

Метка времени, Nodeid, Functioncalled, DevNo, pktid

Примеры строк выглядят следующим образом

1.74547s 34 CsmaChannel:TransmitStart(): UID is 196)
1.74548s 34 CsmaChannel:TransmitEnd(): UID is 196)
1.74548s 23 Node:ReceiveFromDevice(): Node 23 ReceiveFromDevice:  dev 2 (type=ns3::CsmaNetDevice) Packet UID 196
1.74548s 23 BridgeNetDevice:ReceiveFromDevice(): UID is 196
1.74548s 23 CsmaChannel:TransmitStart(): UID is 196)
1.74548s 34 CsmaChannel:PropagationCompleteEvent(): UID is 196)
.
.
.

Для моего исследования мне нужны метки времени должны быть в наносекундах. Есть ли способ настроить это? NB: я пробовал cout и fout внутри функций, но он просто печатает время без node_id, что для меня бесполезно.

Пожалуйста, помогите

1 Ответ

0 голосов
/ 26 марта 2020

Сначала я предложу использовать последнюю версию ns-3, ns-3.30.1. Как правило, это хорошая идея, чтобы оставаться в курсе. При этом мое решение было протестировано с использованием ns-3.30.1, поэтому вполне возможно, что оно не работает с ns-3.20. Если это не сработает, обратитесь к комментариям в sample-log-time-format.cc.

Я ссылался на §11.3 руководства ns-3 , в котором указывалось на Например, ./src/core/examples/sample-log-time-format.cc. На основе этого примера приведен минимальный воспроизводимый пример желаемого результата.

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
// set the time format and precision of LOG macros
// https://stackoverflow.com/questions/60148908
// this example is adapted from ./src/core/examples/sample-log-time-format.cc

#include "ns3/simulator.h"
#include "ns3/log.h"
#include "ns3/random-variable-stream.h"

using namespace ns3;

void
ReplacementTimePrinter (std::ostream &os)
{
    os << Simulator::Now ().GetNanoSeconds () << " ns";
}

void
ReplaceTimePrinter (void)
{
    std::cout << "Replacing time printer function after Simulator::Run ()" << std::endl;
    LogSetTimePrinter (&ReplacementTimePrinter);
}

int
main (int argc, char *argv[])
{
    LogComponentEnable ("RandomVariableStream", LOG_LEVEL_ALL);
    LogComponentEnableAll (LOG_PREFIX_TIME);
    Ptr<UniformRandomVariable> uniformRv = CreateObject<UniformRandomVariable> ();
    Simulator::Schedule (Seconds (0), &ReplaceTimePrinter);

    // schedule some bogus events to demonstrate the new TimePrinter
    Simulator::Schedule (NanoSeconds (1), &UniformRandomVariable::SetAntithetic, uniformRv, false);
    Simulator::Schedule (NanoSeconds (123), &UniformRandomVariable::SetAntithetic, uniformRv, false);
    Simulator::Schedule (NanoSeconds (123456), &UniformRandomVariable::SetAntithetic, uniformRv, false);
    Simulator::Schedule (NanoSeconds (123456789), &UniformRandomVariable::SetAntithetic, uniformRv, false);

    Simulator::Run ();
    Simulator::Destroy ();
}

Используйте

./waf --run <program-name>

для запуска вашей программы, и результат должен быть

RandomVariableStream:RandomVariableStream(0x7fc0aee287d0)
RandomVariableStream:UniformRandomVariable(0x7fc0aee287d0)
RandomVariableStream:SetStream(0x7fc0aee287d0, -1)
RandomVariableStream:SetAntithetic(0x7fc0aee287d0, 0)
Replacing time printer function after Simulator::Run ()
1 ns RandomVariableStream:SetAntithetic(0x7fc0aee287d0, 0)
123 ns RandomVariableStream:SetAntithetic(0x7fc0aee287d0, 0)
123456 ns RandomVariableStream:SetAntithetic(0x7fc0aee287d0, 0)
123456789 ns RandomVariableStream:SetAntithetic(0x7fc0aee287d0, 0)
RandomVariableStream:~RandomVariableStream(0x7fc0aee287d0)

Обратите внимание, что вместо прямого вызова LogSetTimePrinter в нашем коде симулятора мы планируем событие, которое будет вызывать LogSetTimePrinter вместо

Simulator::Schedule (Seconds (0), &ReplaceTimePrinter);

. Я не был уверен, почему это так, но при дальнейшей проверке документации выясняется, что GetImpl() вызывает LogSetTimePrinter. GetImpl() вызывается Simulator::Run(), что означает, что Simulator::Run() будет "переопределять" любые вызовы LogSetTimePrinter до вызова Simulator::Run(). Таким образом, нам нужно создать событие, которое устанавливает TimePrinter после создания SimulatorImpl.

...