I'm trying to use valgrind --tool=callgrind to profile my C++ program on Ubuntu. Here is my code:
#include <iostream>
int main()
{
std::cout<<"hello world"<<std::endl;
return 0;
}
Compile it: g++ main.cpp -g
valgrind: valgrind --tool=callgrind ./a.out
Then I get a file named callgrind.out.1153.
Then I use the tool gprof2dot and the command dot:
python gprof2dot.py -f callgrind -n10 -s callgrind.out.1153 > valgrind.dot
dot -Tpng valgrind.dot -o valgrind.png
However, this png is like this:
For me this is really hard to read.
So is it possible to make callgrind more human readable? For example, can it show me only the execution time of each function of my code or the execution time of my code line by line?
It's not super user-friendly, but I think this does what the OP wants:
callgrind_annotate --tree=both --inclusive=yes --auto=yes --show-percs=yes callgrind.out.${pid} > tree.${pid}
This creates a text file with two sections. The first section is a summary of profiled functions, sorted by the time spent in each. Example of one function:
3,090,761,742,907 (22.39%) < /home/me/proj/src/dir0/file0.cpp:caller0() (79,173,695x) [/home/me/proj/build/reldbg/lib/libzero.so]
768,380,030,255 ( 5.57%) < /home/me/proj/src/dir0/file1.cpp:caller1(unsigned int) (19,814,000x) [/home/me/proj/build/reldbg/lib/libzero.so]
3,861,537,817,283 (27.97%) * /home/me/proj/src/dir0/Abc.cpp:Abc::Abc() [/home/me/proj/build/reldbg/lib/libzero.so]
2,458,035,862,297 (17.80%) > /home/me/proj/src/dir1/file2.h:callee0() (99,049,427x) [/home/me/proj/build/reldbg/lib/libone.so]
1,378,046,252,252 ( 9.98%) > /home/me/proj/src/dir0/file3.cpp:callee1() (99,049,427x) [/home/me/proj/build/reldbg/lib/libzero.so]
The profiled function has the asterisk, its callers have less-than, the functions it calls have greater-than.
The second section is annotated source code, with the amount of time allocated on each line. For example:
--------------------------------------------------------------------------------
-- Auto-annotated source: /home/me/proj/src/dir0/file1.cpp
--------------------------------------------------------------------------------
Ir
-- line 37 ----------------------------------------
7,822,093,316 ( 0.06%) for (uint32 i = 0; i < VEC_SIZE; i++)
. {
21,018,143,872 ( 0.15%) data[i].reset();
110,822,940,416 ( 0.80%) => /home/me/proj/src/dir0/abc.cpp:Abc::reset() (1,910,740,352x)
. }
Related
can you please explain why this code is going in infinite loop? I am unable to find the error. It is working fine with small values of n and m.
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n=1000000, m=1000000;
long long k = 1;
for (long long i = 0; i < n; i++)
{
for (long long j = 0; j < m; j++)
{
k++;
}
}
cout << k;
return 0;
}
It's not infinite, but that k++ operation has to run for 1,000,000 * 1,000,000 = 1,000,000,000,000 times. It's not infinite, but it takes too long. That's exactly why it works well with small n and m values.
It is a typical target for optimization.
Build with -Ofast.
g++ t_duration.cpp -Ofast -std=c++11 -o a_fast
#time ./a_fast
1000000000001
real 0m0.002s
user 0m0.000s
sys 0m0.002s
it takes almost no time to return the output.
Build with -O1.
g++ t_duration.cpp -O1 -std=c++11 -o a_1
#./a_1
419774 ms
About 420 seconds to complete the calculation.
when I Run this code I got this as my output
1000000000001
reference : I had run this code in the code chef IDE(https://www.codechef.com/ide)
you can try in this IDE once, I guess there is some problem with your IDE
or might be some other issue
it took me less than 20 sec to run this(on clock😁)
But when I put the same code in CODE::BLOCKS its taking long time(like you said infinite loops running) and the reason is quite simple it should do 1000000000000 runs
however this brings me a questions what's difference between code chef IDE and code::blocks compiler
(Got a New question from your question 😁🤔(Difference Between Code-Chef IDE and Code::Blocks))
Finally answer is try on with code chef IDE that's it , this code runs fast there🤣
Hope this Helps you 😃
I have a small function in written Haskell with the following type:
foreign export ccall sget :: Ptr CInt -> CSize -> Ptr CSize -> IO (Ptr CInt)
I am calling this from multiple C++ threads running concurrently (via
TBB). During this part of the execution of my program I can barely get a
load average above 1.4 even though I'm running on a six-core CPU (12
logical cores). I therefore suspect that either the calls into Haskell all
get funnelled through a single thread, or there is some significant
synchronization going on.
I am not doing any such thing explicitly, all the function does is operate
on the incoming data (after storing it into a Data.Vector.Storable), and
return the result back as a newly allocated array (from Data.Marshal.Array).
Is there anything I need to do to fully enable concurrent calls like this?
I am using GHC 8.6.5 on Debian Linux (bullseye/testing), and I am compiling with -threaded -O2.
Looking forward to reading some advice,
Sebastian
Using the simple example at the end of this answer, if I compile with:
$ ghc -O2 Worker.hs
$ ghc -O2 -threaded Worker.o caller.c -lpthread -no-hs-main -o test
then running it with ./test occupies only one core at 100%. I need to run it with ./test +RTS -N, and then on my 4-core desktop, it runs at 400% with a load average of around 4.0.
So, the RTS -N flag affects the number of parallel threads that can simultaneously run an exported Haskell function and there is no special action required (other than compiling with -threaded and running with +RTS -n) to fully utilize all available cores.
So, there must be something about your example that's causing the problem. It could be contention between threads over some shared data structure. Or, maybe parallel garbage collection is causing problems; I've observed parallel GC causing worse performance with increasing -N in a simple test case (details forgotten, sadly), so you could try turning off parallel GC with -qg or limiting the number of cores involved with -qn2 or something. To enable these options, you need to call hs_init_with_rtsopts() in place of the usual hs_init() as in my example.
If that doesn't work, I think you'll have to try to narrow down the problem and post a minimal example that illustrates the performance issue to get more help.
My example:
caller.c
#include "HsFFI.h"
#include "Rts.h"
#include "Worker_stub.h"
#include <pthread.h>
#define NUM_THREAD 4
void*
work(void* arg)
{
for (;;) {
fibIO(30);
}
}
int
main(int argc, char **argv)
{
hs_init_with_rtsopts(&argc, &argv);
pthread_t threads[NUM_THREAD];
for (int i = 0; i < NUM_THREAD; ++i) {
int rc = pthread_create(&threads[i], NULL, work, NULL);
}
for (int i = 0; i < NUM_THREAD; ++i) {
pthread_join(threads[i], NULL);
}
hs_exit();
return 0;
}
Worker.hs
module Worker where
import Foreign
fibIO :: Int -> IO Int
fibIO = return . fib
fib :: Int -> Int
fib n | n > 1 = fib (n-1) + fib (n-2)
| otherwise = 1
foreign export ccall fibIO :: Int -> IO Int
My code includes the loop that appends two vectors and discards one of them.
Code:
for (int j = 0; j < superpixels[orgIndex].size(); j++)
{
superpixels[dstIndex].push_back(superpixels[orgIndex][j]);
}
superpixels[orgIndex].clear();
std::vector<int>().swap(superpixels[orgIndex]);
However, the Eclipse debugger reads that superpixels[dstIndex].size() is still unchanged after push_back().
In the first case before the code is executed, I have orgIndex = 1, dstIndex = 287, superpixels[1].size() = 191, superpixels[287].size() = 1.
After the loop executed once, I see that the 191 values of superpixels[1] has been successfully appended to superpixels[287] (that is, superpixels[287][191] is not a garbage and equals the former value of superpixels[1][190])
However, the 'Expression' tab in Eclipse debugger still reads superpixels[1].size() = 191 and superpixels[287].size() = 1 (which should be 0, 192 respectively)
The Eclipse debugger console reads:
Name : superpixels[1].size()
Details:0
Default:191
Decimal:191
Hex:0xbf
Binary:10111111
Octal:0277
Name : superpixels[287].size()
Details:192
Default:1
Decimal:192
Hex:0xc0
Binary:11000000
Octal:0300
Why this happens? What should I do to update them correctly?
My Eclipse version is:
Version: Oxygen Release (4.7.0)
Build id: 20170620-1800
Build flag: -c -fmessage-length=0 -std=c++11 -pthread
Please create a Minimal, Complete, and Verifiable example
I prepared a C++ interface to a legacy Fortran library.
Some subroutines in the legacy library follow an ugly but usable status code convention to report errors, and I use such status codes to throw a readable exception from my C++ code: it works great.
On the other hand, sometimes the legacy library calls STOP (which terminates the program). And it often does it even though the condition is recoverable.
I would like to capture this STOP from within C++, and so far I have been unsuccessful.
The following code is simple, but exactly represents the problem at hand:
The Fortran legacy library fmodule.f90:
module fmodule
use iso_c_binding
contains
subroutine fsub(x) bind(c, name="fsub")
real(c_double) x
if(x>=5) then
stop 'x >=5 : this kills the program'
else
print*, x
end if
end subroutine fsub
end module fmodule
The C++ Interface main.cpp:
#include<iostream>
// prototype for the external Fortran subroutine
extern "C" {
void fsub(double& x);
}
int main() {
double x;
while(std::cin >> x) {
fsub(x);
}
return 0;
}
The compilation lines (GCC 4.8.1 / OS X 10.7.4; $ denotes command prompt ):
$ gfortran -o libfmodule.so fmodule.f90 -shared -fPIC -Wall
$ g++ main.cpp -L. -lfmodule -std=c++11
The run:
$ ./a.out
1
1.0000000000000000
2
2.0000000000000000
3
3.0000000000000000
4
4.0000000000000000
5
STOP x >=5 : this kills the program
How could I capture the STOP and, say, request another number. Notice that I do not want to touch the Fortran code.
What I have tried:
std::atexit: cannot "come back" from it once I have entered it
std::signal: STOP does not seem to throw a signal which I can capture
You can solve your problem by intercepting the call to the exit function from the Fortran runtime. See below. a.out is created with your code and the compilation lines you give.
Step 1. Figure out which function is called. Fire up gdb
$ gdb ./a.out
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
[...]
(gdb) break fsub
Breakpoint 1 at 0x400888
(gdb) run
Starting program: a.out
5
Breakpoint 1, 0x00007ffff7dfc7e4 in fsub () from ./libfmodule.so
(gdb) step
Single stepping until exit from function fsub,
which has no line number information.
stop_string (string=0x7ffff7dfc8d8 "x >=5 : this kills the programfmodule.f90", len=30) at /usr/local/src/gcc-4.7.2/libgfortran/runtime/stop.c:67
So stop_string is called. We need to know to which symbol this function corresponds.
Step 2. Find the exact name of the stop_string function. It must be in one of the shared libraries.
$ ldd ./a.out
linux-vdso.so.1 => (0x00007fff54095000)
libfmodule.so => ./libfmodule.so (0x00007fa31ab7d000)
libstdc++.so.6 => /usr/local/gcc/4.7.2/lib64/libstdc++.so.6 (0x00007fa31a875000)
libm.so.6 => /lib64/libm.so.6 (0x0000003da4000000)
libgcc_s.so.1 => /usr/local/gcc/4.7.2/lib64/libgcc_s.so.1 (0x00007fa31a643000)
libc.so.6 => /lib64/libc.so.6 (0x0000003da3c00000)
libgfortran.so.3 => /usr/local/gcc/4.7.2/lib64/libgfortran.so.3 (0x00007fa31a32f000)
libquadmath.so.0 => /usr/local/gcc/4.7.2/lib64/libquadmath.so.0 (0x00007fa31a0fa000)
/lib64/ld-linux-x86-64.so.2 (0x0000003da3800000)
I found it in (no surprise) the fortran runtime.
$ readelf -s /usr/local/gcc/4.7.2/lib64/libgfortran.so.3|grep stop_string
1121: 000000000001b320 63 FUNC GLOBAL DEFAULT 11 _gfortran_stop_string##GFORTRAN_1.0
2417: 000000000001b320 63 FUNC GLOBAL DEFAULT 11 _gfortran_stop_string
Step 3. Write a function that will replace that function
I look for the precise signature of the function in the source code (/usr/local/src/gcc-4.7.2/libgfortran/runtime/stop.c see gdb session)
$ cat my_exit.c
#define _GNU_SOURCE
#include <stdio.h>
void _gfortran_stop_string (const char *string, int len)
{
printf("Let's keep on");
}
Step 4. Compile a shared object exporting that symbol.
gcc -Wall -fPIC -c -o my_exit.o my_exit.c
gcc -shared -fPIC -Wl,-soname -Wl,libmy_exit.so -o libmy_exit.so my_exit.o
Step 5. Run the program with LD_PRELOAD so that our new function has precedence over the one form the runtime
$ LD_PRELOAD=./libmy_exit.so ./a.out
1
1.0000000000000000
2
2.0000000000000000
3
3.0000000000000000
4
4.0000000000000000
5
Let's keep on 5.0000000000000000
6
Let's keep on 6.0000000000000000
7
Let's keep on 7.0000000000000000
There you go.
Since what you want would result in non-portable code anyway, why not just subvert the exit mechanism using the obscure long jump mechanism:
#include<iostream>
#include<csetjmp>
#include<cstdlib>
// prototype for the external Fortran subroutine
extern "C" {
void fsub(double* x);
}
volatile bool please_dont_exit = false;
std::jmp_buf jenv;
static void my_exit_handler() {
if (please_dont_exit) {
std::cout << "But not yet!\n";
// Re-register ourself
std::atexit(my_exit_handler);
longjmp(jenv, 1);
}
}
void wrapped_fsub(double& x) {
please_dont_stop = true;
if (!setjmp(jenv)) {
fsub(&x);
}
please_dont_stop = false;
}
int main() {
std::atexit(my_exit_handler);
double x;
while(std::cin >> x) {
wrapped_fsub(x);
}
return 0;
}
Calling longjmp jumps right in the middle of the line with the setjmp call and setjmp returns the value passed as the second argument of longjmp. Otherwise setjmp returns 0. Sample output (OS X 10.7.4, GCC 4.7.1):
$ ./a.out
2
2.0000000000000000
6
STOP x >=5 : this kills the program
But not yet!
7
STOP x >=5 : this kills the program
But not yet!
4
4.0000000000000000
^D
$
No library preloading required (which anyway is a bit more involved on OS X than on Linux). A word of warning though - exit handlers are called in reverse order of their registration. One should be careful that no other exit handlers are registered after my_exit_handler.
Combining the two answers that use a custom _gfortran_stop_string function and longjmp, I thought that raising an exception inside the custom function would be similar, then catch in in the main code. So this came out:
main.cpp:
#include<iostream>
// prototype for the external Fortran subroutine
extern "C" {
void fsub(double& x);
}
int main() {
double x;
while(std::cin >> x) {
try { fsub(x); }
catch (int rc) { std::cout << "Fortran stopped with rc = " << rc <<std::endl; }
}
return 0;
}
catch.cpp:
extern "C" {
void _gfortran_stop_string (const char*, int);
}
void _gfortran_stop_string (const char *string, int len)
{
throw 666;
}
Then, compiling:
gfortran -c fmodule.f90
g++ -c catch.cpp
g++ main.cpp fmodule.o catch.o -lgfortran
Running:
./a.out
2
2.0000000000000000
3
3.0000000000000000
5
Fortran stopped with rc = 666
6
Fortran stopped with rc = 666
2
2.0000000000000000
3
3.0000000000000000
^D
So, seems to work :)
I suggest you fork your process before calling the fortran code and exit 0 (edit: if STOP exits with zero, you will need a sentinel exit code, clanky but does the job) after the fortran execution. That way every fortran call will finish in the same way: the same as if it had stopped. Or, if "STOP" ensure an error, throw the exception when the fortran code stops and send some other message when the fortran execution "completes" normaly.
Below is an example inspire from you code assuming a fortran "STOP" is an error.
int main() {
double x;
pid_t pid;
int exit_code_normal = //some value that is different from all STOP exit code values
while(std::cin >> x) {
pid = fork();
if(pid < 0) {
// error with the fork handle appropriately
} else if(pid == 0) {
fsub(x);
exit(exit_code_normal);
} else {
wait(&status);
if(status != exit_code_normal)
// throw your error message.
}
}
return 0;
}
The exit code could be a constant instead of a variable. I don't think it matters much.
Following a comment, it occurs that the result from the execution would be lost if it sits in the memory of the process (rather than, say, write to a file). If it is the case, I can think of 3 possibilities:
The fortran code messes a whole lot of memory during the call and letting the execution continue beyond the STOP is probably not a good idea in the first place.
The fortran code simply return some value (through it's argument if my fortran is not too rusty) and this could be relayed back to the parent easily through a shared memory space.
The execution of the fortran subroutine acts on an external system (ex: writes to a file) and no return values are expected.
In the 3rd case, my solution above works as is. I prefer it over some other suggested solution mainly because: 1) you don't have to ensure the build process is properly maintained 2) fortran "STOP" still behave as expected and 3) it requires very few lines of code and all the "fortran STOP workaround" logic sits in one single place. So in terms of long term maintenance, I much prefer that.
In the 2nd case, my code above needs small modification but still holds the advantages enumerated above at the price of minimal added complexity.
In the 1st case, you will have to mess with the fortran code no matter what.
I'm writing a program that takes 2 command line arguments: a and b respectively.
Everything is good as long as a <= 17.5
As soon as a > 17.5 the program throws the following error:
incorrect checksum for freed object - object was probably modified after being freed
I've narrowed down the problem down to the following piece of code:
for(int a=0; a < viBrickWall.size(); a++) {
vector<int64_t> viTmp(iK-i);
fill(viTmp.begin(),viTmp.end(),2);
for(int b = 0; b < viBrickWall[a].size(); b++) {
viTmp[viBrickWall[a][b]] = 3;
}
viResult.push_back(viTmp);
viTmp.clear();
}
Removing the latter piece of code, gets rid of the error.
I'm also using valgrind to debug the memory, but I haven't been able to find any solution.
Here it is a copy of valgrind's report:
Report hosted in pastebin
EDIT
I compiled the program with debugging flags:
g++ -g -O0 -fno-inline program.cpp
and ran it with valgrind as follows:
` valgrind --leak-check=full --show-reachable=yes --dsymutil=yes ./a.out 48 10 ``
I noticed the following line:
==15318== Invalid write of size 8
==15318== at 0x100001719: iTileBricks(int) (test.cpp:74)
==15318== by 0x100001D7D: main (test.cpp:40)
Line 74 is:
viTmp[viBrickWall[a][b]] = 3;
and Line 40 is:
viBrickWall = iTileBricks(iPanelWidth);
You're causing an invalid write to heap memory with this line:
viTmp[viBrickWall[a][b]] = 3;
this implies that viBrickWall[a][b] is indexing outside of viTmp at that time. Add
int i = viBrickWall[a][b];
assert(0 <= i && i < viTmp.size());
before the store to viTmp[i] = 3.
HINT: maybe increasing the size of viTmp by one would fix it:
-vector<int64_t> viTmp(iK-i);
+vector<int64_t> viTmp(iK - i + 1);
I don't know the content of viBrickWall so this is just an educated guess from the Valgrind output.
I'm not sure if you're using GNU libstdc++ or libc++ on Mac OSX. If you're using libstdc++ or have a Linux box handy, declare viTmp to be a std::__debug::vector would catch this problem quickly.