Difference between revisions of "HOWTO use oprofile"

From Nsnam
Jump to: navigation, search
(provide oprofile example)
(Background)
Line 5: Line 5:
 
= Background =
 
= Background =
  
Please read this tutorial on oprofile:  http://ssvb.github.com/2011/08/23/yet-another-oprofile-tutorial.html
+
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.
  
There 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 therefore 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:
 +
 
 +
* [http://oprofile.sourceforge.net/doc/overview.html#getting-started-with-operf operf]
 +
* [http://oprofile.sourceforge.net/doc/opreport.html opreport]
 +
 
 +
Please read this tutorial on oprofile using opcontrol; it describes a bit behind the testing methodology:  http://ssvb.github.com/2011/08/23/yet-another-oprofile-tutorial.html
  
 
= Use =
 
= Use =

Revision as of 17:42, 9 January 2017

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.

Background

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: http://ssvb.github.com/2011/08/23/yet-another-oprofile-tutorial.html

Use

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: http://smackerelofopinion.blogspot.com/2013/05/getting-started-with-oprofile-on-ubuntu.html

Example

This is a recent run of the example program examples/routing/manet-routing-compare.cc 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:

 # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:build/

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  libm-2.18.so             __ieee754_pow_sse2
 40383     3.6267  libc-2.18.so             _int_malloc
 33561     3.0140  ns3-dev-manet-routing-compare-optimized ns3::MapScheduler::Insert(ns3::Scheduler::Event const&)
 31310     2.8119  libm-2.18.so             __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  libc-2.18.so             _int_free
 25012     2.2463  libstdc++.so.6.0.19      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  libc-2.18.so             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