HOWTO use oprofile: Difference between revisions
(→Use) |
(provide oprofile example) |
||
Line 28: | Line 28: | ||
# opcontrol --stop | # opcontrol --stop | ||
# opreport -l ./test-program | # opreport -l ./test-program | ||
# opcontrol --deinit | |||
Note: You may need to stop the NMI watchdog to free up counter 0 prior to starting. | 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: | If you receive an error on opcontrol --start, try this: | ||
echo | echo 0 > /proc/sys/kernel/nmi_watchdog | ||
For more information: | For more information: | ||
Line 40: | Line 41: | ||
= Example = | = 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 = | = Additional references = |
Revision as of 06:00, 27 February 2015
Main Page - Roadmap - Summer Projects - Project Ideas - Developer FAQ - Tools - Related Projects
HOWTOs - Installation - Troubleshooting - User FAQ - 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
Please read this tutorial on oprofile: http://ssvb.github.com/2011/08/23/yet-another-oprofile-tutorial.html
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.
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...