HOWTO use oprofile

From Nsnam
Revision as of 17:42, 9 January 2017 by Tomh (Talk | contribs) (Background)

Jump to: navigation, search

Main Page - Current Development - Developer FAQ - Tools - Related Projects - Project Ideas - Summer Projects

Installation - Troubleshooting - User FAQ - HOWTOs - Samples - Models - Education - Contributed Code - Papers

This is a brief HOWTO on using oprofile to statistically sample the execution performance of an ns-3 program.


here are several open source profilers, including gprof, oprofile, sysprof, and valgrind. This HOWTO focuses on oprofile, which is a good tool for ns-3 because ns-3 programs are logic-heavy with lots of small functions and templates, and a statistical profiler such as oprofile is more relevant than a profile that counts instructions such as gprof or valgrind.

We will be using operf and opreport; some documentation is found here:

Please read this tutorial on oprofile using opcontrol; it describes a bit behind the testing methodology:


oprofile is available as a package on Linux distros (e.g. 'yum install oprofile').

First, it is strongly recommended to build ns-3 as optimized code before profiling.

 ./waf configure -d optimized --enable-examples --enable-static

Second, you will need to run as root. Third you will want to run the program outside of waf, which may require you to set the LD_LIBRARY_PATH variable to find the ns-3 libraries.

 # opcontrol --deinit
 # opcontrol --no-vmlinux
 # opcontrol --separate=kernel
 # opcontrol --init
 # opcontrol --reset
 # opcontrol --start
 # ./test-program
 # opcontrol --stop
 # opreport -l ./test-program
 # opcontrol --deinit

Note: You may need to stop the NMI watchdog to free up counter 0 prior to starting. If you receive an error on opcontrol --start, try this:

 echo 0 > /proc/sys/kernel/nmi_watchdog

For more information:


This is a recent run of the example program examples/routing/ on a 64-bit Fedora 20 Linux machine. I had first used 'yum' to install oprofile.

First, as non-privileged user, I built ns-3:

 $ ./waf configure -d optimized --enable-static --enable-examples --enable-tests && ./waf build

Next, I sudo'ed to root shell and did the following. First, I added to my LD_LIBRARY_PATH environment variable the location of the ns-3 libraries, which are in the 'build/' directory:


Next, I stepped through the commands above:

 # opcontrol --deinit
 # opcontrol --no-vmlinux
 # opcontrol --separate=kernel
 # opcontrol --init
 # opcontrol --reset
 # opcontrol --start

At this point, I received an error:

 Error: counter 0 not available nmi_watchdog using this resource

I needed to disable this watchdog as stated above:

 # echo 0 > /proc/sys/kernel/nmi_watchdog

Then I ran deinit and started over.

 # opcontrol --deinit
 # opcontrol --no-vmlinux
 # opcontrol --separate=kernel
 # opcontrol --init
 # opcontrol --reset
 # opcontrol --start

At this point, I can run programs. The program that I want is found in 'build/examples/routing/ns3-dev-manet-routing-compare-optimized'.

 # cd build/examples/routing
 # ./ns3-dev-manet-routing-compare-optimized

Once the program finished, I did:

 # opcontrol --stop
 # opreport -l ./ns3-dev-manet-routing-compare-optimized > /tmp/opreport.out
 # opcontrol --deinit

This left a copy of my opreport in a temporary file. Let's look at the beginning of this file:

 # head -20 /tmp/opreport.txt 
 CPU: Core 2, speed 2.4e+06 MHz (estimated)
 Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
 samples  %        image name               symbol name
 43062     3.8673             __ieee754_pow_sse2
 40383     3.6267             _int_malloc
 33561     3.0140  ns3-dev-manet-routing-compare-optimized ns3::MapScheduler::Insert(ns3::Scheduler::Event const&)
 31310     2.8119             __ieee754_log_sse2
 31284     2.8095  ns3-dev-manet-routing-compare-optimized ns3::DcfManager::UpdateBackoff()
 30043     2.6981  ns3-dev-manet-routing-compare-optimized ns3::int64x64_t::Mul(ns3::int64x64_t const&)
 29855     2.6812  ns3-dev-manet-routing-compare-optimized ns3::DcfManager::MostRecent(ns3::Time, ns3::Time, ns3::Time, ns3::Time, ns3::Time, ns3::Time, ns3::Time) const
 29347     2.6356  ns3-dev-manet-routing-compare-optimized ns3::DcfManager::GetAccessGrantStart() const
 28877     2.5934             _int_free
 25012     2.2463      std::_Rb_tree_increment(std::_Rb_tree_node_base*)
 23880     2.1446  ns3-dev-manet-routing-compare-optimized ns3::DcfManager::GetBackoffStartFor(ns3::DcfState*)
 21907     1.9674  ns3-dev-manet-routing-compare-optimized ns3::aodv::RoutingTable::Purge()
 20875     1.8747  ns3-dev-manet-routing-compare-optimized ns3::Ptr<ns3::Packet>::~Ptr()
 20265     1.8200  ns3-dev-manet-routing-compare-optimized ns3::DefaultSimulatorImpl::Now() const
 18734     1.6825  ns3-dev-manet-routing-compare-optimized ns3::InterferenceHelper::CalculatePer(ns3::Ptr<ns3::InterferenceHelper::Event const>, std::vector<ns3::InterferenceHelper::NiChange, std::allocator<ns3::InterferenceHelper::NiChange> >*) const
 18368     1.6496             malloc
 17441     1.5663  ns3-dev-manet-routing-compare-optimized ns3::ConstantVelocityHelper::Update() const

Besides the event scheduling (the top-most ns-3 function listed above), the program spends a lot of time in the Wifi DCF code, purging the AODV routing table, in Wifi interference calculations, in mobility updates, etc...

Additional references