Profiling

Author(s): The Ciao Development Team.

Stability: [devel] Currently the subject of active development and/or research. Functionality may be limited and API and/or functionality may change without warning or deprecation period. Not recommended yet for use in production.


This module provides a simple Prolog-level interface for the built-in profiler. This is a basic, relatively low overhead profiler, which can be used to determine call counts, times, etc. per predicate when executing a goal or an executable. There exist bundles with other, more complex profilers, but which may have higher overhead.

Enabling profiling

The profiling instrumentation is disabled in the default engine to avoid overhead when not needed. Thus, in order to be able to use the profiler the engine must be recompiled with the debug_level option set to profile.

For example, after having built and installed Ciao normally (which builds the standard engine) you can do:

./ciao-boot.sh configure --set-flag core:debug_level=profile
./ciao-boot.sh build core.engine
./ciao-boot.sh configure --set-flag core:debug_level=nodebug

This will build the engine with profiling and leave the configuration back to normal, now with both the standard and the profiling engines compiled.

Profiling calls or executions

Once the standard and profiling engines are compiled you can select between these engine versions by setting the CIAODBG environment variable before starting the top level or compiled application. E.g., for bash-style shells:

$ CIAODBG=profile ciaosh
Ciao 1.23 (2024-07-21 11:08:37 +0200) [DARWINx86_64] [profile]
?-

You can then load this module and issue the commands it provides:

?- use_module(library(profile)).
yes
?- use_module('core/examples/general/nqueens').

yes
?- profile(queens(15,Q),[calls,roughtime]).

Q = [8,5,9,1,10,7,3,12,2,4,6,14,11,13,15] ? 

yes
?- print_profile.
{profile: dump saved in /tmp/ciao__profile.txt}

Profile information:
25 predicates called, 55596 calls made, 0.02 secs. accumulated time
Calls            Time (rough)            Type    Spec
=====            ============            ====    ====
38644 (69.51%)   0.015135 (70.18%)       Emul    nqueens:no_attack_2/3
8442 (15.18%)    0.003347 (15.52%)       Emul    nqueens:sel/3
7098 (12.77%)    0.002481 (11.50%)       Emul    nqueens:no_attack/2
1360 (2.45%)     0.000547 (2.54%)        Emul    nqueens:queens_2/3
16 (0.03%)       0.000014 (0.06%)        Emul    nqueens:queens_list/2
4 (0.01%)        0.000007 (0.03%)        Built   hiord_rt:call/1
3 (0.01%)        0.000004 (0.02%)        Emul    internals:rt_module_exp/6/0$$33/4
3 (0.01%)        0.000003 (0.01%)        C       internals:$global_vars_get_root/1
...
1 (0.00%)        0.000001 (0.00%)        Emul    nqueens:queens/2

You can also profile a whole compiled program. You can use the CIAORTOPTS environment variable to pass engine options such as --profile-calls and --profile-roughtime. This example executes ciaopp performing analysis on file guardians.pl with call and time profiling, printing the profiling results at the end:

$ cd core/examples/general
$ CIAODBG=profile CIAORTOPTS="--profile-calls --profile-roughtime" ciaopp -A guardians.pl

Usage and interface

Documentation on exports

X is a profiler option:
  • calls: count number of calls per predicate
  • roughtime: rough approximation of execution time (since the predicate is called until the next one is called)

Usage:profile_opt(X)

X is a profiler option.

    PREDICATEprofile/2

    Usage:profile(G,Opts)

    Profile execution of G (as with once/1)

    Meta-predicate with arguments: profile(goal,?).

    PREDICATEprofile/1

    Usage:profile(G)

    Profile execution of G (as with once/1) with default options (calls)

      Meta-predicate with arguments: profile(goal).

      Usage:

      Outputs an ascii printout of the profiling results through standard_user, and also leaves the result in a file in a temporary directory (reporting the name and location of the dump file).

        Documentation on imports

        This module has the following direct dependencies: