모각코(개인 활동 계획)

모각코 두 번째 모임 개인 계획, 활동과정 및 결과

Beige00 2024. 1. 13. 10:58

이번 모각코에서는 네트워크 시뮬레이터 "NS-3"를 공부할 것이다.

 

NS-3는 입문자들을 위한 Tutorial 코드를 6개 제공하고 있다.

이미 Third.cc가지는 공부를 완료했으므로, fourth.cc를 공부할 계획이다.


* 활동 과정 및 결과

Third.cc는 각각 P2P link, LAN, Wifi 연결 상황을 가정한 토폴로지를 구현해보는 방식으로 코드가 짜여있었다.

본 fourth.cc는 이전까지의 토폴로지를 구성하는 시나리오와 다르게, 시뮬레이터를 돌리며 로그를 찍는 방법을 다루고 있다.(TCP throughput, error rate, SNR 등) 

따라서 해당 기법을 배우면 IRSML에서 필요로 하는 데이터들을 뽑아내는 방법을 고안해낼 수 있을 것 같다.

특히 현재 생각하고있는 IRSML 구현 과정은

1. NS-3를 통해 논문에 제시된 토폴로지를 구성, 시뮬레이션.(1020회, 각 2400s)

2. 추출된 data를 csv 파일로 구성하여 COLAB에 구현된 IRSML 알고리즘에 적용.

3. Score 평가

이다. 여기서 2.에 사용할 방법이 되겠다고 볼 수 있겠다.

 

* Tracing

NS-3에서 output을 얻는 전략은 크게 2가지가 있다.

1. bulk output 메커니즘을 사용해 그 output에서 data를 뽑아내는 방법.

2. 원하는 data만 선별해서 추출하는 output 메커니즘을 직접 개발하는 방법.

 

1.의 경우는 유의미한 데이터를 뽑아내기 위해 스크립트를 작성하는 것(추출법 정의)외에 ns-3에 대해 아무것도 변경하지 않아도 된다. (Pcap, NS_LOG output) 

그러나 NS_LOG output은 오직 debug build에서만 이용 가능해서 성능에 패널티를 받는다.

 

2.의 경우가 Tracing 메커니즘이다. ("low-level" tracing)

high-level tracing은 trace helper를 활용해 사전에 정의된 소스 정보를 얻는 것이다.

low-level은 소스를 직접 custom sink에 연결하는 것이다.

2.의 장점은 관리해야할 데이터를 줄일 수 있고, 후처리 과정(스크립트 작성)을 하지 않을 수 있다는 점이다.

 

결론적으로 tracing system은 각각 독립적인 tracing source와 tracing sink의 개념으로 설계되었으며, source를 sink에 연결하는 메커니즘을 사용한다.

 

Trace source : Event Alarm( ex: TCP의 cwnd 크기가 변할 때 마다, 연결된 sink들은 old, new value를 전달 받음.)

Trace sink : callback Function. (source가 전달한 정보의 소비자.)

-> sink가 trace event를 받아 처리하고 싶으면, trace soure가 가지고 있는 Callback List에 본인을 추가한다.

(Observer Pattern)

 

소스코드를 보면, class 하나와 함수를 정의하고 있다.

각각 Tracing 할 source와 sink 함수이다.

 

class MyObject가 상속하는 Object는 ns-3 상에서 제공되는 클래스이다.

해당 클래스의 정의를 Documentation에 가서 찾아보았다.

Object Documentation

설명에 따르면 Object는 메모리 관리와 객체 집합을 제공하는 기본 클래스라고 한다.

따라서 우리가 현재 만들어주고 있는 MyObject는 Tracing value를 TraceConnect 함수에 전해주는 역할을 하게 되는 것이다.

 

구성을 보면, TypeId GetTypeId()를 정의해주고 있는데, 해당 함수의 원형을 Object.h 문서에서 찾아보았다.

결국  MyObject 객체로 만든 객체를 TraceConnect 함수로 연결해주어야하는데, 이때 이 CallBack 함수는

