How can you profile compiled code?

15

7

Is it possible to profile compiled code? I am using Workbench 2.0 and the Profile[] command but I do not get a profile of my compiled function.

I apologize if the answer is readily available but I could not find it Workbench documentation nor using Google.

shoda

Posted 2013-01-21T16:35:33.780

Reputation: 253

2I don't think it is, you could try to export your code to C and use another tool for this, but as the variables are renamed during the export, this wouldn't be practical ... – faysou – 2013-01-21T16:42:06.067

3@FaysalAberkane It is possible to intercept generated symbolic C code for functions compiled to C. It should then be possible to write some code analyzer in Mathematica which would connect Mathematica variables and those used in a C program, although such a connection may not always be meaningful. – Leonid Shifrin – 2013-01-21T16:54:29.887

1Link to MathGroup version – Szabolcs – 2013-01-22T03:39:12.633

Answers

13

Before doing any optimizations by using a profiler you should have a look at what your compiled function looks like by using CompilePrint to inspect that the compiled code has not calls to MainEvaluate:

Needs["CompiledFunctionTools`"]
c = Compile[{{x}}, x^2 + Sin[x^2]];
CompilePrint[c]

From my expirience callbacks to MainEvaluate are the main source of slow compiled functions, like here:

Needs["CompiledFunctionTools`"]
f[x_] := x^2 + Sin[x^2]
c = Compile[{{x}}, f[x]];
CompilePrint[c]

Having said that here is an approach to profile a compiled function by converting it to a C code. Never used this myself, so I am not sure how useful this is.

The example is a modification from the ref/LiftingFilterData reference page (Applications).

Generate and export some code:

Needs["CompiledFunctionTools`"]
Needs["CCompilerDriver`"];
Needs["SymbolicC`"];
Needs["CCodeGenerator`"];

lf = WaveletFilterCoefficients[DaubechiesWavelet[2], 
   "LiftingFilter"];
lfunc = lf["ForwardLiftingFunction", Compiled -> True];

(* you may need to create the directory *)    
outdir = $CCompilerDefaultDirectory;
flwt = Export[FileNameJoin[{outdir, "flwt.c"}], 
   CCodeStringGenerate[lfunc, "flwt"], "Text"];

Generate a header file and an example main:

Export[FileNameJoin[{outdir, "flwt.h"}], 
  CCodeStringGenerate[lfunc, "flwt", 
   "CodeTarget" -> "WolframRTLHeader"], "Text"];
flwtmain = "ExampleData/flwtmain.c";

Create the executable (with the profiling option -pg - not sure what it is on windows):

exe = CreateExecutable[{flwt, flwtmain}, "flwt.exe", 
  "Libraries" -> "WolframRTL_Static_Minimal", 
  "CompileOptions" -> "-pg", "ShellCommandFunction" -> Print]

Create some data and export that too:

data = N[Sin[Range[10]]];
Export[FileNameJoin[{outdir, "data.txt"}], Join[{Length[data]}, data],
   "Text"];

Now, in outdir you should have a flwt.exe. To profile it use something like

valgrind --tool=callgrind ./flwt.exe

from the shell command. Note that gprof is not good here, since that can not profile into shared libraries. Then you can analyze and visualize the calling via:

kcachegrind

Not sure if this is maybe not too involved to get a profile of a compiled function, but to some degree it is possible. Hope this helps.

user21

Posted 2013-01-21T16:35:33.780

Reputation: