dorapon2000’s diary

忘備録的な。セキュリティとかネットワークすきです。

ns3.29のcodelのサンプルコードでSojournTimeを正しくトレーシングできない

正確には、ns-3-dev-git/codel-vs-pfifo-asymmetric.cc at master · nsnam/ns-3-dev-git · GitHubのSojournTimeを正しくトレーシングできません。その値をトレーシングしない以外は正常に動いていました。

特定の値の推移を記録できるトレーシングの仕組みについては、公式チュートリアルに詳しい説明があります。

環境

問題

github.com

codel-vs-pfifo-asymmetric.ccはns3に同封されているサンプルコードで、CoDelの性能評価することができます。 特にDroppingState・SojournTime・QueueLengthなどCoDelの性質を知るために必要な値をトレースできます。

問題は、SojournTimeだけなぜか出力ファイルが空白になってしまっていることです。 本来ならばcodel-vs-pfifo-fast-asymmetric-CoDel-sojourn.trにSojournTimeの値が時系列順に列挙されているはずです。

しかし、それ以外のトレースソースについては値をトレースできていますし、プログラム自体もエラーを出しません。

むむむ🤔

修正場所

2箇所修正すべき箇所があります。

$ diff -u codel-vs-pfifo-asymmetric.cc.orig codel-vs-pfifo-asymmetric.cc
--- codel-vs-pfifo-asymmetric.cc.orig   2018-10-12 00:50:29.826270000 +0900
+++ codel-vs-pfifo-asymmetric.cc        2018-10-12 00:51:16.568112000 +0900
@@ -92,9 +92,9 @@
 }

 static void
-SojournTracer (Ptr<OutputStreamWrapper>stream, Time oldval, Time newval)
+SojournTracer (Ptr<OutputStreamWrapper>stream, Time val)
 {
-  *stream->GetStream () << oldval << " " << newval << std::endl;
+  *stream->GetStream () << val << std::endl;
 }

 static void
@@ -109,7 +109,7 @@
   else
     {
       Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (sojournTrFileName.c_str ());
-      Config::ConnectWithoutContext ("/NodeList/2/$ns3::TrafficControlLayer/RootQueueDiscList/0/$ns3::CoDelQueueDisc/Sojourn", MakeBoundCallback (&SojournTracer, stream));
+      Config::ConnectWithoutContext ("/NodeList/2/$ns3::TrafficControlLayer/RootQueueDiscList/0/$ns3::CoDelQueueDisc/SojournTime", MakeBoundCallback (&SojournTracer, stream));
     }
 }

1箇所目は、Sojournというトレースシンク名で、正しくはSojournTimeでした。

  • SojournTime: Sojourn time of the last packet dequeued from the queue disc Callback signature: ns3::Time::TracedCallback

@ ns-3: ns3::CoDelQueueDisc Class Reference

2箇所目は、SojournTimeのコールバック関数のシグネチャが違いました。 上の記述にもCallback signature: ns3::Time::TracedCallbackとありますが、このシグネチャは引数を1つしか持ちません。

typedef void(* ns3::Time::TracedCallback) (Time value)

@ ns-3: ns3::Time Class Reference

当のコールバック関数SojournTracerはstreamと合わせて引数が2つじゃないかと思われるかもしれませんが、streamはns3の便利機能の1つで、いわばおまけです。 MakeBoundCallbackでファイルストリームをコールバック関数に渡すことでファイルに結果を出力してくれます。

過去の情報が修正されずに残ってしまったという感じでしょうか。

出力結果の可視化

トレース結果はgnuplotなどで可視化したいので、下に示すコードのように、時刻の値とsojournTimeの値を並べて出力するのがいいと思います。

static void
SojournTracer (Ptr<OutputStreamWrapper>stream, Time val)
{
  *stream->GetStream () << Simulator::Now ().GetSeconds () << " " << val.GetMilliSeconds() << std::endl;
}