GetTypeId로 자신이 Tracing할 TypeId를 가져온다.

이때 호출될 ID를 return하는 것이다.

소스코드에 써있는 데로 TypeId 객체에 해당  Class 정보와 Tracing할 값을 전부 지정해주면, TraceConnect 함수를 통해 연결된 sink는 주어진 Callback 함수대로 해당 값을 Tracing할 것이다.

후에는 Tracing할 값을 만들어준다. (m_myInt)

 

그 다음 IntTrace라는 Tracing CallBack 함수를 만들어준다.

보통 Call Back 함수는 old -> new 값을 LOG에 찍거나 출력하게 구성한다.

 

그 후, 최종적으로 MyObject class Pointer를 만들고, 해당 source에 Tracesource 이름, Callback 함수를 연결해주어 Tracing을 해주는 것이 Fourth.cc가 되겠다.

 

fourth.cc 결과

 


근데 공부를 하다가 찾은 자료에 의하면, TraceConnectWithoutContext는 실제 시스템에서 잘 이용되지 않는다고 한다.

대신 Config path를 사용해서 trace source를 선택하는 Config System이 주로 사용된다고 한다.

결론적으로, 적절한 trace sink 코드를 작성해 source와 sink를 연결하고,

trace source의 path string을 만들어 Connect method에 넘겨준다. 그리고 동시에 callback 함수를 넘겨주면 정보를 뽑아볼 수 있게 된다.

이를 통해 third.cc에서 MH들의 이동 과정을 찍어보겠다.

결국 Config에서 제공하는 Connect, ConnectWithoutContext 함수는 내가 확인하고 싶은 Trace source에 대해 미리 설정되어있는 ConfigPath를 사용해서 직접 만든 Trace sink 함수에 연결하는 것이다.

Config::Connect는 Ptr<Object>를 찾고, 값이 변경되었을 시 Callback 함수를 실행한다.

* 이용가능한 Trace source list
https://www.nsnam.org/docs/release/3.37/doxygen/de/de5/_trace_source_list.html

 

ns-3: All TraceSources

This is a list of all Tracing sources. For more information see the Tracing section of this API documentation and the Tracing sections in the Tutorial and Manual. ns3::AarfcdWifiManager Rate: Traced value for rate changes (b/s) ns3::AarfWifiManager Rate: T

www.nsnam.org

 

* 사용법

1. Tracing source 결정. (RTO 가정)

이미 TcpSocketBase source가 존재한다고 가정

2. Config Path, Callback Signature 확인

=> Config Path는 " /NodeList/[i]/$ns3::TcpL4Protocol/SocketList/[i]"

=> Trace source name은 RTO.

따라서 최종 Config Path는 "/NodeList/[i]/$ns3::TcpL4Protocol/SocketList/[i]/RTO"가 될 것이다.

 

=> Callback Signature는 다음과 같다.

3. Callback function 정의

void
getRTO(std::string context, Time oldValue, Time newValue)
{
	NS_LOG_UNCOND(context<<"@ oldRTO = "<< oldValue.GetMilliSeconds
    << " @ newRTO = "<<newValue.GetMilliSeconds);
}

해당 함수는 임의로 작성한 sink function이다.

이 함수가 작동한다면, RTO 값의 변경 시, LOG에

"/NodeList/[i]/$ns3::TcpL4Protocol/SocketList/[i]/RTO@ oldRTO = 2500 @ newRTO= 2800"

과 같은 형식으로 Tracing result를 기록할 것이다.

 

4. 연결

Config::Connect ("/NodeList/[i]/$ns3::TcpL4Protocol/SocketList/[i]/RTO", MakeCallback (&getRTO));

과 같이 Connect하면 NodeList에 존재하는 i 번째 노드의 TcpL4protocol, SocketList의 i번째의 RTO를 Tracing하며 getRTO를 실행할 것이다.

 

* 최종 공부 결과 정리 (https://beige00.tistory.com/31)