Bug 997

Summary: Speedup Ipv4EndpointDemux when many ports in use
Product: ns-3 Reporter: Michele Weigle <mweigle>
Component: internetAssignee: ns-bugs <ns-bugs>
Status: NEEDINFO ---    
Severity: normal CC: pn709, tomh
Priority: P5 Keywords: patch
Version: ns-3.9   
Hardware: All   
OS: All   
Attachments: Modification to ipv4-end-point-demux
New diff with multimap

Description Michele Weigle 2010-09-17 16:31:35 EDT
Created attachment 982 [details]
Modification to ipv4-end-point-demux

Added a simple std::map-based cache to Ipv4EndpointDemux, which GREATLY accelerates things when many ports are in use. Patch attached as ipv4-endpoint-cache.diff
Comment 1 Tom Henderson 2010-09-20 09:24:22 EDT
(In reply to comment #0)
> Created an attachment (id=982) [details]
> Modification to ipv4-end-point-demux
> Added a simple std::map-based cache to Ipv4EndpointDemux, which GREATLY
> accelerates things when many ports are in use. Patch attached as
> ipv4-endpoint-cache.diff

Would you agree to just simply replace the std::list structure with std::map?  I don't see the benefit of maintaining both, unless there were a way to switch the underlying implementation from a user program.  There is a method GetAllEndPoints() that returns a list but I think it is only used by the NSC code and could easily be cut over.
Comment 2 Michele Weigle 2010-09-30 07:02:35 EDT
Created attachment 987 [details]
New diff with multimap
Comment 3 Michele Weigle 2010-09-30 07:03:16 EDT
Talked with Greg.  Here are his comments:
"Although it has to be changed to an std::multimap, because the Ipv4EndPointDemux may be handling more than one local address and shouldn't prevent them from using the same port number."

New attachment is the new diff using multimap.
Comment 4 Petr Novotny 2011-01-22 14:32:31 EST
After applying the diff occured following exception:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb667d6c0 (LWP 4577)]
0xb709046e in ns3::SimpleRefCount<ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter>::GetReferenceCount (this=0x0) at ../src/core/simple-ref-count.h:105
105	    return m_count;
(gdb) bt
#0  0xb709046e in ns3::SimpleRefCount<ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter>::GetReferenceCount (this=0x0) at ../src/core/simple-ref-count.h:105
#1  0xb7079c6c in ns3::Object::CheckLoose (this=0x80f0dc8)
    at ../src/core/object.cc:348
#2  0xb7080885 in ns3::Object::AggregateObject (this=0x80f0dc8, o=
      {m_ptr = 0xbfffe208}) at ../src/core/object.cc:230
#3  0xb794cd6d in ns3::InternetStackHelper::Install (this=0xbfffe340, node=
      {m_ptr = 0xbfffe278}) at ../src/helper/internet-stack-helper.cc:370
#4  0xb794d715 in ns3::InternetStackHelper::Install (this=0xbfffe340, c=
            {m_nodes = {<std::_Vector_base<ns3::Ptr<ns3::Node>, std::allocator<ns3::Ptr<ns3::Node> > >> = {_M_impl = {<std::allocator<ns3::Ptr<ns3::Node> >> = {<__gnu_cxx::new_allocator<ns3::Ptr<ns3::Node> >> = {<No data fields>}, <No data fields>}, _M_start = 0xbfffe938, _M_finish = 0xa, _M_end_of_storage = 0x0}}, <No data fields>}}) at ../src/helper/internet-stack-helper.cc:335
#5  0x08077ef0 in AdHocMobileNetworkConfigurationGenerator::GenerateNetworkIBMVisit (this=0xbfffe9f0, numberOfNodes=50, gridXLength=75, gridYLength=75, 
    mobilitySpeed=10) at ../scratch/fifth.cc:4489
#6  0x08055abd in main () at ../scratch/fifth.cc:5189

