[gambit-list] New wiki page "Using Gambit with External Libraries"

Bradley Lucier lucier at math.purdue.edu
Thu Jul 3 17:54:28 EDT 2008


I'll answer your second question first.

> adamsonj at email.unc.edu (Joel J. Adamson) writes:
>
>> Given your explanation, me too; but can I get rid of the  
>> optimization?
>> It appears that's what was slowing my machine down.  Direct me to the
>> option for compile-file that controls optimization.
>
> Okay, I've found cc-options:, but I thought you were suggesting that
> certain options are always included.  Can you clarify this for me?

If you're on a linux or MacOS or *BSD or ... box you can see what  
command gsc uses to call gcc (including all options) by giving the  
following commands (I'm doing it on my MacOS box with a 64-bit  
compiled gambit):

> [descartes:~] lucier% ls -l `which gsc-cc-o.bat`
> -rwxr-xr-x   1 root  wheel  1140 Jul  2 12:08 /usr/local/Gambit-C/ 
> current/bin/gsc-cc-o.bat*
> [descartes:~] lucier% cat `which gsc-cc-o.bat`
> #! /bin/sh
>
> # Script parameters are passed in the following environment variables:
> #   GSC_CC_O_GAMBCDIR
> #   GSC_CC_O_OBJ_FILENAME
> #   GSC_CC_O_C_FILENAME_DIR
> #   GSC_CC_O_C_FILENAME_BASE
> #   GSC_CC_O_CC_OPTIONS
> #   GSC_CC_O_LD_OPTIONS_PRELUDE
> #   GSC_CC_O_LD_OPTIONS
>
> # echo GSC_CC_O_GAMBCDIR = "${GSC_CC_O_GAMBCDIR}"
> # echo GSC_CC_O_OBJ_FILENAME = "${GSC_CC_O_OBJ_FILENAME}"
> # echo GSC_CC_O_C_FILENAME_DIR = "${GSC_CC_O_C_FILENAME_DIR}"
> # echo GSC_CC_O_C_FILENAME_BASE = "${GSC_CC_O_C_FILENAME_BASE}"
> # echo GSC_CC_O_CC_OPTIONS = "${GSC_CC_O_CC_OPTIONS}"
> # echo GSC_CC_O_LD_OPTIONS_PRELUDE = "${GSC_CC_O_LD_OPTIONS_PRELUDE}"
> # echo GSC_CC_O_LD_OPTIONS = "${GSC_CC_O_LD_OPTIONS}"
>
> cd "${GSC_CC_O_C_FILENAME_DIR}"
>
> gcc -mcpu=970 -m64  -no-cpp-precomp -Wall -W -Wno-unused -O1 -fno- 
> math-errno -fschedule-insns2 -fno-trapping-math -fno-strict- 
> aliasing -fwrapv -fomit-frame-pointer -fPIC -fno-common -bundle - 
> flat_namespace -undefined suppress -I"${GSC_CC_O_GAMBCDIR}include" - 
> D___DYNAMIC -D___SINGLE_HOST -o "${GSC_CC_O_OBJ_FILENAME}" $ 
> {GSC_CC_O_CC_OPTIONS} ${GSC_CC_O_LD_OPTIONS_PRELUDE} "$ 
> {GSC_CC_O_C_FILENAME_BASE}" ${GSC_CC_O_LD_OPTIONS}

The gcc command-line options in your gcc-cc-o.bat are likely different.

All the gcc command options that come before

-o "${GSC_CC_O_OBJ_FILENAME}"

are always specified.

In the Gambit manual, the function compile-file is described as

> procedure: compile-file file [options: options] [output: output]  
> [cc-options: cc-options] [ld-options-prelude: ld-options-prelude]  
> [ld-options: ld-options]


OK.  Given the strings passed as arguments to compile-file, here is  
where they are inserted in the gcc command line in gsc-cc-o.bat:

cc-options gets placed into ${GSC_CC_O_CC_OPTIONS}
ld-options-prelude gets placed into ${GSC_CC_O_LD_OPTIONS_PRELUDE}
ld-options gets placed into ${GSC_CC_O_LD_OPTIONS}

These are the same options that can be passed to gsc on the command  
line.

Now for the first question:

On Jul 3, 2008, at 2:18 PM, Joel J. Adamson wrote:

>>
>> The main question is what you do with the .c file (that you almost
>> never see if you use "compile-file").  Do you try to compile it
>> yourself with gcc, and guess what the correct gcc options are on your
>> specific combination of machine and OS and gambit system for:
>> correctness, "sharedness" or non-sharedness (for lack of a better
>> term), 32-bit or 64-bit, setting ieee arithmetic, or whatever other
>> things could be screwed up on the gcc command line, and then use gcc
>> to link it (with the same questions), or do you want to trust gsc to
>> call gcc (or whatever your compiler is) to compile and link the files
>> for you with all the correct options, figured out automatically at
>> the time you configured gambit?
>>
>> I'd go with gsc doing it.
>
> Given your explanation, me too; but can I get rid of the optimization?
> It appears that's what was slowing my machine down.  Direct me to the
> option for compile-file that controls optimization.

First, I recommend that gambit be configured with the --enable-single- 
host option, which is nearly always a good idea.  (The only time I  
haven't used it is to build gambit on the OLPC XO machine, which I  
believe has 256 MB of memory.)  So I'm going to assume that you've  
configured gambit with --enable-single-host.

If your machine does not have the resources for gsc to compile a  
Scheme file with the default optimization level and with --enable- 
single-host, it is likely to be for one of three reasons:

1.  The file contains very large Scheme procedures or expressions (at  
least, they're very large after macro expansion and inlining); a good  
example of this is the file syntax-case.scm, installed in the Gambit  
"home" directory ~~.

2.  The file itself is large, and consists of a lot of separate  
smaller functions that don't call each other or otherwise interact; a  
good example of this would be a file that defines a lot of c-lambdas  
that allow Scheme programs to call C functions in some external library.

3.  The file itself is large, and consists of a lot of smaller  
functions that call each other a lot.

Here is how I would treat each situation.

1.  Pass "-O0" as cc-options.  This will override the other  
optimization options given earlier in the gcc command line (but will  
keep the options needed for correctness and other things).  Runtime  
performance will be lower, but for something like syntax-case, which  
is run when files are compiled, it's unlikely to matter.

Applying this idea to syntax-case.scm gives:

> [descartes:~/programs/gambc-v4_2_8/misc] lucier% time gsc syntax-case
> 371.444u 20.352s 6:43.29 97.1%  0+0k 23+53io 0pf+0w
> [descartes:~/programs/gambc-v4_2_8/misc] lucier% time gsc -cc- 
> options "-O0" syntax-case
> 78.764u 3.360s 1:24.34 97.3%    0+0k 0+44io 0pf+0w


And most of that 1:24.34 was actually taken up by the Scheme->C  
compilation, not the gcc compilation.

2.  Pass "-U___SINGLE_HOST" as cc-options. The --enable-single-host  
configuration option (which is what adds "-D___SINGLE_HOST" to the  
gcc command line in gsc-cc-o.bat) improves runtime performance only  
when a bunch of procedures in a single file call each other.  If  
that's not the case, e.g., in a file that just contains a lot of  
Scheme<->C glue for procedures in an external library, then you don't  
need --enable-single-host.

Here is an example of the effect of this option when compiling the  
Meroon object system source code (which consists of a lot of files  
that are *very* interrelated, but I needed an example):

> (time (compile-file "_meroon.scm"))
>     130226 ms real time
>     13632 ms cpu time (12983 user, 649 system)
>     36 collections accounting for 5163 ms real time (4808 user, 90  
> system)
>     1689799168 bytes allocated
>     no minor faults
>     no major faults
> (time (compile-file "_meroon.scm" cc-options: "-U___SINGLE_HOST"))
>     60636 ms real time
>     12653 ms cpu time (11928 user, 725 system)
>     17 collections accounting for 4944 ms real time (4677 user, 254  
> system)
>     1680932928 bytes allocated
>     no minor faults
>     no major faults


In each case the Scheme->C translation took around 13 seconds; the  
total compile time ("real time") with the default cc-options was 130  
seconds, and with -U___SINGLE_HOST was 61 seconds.

Just for an example, here's what happens when -O0 is added to cc- 
options:

> (time (compile-file "_meroon.scm" cc-options: "-O0"))
>     35558 ms real time
>     13356 ms cpu time (12731 user, 625 system)
>     36 collections accounting for 4900 ms real time (4731 user, 73  
> system)
>     1689800640 bytes allocated
>     no minor faults
>     no major faults
> (time (compile-file "_meroon.scm" cc-options: " -O0 - 
> U___SINGLE_HOST"))
>     27885 ms real time
>     12657 ms cpu time (11919 user, 738 system)
>     17 collections accounting for 4985 ms real time (4699 user, 257  
> system)
>     1680935072 bytes allocated
>     no minor faults
>     no major faults


Here is the runtime of the Meroon interp.scm benchmark when compiled  
with the four sets of options:

default:

> (time (start-bench))
>     363 ms real time
>     359 ms cpu time (315 user, 44 system)
>     1 collection accounting for 58 ms real time (28 user, 29 system)
>     7196816 bytes allocated
>     no minor faults
>     no major faults


With cc-options: "-U___SINGLE_HOST"

> (time (start-bench))
>     611 ms real time
>     609 ms cpu time (565 user, 44 system)
>     1 collection accounting for 57 ms real time (28 user, 29 system)
>     7196816 bytes allocated
>     no minor faults
>     no major faults


With cc-options: "-O0"

> (time (start-bench))
>     1163 ms real time
>     1153 ms cpu time (1105 user, 48 system)
>     1 collection accounting for 63 ms real time (30 user, 31 system)
>     7196816 bytes allocated
>     no minor faults
>     no major faults


With cc-options: " -O0 -U___SINGLE_HOST"

> (time (start-bench))
>     1642 ms real time
>     1633 ms cpu time (1585 user, 48 system)
>     1 collection accounting for 58 ms real time (28 user, 29 system)
>     7196816 bytes allocated
>     no minor faults
>     no major faults


So the default set of options for gcc gives a program that runs over  
4 times as fast as specifying " -O0 -U___SINGLE_HOST" on this example.

3.  Basically, in this situation, there's no standard suggestion  
about the best way to compile programs if you're concerned about  
runtime performance.  I'd try one of the cc-options given in part 2.





More information about the Gambit-list mailing list