version 1.203, 2009/02/20 19:32:09
|
version 1.204, 2009/04/22 10:38:30
|
Line 145 Gforth Environment
|
Line 145 Gforth Environment
|
* Environment variables:: that affect how Gforth starts up |
* Environment variables:: that affect how Gforth starts up |
* Gforth Files:: What gets installed and where |
* Gforth Files:: What gets installed and where |
* Gforth in pipes:: |
* Gforth in pipes:: |
* Startup speed:: When 35ms is not fast enough ... |
* Startup speed:: When 14ms is not fast enough ... |
|
|
Forth Tutorial |
Forth Tutorial |
|
|
Line 631 material in this chapter.
|
Line 631 material in this chapter.
|
* Environment variables:: that affect how Gforth starts up |
* Environment variables:: that affect how Gforth starts up |
* Gforth Files:: What gets installed and where |
* Gforth Files:: What gets installed and where |
* Gforth in pipes:: |
* Gforth in pipes:: |
* Startup speed:: When 35ms is not fast enough ... |
* Startup speed:: When 14ms is not fast enough ... |
@end menu |
@end menu |
|
|
For related information about the creation of images see @ref{Image Files}. |
For related information about the creation of images see @ref{Image Files}. |
Line 1139 Pipes involving Gforth's @code{stderr} o
|
Line 1139 Pipes involving Gforth's @code{stderr} o
|
@cindex speed, startup |
@cindex speed, startup |
|
|
If Gforth is used for CGI scripts or in shell scripts, its startup |
If Gforth is used for CGI scripts or in shell scripts, its startup |
speed may become a problem. On a 300MHz 21064a under Linux-2.2.13 with |
speed may become a problem. On a 3GHz Core 2 Duo E8400 under 64-bit |
glibc-2.0.7, @code{gforth -e bye} takes about 24.6ms user and 11.3ms |
Linux 2.6.27.8 with libc-2.7, @code{gforth-fast -e bye} takes 13.1ms |
system time. |
user and 1.2ms system time (@code{gforth -e bye} is faster on startup |
|
with about 3.4ms user time and 1.2ms system time, because it subsumes |
|
some of the options discussed below). |
|
|
If startup speed is a problem, you may consider the following ways to |
If startup speed is a problem, you may consider the following ways to |
improve it; or you may consider ways to reduce the number of startups |
improve it; or you may consider ways to reduce the number of startups |
(for example, by using Fast-CGI). |
(for example, by using Fast-CGI). Note that the first steps below |
|
improve the startup time at the cost of run-time (including |
|
compile-time), so whether they are profitable depends on the balance |
|
of these times in your application. |
|
|
|
An easy step that influences Gforth startup speed is the use of a |
|
number of options that increase run-time, but decrease image-loading |
|
time. |
|
|
|
The first of these that you should try is @code{--ss-number=0 |
|
--ss-states=1} because this option buys relatively little run-time |
|
speedup and costs quite a bit of time at startup. @code{gforth-fast |
|
--ss-number=0 --ss-states=1 -e bye} takes about 2.8ms user and 1.5ms |
|
system time. |
|
|
An easy step that influences Gforth startup speed is the use of the |
The next option is @code{--no-dynamic} which has a substantial impact |
@option{--no-dynamic} option; this decreases image loading speed, but |
on run-time (about a factor of 2 on several platforms), but still |
increases compile-time and run-time. |
makes startup speed a little faster: @code{gforth-fast --ss-number=0 |
|
--ss-states=1 --no-dynamic -e bye} consumes about 2.6ms user and 1.2ms |
Another step to improve startup speed is to statically link Gforth, by |
system time. |
building it with @code{XLDFLAGS=-static}. This requires more memory for |
|
the code and will therefore slow down the first invocation, but |
The next step to improve startup speed is to use a data-relocatable |
subsequent invocations avoid the dynamic linking overhead. Another |
image (@pxref{Data-Relocatable Image Files}). This avoids the |
disadvantage is that Gforth won't profit from library upgrades. As a |
relocation cost for the code in the image (but not for the data). |
result, @code{gforth-static -e bye} takes about 17.1ms user and |
Note that the image is then specific to the particular binary you are |
8.2ms system time. |
using (i.e., whether it is @code{gforth}, @code{gforth-fast}, and even |
|
the particular build). You create the data-relocatable image that |
The next step to improve startup speed is to use a non-relocatable image |
works with @code{./gforth-fast} with @code{GFORTHD="./gforth-fast |
(@pxref{Non-Relocatable Image Files}). You can create this image with |
--no-dynamic" gforthmi gforthdr.fi} (the @code{--no-dynamic} is |
@code{gforth -e "savesystem gforthnr.fi bye"} and later use it with |
required here or the image will not work). And you run it with |
@code{gforth -i gforthnr.fi ...}. This avoids the relocation overhead |
@code{gforth-fast -i gforthdr.fi ... -e bye} (the flags discussed |
and a part of the copy-on-write overhead. The disadvantage is that the |
above don't matter here, because they only come into play on |
non-relocatable image does not work if the OS gives Gforth a different |
relocatable code). @code{gforth-fast -i gforthdr.fi -e bye} takes |
address for the dictionary, for whatever reason; so you better provide a |
about 1.1ms user and 1.2ms system time. |
fallback on a relocatable image. @code{gforth-static -i gforthnr.fi -e |
|
bye} takes about 15.3ms user and 7.5ms system time. |
One step further is to avoid all relocation cost and part of the |
|
copy-on-write cost through using a non-relocatable image |
The final step is to disable dictionary hashing in Gforth. Gforth |
(@pxref{Non-Relocatable Image Files}). However, this has the |
builds the hash table on startup, which takes much of the startup |
disadvantage that it does not work on operating systems with address |
overhead. You can do this by commenting out the @code{include hash.fs} |
space randomization (the default in, e.g., Linux nowadays), or if the |
in @file{startup.fs} and everything that requires @file{hash.fs} (at the |
dictionary moves for any other reason (e.g., because of a change of |
moment @file{table.fs} and @file{ekey.fs}) and then doing @code{make}. |
the OS kernel or an updated library), so we cannot really recommend |
The disadvantages are that functionality like @code{table} and |
it. You create a non-relocatable image with @code{gforth-fast |
@code{ekey} is missing and that text interpretation (e.g., compiling) |
--no-dynamic -e "savesystem gforthnr.fi bye"} (the @code{--no-dynamic} |
now takes much longer. So, you should only use this method if there is |
is required here, too). And you run it with @code{gforth-fast -i |
no significant text interpretation to perform (the script should be |
gforthnr.fi ... -e bye} (again the flags discussed above don't |
compiled into the image, amongst other things). @code{gforth-static -i |
matter). @code{gforth-fast -i gforthdr.fi -e bye} takes |
gforthnrnh.fi -e bye} takes about 2.1ms user and 6.1ms system time. |
about 0.9ms user and 0.9ms system time. |
|
|
|
If the script you want to execute contains a significant amount of |
|
code, it may be profitable to compile it into the image to avoid the |
|
cost of compiling it at startup time. |
|
|
@c ****************************************************************** |
@c ****************************************************************** |
@node Tutorial, Introduction, Gforth Environment, Top |
@node Tutorial, Introduction, Gforth Environment, Top |
Line 15093 addresses, then sets up the memory (stac
|
Line 15112 addresses, then sets up the memory (stac
|
information in the image file, and (finally) starts executing Forth |
information in the image file, and (finally) starts executing Forth |
code. |
code. |
|
|
The image file variants represent different compromises between the |
The default image file is @file{gforth.fi} (in the @code{GFORTHPATH}). |
goals of making it easy to generate image files and making them |
You can use a different image by using the @code{-i}, |
portable. |
@code{--image-file} or @code{--appl-image} options (@pxref{Invoking |
|
Gforth}), e.g.: |
|
|
|
@example |
|
gforth-fast -i myimage.fi |
|
@end example |
|
|
|
There are different variants of image files, and they represent |
|
different compromises between the goals of making it easy to generate |
|
image files and making them portable. |
|
|
@cindex relocation at run-time |
@cindex relocation at run-time |
Win32Forth 3.4 and Mitch Bradley's @code{cforth} use relocation at |
Win32Forth 3.4 and Mitch Bradley's @code{cforth} use relocation at |
run-time. This avoids many of the complications discussed below (image |
run-time. This avoids many of the complications discussed below (image |
files are data relocatable without further ado), but costs performance |
files are data relocatable without further ado), but costs performance |
(one addition per memory access). |
(one addition per memory access) and makes it difficult to pass |
|
addresses between Forth and library calls or other programs. |
|
|
@cindex relocation at load-time |
@cindex relocation at load-time |
By contrast, the Gforth loader performs relocation at image load time. The |
By contrast, the Gforth loader performs relocation at image load time. The |
Line 15133 with code addresses or with pieces of ma
|
Line 15162 with code addresses or with pieces of ma
|
If any complex computations involving addresses are performed, the |
If any complex computations involving addresses are performed, the |
results cannot be represented in the image file. Several applications that |
results cannot be represented in the image file. Several applications that |
use such computations come to mind: |
use such computations come to mind: |
|
|
@itemize @minus |
@itemize @minus |
@item |
@item |
Hashing addresses (or data structures which contain addresses) for table |
Hashing addresses (or data structures which contain addresses) for table |
Line 15171 a place where it is stored in a non-mang
|
Line 15201 a place where it is stored in a non-mang
|
@cindex non-relocatable image files |
@cindex non-relocatable image files |
@cindex image file, non-relocatable |
@cindex image file, non-relocatable |
|
|
These files are simple memory dumps of the dictionary. They are specific |
These files are simple memory dumps of the dictionary. They are |
to the executable (i.e., @file{gforth} file) they were created |
specific to the executable (i.e., @file{gforth} file) they were |
with. What's worse, they are specific to the place on which the |
created with. What's worse, they are specific to the place on which |
dictionary resided when the image was created. Now, there is no |
the dictionary resided when the image was created. Now, there is no |
guarantee that the dictionary will reside at the same place the next |
guarantee that the dictionary will reside at the same place the next |
time you start Gforth, so there's no guarantee that a non-relocatable |
time you start Gforth, so there's no guarantee that a non-relocatable |
image will work the next time (Gforth will complain instead of crashing, |
image will work the next time (Gforth will complain instead of |
though). |
crashing, though). Indeed, on OSs with (enabled) address-space |
|
randomization non-relocatable images are unlikely to work. |
|
|
You can create a non-relocatable image file with |
You can create a non-relocatable image file with @code{savesystem}, e.g.: |
|
|
|
@example |
|
gforth app.fs -e "savesystem app.fi bye" |
|
@end example |
|
|
doc-savesystem |
doc-savesystem |
|
|
Line 15191 doc-savesystem
|
Line 15225 doc-savesystem
|
@cindex data-relocatable image files |
@cindex data-relocatable image files |
@cindex image file, data-relocatable |
@cindex image file, data-relocatable |
|
|
These files contain relocatable data addresses, but fixed code addresses |
These files contain relocatable data addresses, but fixed code |
(instead of tokens). They are specific to the executable (i.e., |
addresses (instead of tokens). They are specific to the executable |
@file{gforth} file) they were created with. For direct threading on some |
(i.e., @file{gforth} file) they were created with. Also, they disable |
architectures (e.g., the i386), data-relocatable images do not work. You |
dynamic native code generation (typically a factor of 2 in speed). |
get a data-relocatable image, if you use @file{gforthmi} with a |
You get a data-relocatable image, if you pass the engine you want to |
Gforth binary that is not doubly indirect threaded (@pxref{Fully |
use through the @code{GFORTHD} environment variable to @file{gforthmi} |
Relocatable Image Files}). |
(@pxref{gforthmi}), e.g. |
|
|
|
@example |
|
GFORTHD="/usr/bin/gforth-fast --no-dynamic" gforthmi myimage.fi source.fs |
|
@end example |
|
|
|
Note that the @code{--no-dynamic} is required here for the image to |
|
work (otherwise it will contain references to dynamically generated |
|
code that is not saved in the image). |
|
|
|
|
@node Fully Relocatable Image Files, Stack and Dictionary Sizes, Data-Relocatable Image Files, Image Files |
@node Fully Relocatable Image Files, Stack and Dictionary Sizes, Data-Relocatable Image Files, Image Files |
@section Fully Relocatable Image Files |
@section Fully Relocatable Image Files |
Line 15209 Relocatable Image Files}).
|
Line 15252 Relocatable Image Files}).
|
These image files have relocatable data addresses, and tokens for code |
These image files have relocatable data addresses, and tokens for code |
addresses. They can be used with different binaries (e.g., with and |
addresses. They can be used with different binaries (e.g., with and |
without debugging) on the same machine, and even across machines with |
without debugging) on the same machine, and even across machines with |
the same data formats (byte order, cell size, floating point |
the same data formats (byte order, cell size, floating point format), |
format). However, they are usually specific to the version of Gforth |
and they work with dynamic native code generation. However, they are |
they were created with. The files @file{gforth.fi} and @file{kernl*.fi} |
usually specific to the version of Gforth they were created with. The |
are fully relocatable. |
files @file{gforth.fi} and @file{kernl*.fi} are fully relocatable. |
|
|
There are two ways to create a fully relocatable image file: |
There are two ways to create a fully relocatable image file: |
|
|
Line 15279 instructions.
|
Line 15322 instructions.
|
@cindex @code{GFORTH} -- environment variable |
@cindex @code{GFORTH} -- environment variable |
@cindex @code{gforth-ditc} |
@cindex @code{gforth-ditc} |
There are a few wrinkles: After processing the passed @i{options}, the |
There are a few wrinkles: After processing the passed @i{options}, the |
words @code{savesystem} and @code{bye} must be visible. A special doubly |
words @code{savesystem} and @code{bye} must be visible. A special |
indirect threaded version of the @file{gforth} executable is used for |
doubly indirect threaded version of the @file{gforth} executable is |
creating the non-relocatable images; you can pass the exact filename of |
used for creating the non-relocatable images; you can pass the exact |
this executable through the environment variable @code{GFORTHD} |
filename of this executable through the environment variable |
(default: @file{gforth-ditc}); if you pass a version that is not doubly |
@code{GFORTHD} (default: @file{gforth-ditc}); if you pass a version |
indirect threaded, you will not get a fully relocatable image, but a |
that is not doubly indirect threaded, you will not get a fully |
data-relocatable image (because there is no code address offset). The |
relocatable image, but a data-relocatable image |
normal @file{gforth} executable is used for creating the relocatable |
(@pxref{Data-Relocatable Image Files}), because there is no code |
image; you can pass the exact filename of this executable through the |
address offset). The normal @file{gforth} executable is used for |
environment variable @code{GFORTH}. |
creating the relocatable image; you can pass the exact filename of |
|
this executable through the environment variable @code{GFORTH}. |
|
|
@node cross.fs, , gforthmi, Fully Relocatable Image Files |
@node cross.fs, , gforthmi, Fully Relocatable Image Files |
@subsection @file{cross.fs} |
@subsection @file{cross.fs} |