Here is code of the method from which the NS3 code is called (till the 4489 line):

	void GenerateNetworkIBMVisit (
			uint32_t numberOfNodes,
			uint32_t gridXLength,
			uint32_t gridYLength,
			double mobilitySpeed)
			NS_ASSERT(numberOfNodes != 0);
			NS_ASSERT(gridXLength != 0);
			NS_ASSERT(gridYLength != 0);


			// wifi and adhoc configuration

			StringValue phyMode = StringValue ("DsssRate11Mbps");
			//StringValue phyMode = StringValue ("OfdmRate24Mbps");
			//WifiModeValue phyMode = WifiModeValue(WifiPhy::GetOfdmRate54Mbps());

			// disable fragmentation for frames below 2200 bytes
			Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
			// turn off RTS/CTS for frames below 2200 bytes
			Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
			// Fix non-unicast data rate to be the same as that of unicast
			Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode", phyMode);

			// The below set of helpers will help us to put together the wifi NICs we want
			WifiHelper wifi;
			  //wifi.EnableLogComponents ();  // Turn on all Wifi logging
			wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
			//wifi.SetStandard (WIFI_PHY_STANDARD_80211g);

			YansWifiPhyHelper wifiPhy =  YansWifiPhyHelper::Default ();
			// This is one parameter that matters when using FixedRssLossModel
			// set it to zero; otherwise, gain will be added
			wifiPhy.Set ("RxGain", DoubleValue (0) );
			// ns-3 support RadioTap and Prism tracing extensions for 802.11b
			//wifiPhy.SetPcapFormat (YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP);

			YansWifiChannelHelper wifiChannel ;
			wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
			NS_LOG_UNCOND("	Propagation delay model: ConstantSpeedPropagationDelayModel");
			//wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",DoubleValue(-80));
			NS_LOG_UNCOND("	Propagation loss model: LogDistancePropagationLossModel - exp 3");
			wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel", "Exponent", DoubleValue(3));
			//NS_LOG_UNCOND("	Propagation loss model: NakagamiPropagationLossModel");
			//wifiChannel.AddPropagationLoss ("ns3::NakagamiPropagationLossModel");

			wifiPhy.SetChannel (wifiChannel.Create ());

			// Add a non-QoS upper mac, and disable rate control
			NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
			wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
										"DataMode", phyMode,
										   "ControlMode", phyMode);
			// Set it to adhoc mode
			wifiMac.SetType ("ns3::AdhocWifiMac");
			NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, m_nodes);

			// mobility configuration
			// Note that with FixedRssLossModel, the positions below are not used for received signal strength.

			MobilityHelper mobility;

			int gridDeltaX = gridXLength / numberOfNodesX;
			int gridDeltaY = gridYLength / numberOfNodesY;

			mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
										"MinX", DoubleValue (0.0),
										"MinY", DoubleValue (0.0),
										"DeltaX", DoubleValue (gridDeltaX),
										"DeltaY", DoubleValue (gridDeltaY),
										"GridWidth", UintegerValue (numberOfNodesX),
										"LayoutType", StringValue ("RowFirst"));

			NS_LOG_UNCOND("	Position allocator: RandomRectanglePositionAllocator");

			mobility.SetPositionAllocator ("ns3::RandomRectanglePositionAllocator",
													"X", RandomVariableValue(UniformVariable (0, gridXLength)),
													"Y", RandomVariableValue(UniformVariable (0, gridYLength)));

			if (mobilitySpeed == 0)
				mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");

				NS_LOG_UNCOND("	Mobility model: ConstantPositionMobilityModel");
				mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
										  "Bounds", RectangleValue (Rectangle (0, gridXLength, 0, gridYLength)),
										  "Speed", RandomVariableValue (ConstantVariable (mobilitySpeed)),
										  "Pause", RandomVariableValue (ConstantVariable (0.2)));

				NS_LOG_UNCOND("	Mobility model: RandomDirection2dMobilityModel");
				NS_LOG_UNCOND("		Speed: " << mobilitySpeed);
				NS_LOG_UNCOND("		Pause: " << ConstantVariable (0.2));
				NS_LOG_UNCOND("		Bounds: " << Rectangle (0, gridXLength, 0, gridYLength));

			mobility.Install (m_nodes);


			// routing configuration
			OlsrHelper olsr;
			Ipv4StaticRoutingHelper staticRouting;
			Ipv4ListRoutingHelper list;
			list.Add (staticRouting, 0);
			list.Add (olsr, 10);

			InternetStackHelper internet;
			internet.Install (m_nodes);