Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Application benchmark suite available

40 views
Skip to first unread message

Anton Ertl

unread,
Aug 29, 2009, 6:44:21 PM8/29/09
to
At long last I finally got around to putting the application
benchmarks that I tend to use for performance evaluations in one
package. I hope that this will raise the level of benchmarking in the
Forth community from the usual toy benchmarks (with non-representative
performance); another effect I hope for is an increase in the
usability of Forth systems out of the box.

To whet your appetite, here are results (in seconds user time on a
3GHz Xeon 5450) for four systems on one benchmark (three runs per
system and benchmark):

for FORTH in "bigforth -m 16M -e " \
~/"xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M ../setup-gforth.fs -e " \
iforth \
vfxlin; do
echo `BENCH=cd16sim ./run` "$FORTH"; done
[9.997 10.001 10.013 ] cd16sim bigforth -m 16M -e
[2.768 2.776 2.776 ] cd16sim /nfs/a5/anton/xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M ../setup-gforth.fs -e
[0.392 0.404 0.404 ] cd16sim iforth
[0.508 0.512 0.516 ] cd16sim vfxlin

You can download the package from
http://www.complang.tuwien.ac.at/forth/appbench-1.0.zip


And here's the README:

This is a set of Forth application benchmarks, in contrast to the
small benchmarks that are usually used for benchmarking Forth systems.

Most of these applications (except cross and vmgen, which are not run
by default) should be portable between Forth systems, but a test with
Gforth (several versions), bigForth 2.1.6, iforth 2.1.2541, and vfxlin
4.05 Alpha 8 [build 0207] showed the following systems to be working:

Benchmark Systems
benchgc gforth iforth
brainless gforth
brew gforth
cd16sim bigforth gforth iforth vfxlin
fcp bigforth gforth
lexex gforth vfxlin

That's with most systems out of the box, but a little more effort for
Gforth (otherwise gforth-0.7.0 would not have worked for fcp, and the
output would contain warnings). It may be easy for knowledgeable
users to enable options in the systems to make them work with more
benchmarks, though.


HOW TO RUN THE BENCHMARKS

There is a bash script "run" that makes it easy. cd into the
appbench-1.0 directory, then say, e.g.:

BENCH="cd16sim lexex" FORTH=vfxlin ./run

and after a while you will see output like:

[0.500 0.500 0.512 ] cd16sim
[4.040 4.048 4.052 ] lexex

These are the user time from three runs of the benchmarks; the results
for one benchmark are sorted to make it easier to see or compute the
median. The standard output of the benchmarks is suppressed. To make
it easier to see what's going on, there is also another script "test"
that performs only one run and shows the standard output. Use it,
e.g., like this:

BENCH="cd16sim lexex" FORTH=vfxlin ./test

In my testing I used the following variants for the FORTH variable:

FORTH="bigforth -d 16M -e "
FORTH="gforth-fast -m 16M ../setup-gforth.fs -e " #default
FORTH="iforth"
FORTH="vfxlin"

The benchmark names possible in BENCH are:

BENCH="benchgc brainless brew cd16sim fcp lexex cross vmgen"

The default is all but cross and vmgen.

You can change the number of runs by setting RUNS:

RUNS=5 BENCH="cd16sim lexex" FORTH=vfxlin ./run

The default number of RUNS is 3.

You can also change the command used for timing by setting TIME, but
that command should produce only a single number on stderr as output.
The default is TIME, and the TIMEFORMAT="%U" per default to report
only user time.


DOWNLOADING AND INSTALLING

You can download this package from
http://www.complang.tuwien.ac.at/forth/appbench.zip

Just unpack it anywhere, then cd into the appbench-1.0 directory and
benchmark away.


ABOUT THE BENCHMARKS

Benchmark Author Purpose, Remarks
bench-gc 1.0 Anton Ertl Garbage Collector
brainless 0.0.2 David Kuehling Chess, different results for 32-bit and 64-bit systems
brew 0.2.0 Robert Epprecht Evolutionary playground, incorrect on 64-bit
cd16sim v11 Brad Eckert CPU emulator
cross 0.7.x Bernd Paysan Forth cross compiler, Gforth only, short run, unstable
fcp 1.31-64 Ian Osgood Chess
lexex Gerry Jackson Scanner Generator
vmgen 0.7.x Anton Ertl Interpreter generator, Gforth-only, short run

If you want to see how the benchmarks are invoked on the Forth level,
look into the file benchstrings.


ACKNOWLEDGMENTS

Thanks to all the authors of the applications that serve here as
benchmark for making them available and portable.


FEEDBACK

If you have any feedback (problem reports, fixes, new benchmarks
etc.), you can contact me by email at
an...@mips.complang.tuwien.ac.at.

Anton Ertl
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2009: http://www.euroforth.org/ef09/

Anton Ertl

unread,
Aug 30, 2009, 10:35:11 AM8/30/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>To whet your appetite, here are results (in seconds user time on a
>3GHz Xeon 5450) for four systems on one benchmark (three runs per
>system and benchmark):

I need to do the following first:

export FORTH

>for FORTH in "bigforth -m 16M -e " \
> ~/"xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M ../setup-gforth.fs -e " \
> iforth \
> vfxlin; do
> echo `BENCH=cd16sim ./run` "$FORTH"; done
>[9.997 10.001 10.013 ] cd16sim bigforth -m 16M -e
>[2.768 2.776 2.776 ] cd16sim /nfs/a5/anton/xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M ../setup-gforth.fs -e
>[0.392 0.404 0.404 ] cd16sim iforth
>[0.508 0.512 0.516 ] cd16sim vfxlin

Another result for the same benchmark on a 2GHz Opteron 270 box
where a newer version of vfxlin (4.30 RC1 [build 0324]) is installed:

[27.954 28.054 35.942 ] cd16sim bigforth -m 16M -e
[5.992 6.000 6.008 ] cd16sim /nfs/a5/anton/xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M ../setup-gforth.fs -e
[0.840 0.840 0.844 ] cd16sim iforth
[0.792 0.808 0.912 ] cd16sim vfxlin

>Most of these applications (except cross and vmgen, which are not run
>by default) should be portable between Forth systems, but a test with
>Gforth (several versions), bigForth 2.1.6, iforth 2.1.2541, and vfxlin
>4.05 Alpha 8 [build 0207] showed the following systems to be working:
>
>Benchmark Systems
>benchgc gforth iforth
>brainless gforth
>brew gforth
>cd16sim bigforth gforth iforth vfxlin
>fcp bigforth gforth
>lexex gforth vfxlin

The newer version of vfxlin did not change anything here.

- anton

Gerry

unread,
Aug 30, 2009, 12:33:42 PM8/30/09
to
Anton Ertl wrote:
[...]

Yes, the lexex benchmark will work with bigforth 2.2.0 (under Windows
XP at least) if the default dataspace and return stack sizes are
increased e.g. by starting bigforth with:
bigforth.exe -d 4M -r 8k ...

Not having access to an iforth system I've no idea why that fails. As
lexex works with several other systems perhaps it's a system resource
problem too.

Gerry


Anton Ertl

unread,
Aug 30, 2009, 1:13:19 PM8/30/09
to
"Gerry" <ge...@jackson9000.fsnet.co.uk> writes:

Yes, that also helped brainless, so now the table looks like:

Benchmark Systems
benchgc gforth iforth

brainless bigforth gforth


brew gforth
cd16sim bigforth gforth iforth vfxlin
fcp bigforth gforth

lexex bigforth gforth vfxlin

I need to find out how to load FALIGNED to make benchgc work with
bigForth. The failure of brew is mysterious.

>Not having access to an iforth system I've no idea why that fails.

I have access, but I have no idea, either. I only see:

executing /dfwforth/include/iforth.prf
Creating ��� Several utilities Version 3.07 ���
Creating ��� Extended OS words Version 3.16 ���
Creating ��� Terminal Driver Version 3.12 ���
Creating ��� Command line Editor Version 1.28 ���
Creating ��� Online help Version 1.34 ���
Creating ��� Glossary Generator Version 1.05 ���
Creating ��� Disassembler Version 2.20 ��� Loading run.fth ...
Loading extended mini oof ...
Extended mini oof loaded.
Data: ---
System: ---
Float: ---Loading Sets.fth ...
Sets.fth loaded.
Data: ---
System: ---
Float: ---Loading ShellSort.fth...
ShellSort.fth loaded.
Data: ---
System: ---
Float: ---Loading SyntaxTree.fth ...

Redefining cellSyntaxTree.fth loaded.
Data: ---
System: ---
Float: ---Loading TransitionTable.fth ...
TransitionTable.fth loaded.
Data: ---
System: ---
Float: ---Loading LexArrays.fth...

**** STACK DUMP ****
1darray (+$00000061)
$00000000 (0)
HEAD>exec (+$000009F5)
$00000000 (0)
$0809D41C (134861852)
$00000028 (40)
?STACK (+$0000017C)
ERROR>TEXT (+$0000011C)
$00000000 (0)
$0000001A (26)
**** STACK DUMP ****
INCLUDED (+$00000052)
$THROW (+$00000107)
?STACK (+$0000017C)
ERROR>TEXT (+$0000011C)
$00000000 (0)
$00000023 (35)
$00000027 (39)
$083A7C00 (138050560)
$00000000 (0)
$00000000 (0)
iForth version 2.1.2541, generated 00:39:42, January 28, 2007.
i6 binary, native floating-point, double precision.
Copyright 1996 - 2007 Marcel Hendrix.

>As
>lexex works with several other systems perhaps it's a system resource
>problem too.

If so, I am not familiar enough with iForth to try different sizes.

- anton

Gerry

unread,
Aug 30, 2009, 2:03:00 PM8/30/09
to
Anton Ertl wrote:
> "Gerry" <ge...@jackson9000.fsnet.co.uk> writes:
>> Anton Ertl wrote:

[...]

This indicates that iForth never finished compiling the file
LexArrays.fth so it's unlikely to be a system resource problem.

If the reference to 1darray in the first stack dump is an indication
of what failed it could be due to this bit of code which defines and
creates a data structure that will point to an array:of cells.

: 1darray
does> ( i -- ad )
2@ >r ( -- i n ) ( R: -- ad1 ) \ ad1 of
array[0]
over 0 rot within ( -- i f )
0= abort" Index to tokens array out of range"
cells r> + ( -- ad )
;

create lex_tokens 0 , 0 , 1darray

Is there anything wrong with this?

[...]

Gerry


Bernd Paysan

unread,
Aug 30, 2009, 3:06:46 PM8/30/09
to
Anton Ertl wrote:
> for FORTH in "bigforth -m 16M -e " \
> ~/"xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M
> ../setup-gforth.fs -e " \ iforth \
> vfxlin; do
> echo `BENCH=cd16sim ./run` "$FORTH"; done
> [9.997 10.001 10.013 ] cd16sim bigforth -m 16M -e
> [2.768 2.776 2.776 ] cd16sim
> [/nfs/a5/anton/xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M
> [../setup-gforth.fs -e 0.392 0.404 0.404 ] cd16sim iforth 0.508 0.512
> [0.516 ] cd16sim vfxlin

Looks like these applications have severe data/code problems. I have
occasionally, in the worst case, the speed of an application can go down
by a factor of 50. Looks like I have to add some code/data space
separation in bigForth, as well (VFX and iForth already do), just for
benchmark reasons. If you don't put all variables close to the code
that uses them, you won't suffer from that problem.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/

Anton Ertl

unread,
Aug 30, 2009, 3:07:26 PM8/30/09
to

Looks fine, and it works interactively. However, typing something
more finally gives an error message:

[-3]FORTH> ok
[-3]FORTH> ok
[-3]FORTH> 1
Thrown out of `lexarrays.fth'
Error -4 in line #419 at nesting level 1
underflow ?

-4 is probably a stack underflow, as also indicated by the "[-3]".

Line #419 contains:

: getToken ( state -- tok ) lex_tokens @ ;

and if I add that interactively, I get:

FORTH> : 1darray
<3>[FORTH>] does> ( i -- ad )
<3>[FORTH>] 2@ >r ( -- i n ) ( R: -- ad1 ) \ ad1 of
<3>[FORTH>] over 0 rot within ( -- i f )
<3>[FORTH>] 0= abort" Index to tokens array out of range"
<3>[FORTH>] cells r> + ( -- ad )
<3>[FORTH>] ; ok
FORTH> ok
FORTH> create lex_tokens 0 , 0 , 1darray ok
FORTH> : getToken ( state -- tok ) lex_tokens @ ;

**** STACK DUMP ****
1darray (+$00000061)
$00000000 (0)
HEAD>exec (+$000009F5)
$00000000 (0)
$0809D41C (134861852)

Error -2
Index to tokens array out of range ?

This seems strange, given that lex_tokens is not immediate. Maybe an
iForth bug?

Anton Ertl

unread,
Aug 30, 2009, 3:18:00 PM8/30/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>This seems strange, given that lex_tokens is not immediate. Maybe an
>iForth bug?

A very simple test case:

: foo does> ." x" ; create bar foo : flip bar ;

This outputs "x" and pushes a value on the stack; moreover, performin
FLIP later does not output x, so it looks like BAR is treated as
immediate. Looks very much like an iForth bug to me. Maybe Marcel
has already fixed it, the version I have is pretty old.

Anton Ertl

unread,
Aug 30, 2009, 3:22:28 PM8/30/09
to
Bernd Paysan <bernd....@gmx.de> writes:
>Anton Ertl wrote:
>> for FORTH in "bigforth -m 16M -e " \
>> ~/"xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M
>> ../setup-gforth.fs -e " \ iforth \
>> vfxlin; do
>> echo `BENCH=cd16sim ./run` "$FORTH"; done
>> [9.997 10.001 10.013 ] cd16sim bigforth -m 16M -e
>> [2.768 2.776 2.776 ] cd16sim
>> [/nfs/a5/anton/xxxgforthbench/ia32/gcc-2.95/gforth-fast-0.7.0 -m 16M
>> [../setup-gforth.fs -e 0.392 0.404 0.404 ] cd16sim iforth 0.508 0.512
>> [0.516 ] cd16sim vfxlin
>
>Looks like these applications have severe data/code problems.

One could also say the bigForth has severe data/code problems:-)

>I have
>occasionally, in the worst case, the speed of an application can go down
>by a factor of 50. Looks like I have to add some code/data space
>separation in bigForth, as well (VFX and iForth already do)

And Gforth as well. After all, this issue has been known for more
than a decade.

>just for
>benchmark reasons.

Well, why did you do native code in the first place?

>If you don't put all variables close to the code
>that uses them, you won't suffer from that problem.

The question is who should not put the variables close to the code?
IMO it's the compiler.

- anton

ygrek

unread,
Aug 30, 2009, 3:26:20 PM8/30/09
to

Neat. Thanks for putting this up.

CPU : Intel(R) Celeron(R) CPU 3.20GHz

[2.408 2.420 2.432 ] cd16sim spf ../setup-spf.f
[22.309 22.321 22.489 ] cd16sim gforth-fast -m 16M ../setup-gforth.fs -e
[0.788 0.800 0.808 ] cd16sim vfxlin

Versions:
SP-Forth 4.20
gforth 0.6.2-7.3 (Debian package)
vfxlin 4.40 RC1 [build 0339]

SP-Forth notes:
All benchmarks except for cd16sim failed for various reasons - will
investigate later.
setup-spf.f contains:

: INCLUDE ;

lib/include/defer.f \ DEFER
lib/ext/case.f \ CASE
lib/include/facil.f \ TIME&DATE
lib/include/string.f \ /STRING
lib/include/core-ext.f \ 0>
lib/include/double.f \ 2CONSTANT
lib/include/float.f
lib/ext/caseins.f

: bounds OVER + SWAP ;


PS (to MPE people): VFX deb repository is unusable.

--
ygrek

ygrek

unread,
Aug 30, 2009, 3:48:02 PM8/30/09
to
Sun, 30 Aug 2009 19:26:20 +0000, ygrek wrote:

> CPU : Intel(R) Celeron(R) CPU 3.20GHz
>
> [2.408 2.420 2.432 ] cd16sim spf ../setup-spf.f
> [22.309 22.321 22.489 ] cd16sim gforth-fast -m 16M ../setup-gforth.fs -e
> [0.788 0.800 0.808 ] cd16sim vfxlin
>
> Versions:
> SP-Forth 4.20
> gforth 0.6.2-7.3 (Debian package)
> vfxlin 4.40 RC1 [build 0339]

[3.080 3.088 3.104 ] fcp spf ../setup-spf.f
[15.885 15.909 15.913 ] fcp gforth-fast -m 16M ../setup-gforth.fs -e

--
ygrek

Anton Ertl

unread,
Aug 30, 2009, 3:49:49 PM8/30/09
to
ygrek <yg...@forth.org.ru> writes:
>SP-Forth 4.20

I see there's a .deb package now. However, when I tried to run
cd16sim, I ran across the following:

[c7:~/forth/appbench-1.0:24482] FORTH="spf4 ../setup/spf.f" BENCH=cd16sim ./test
spf4 ../setup/spf.f
Exception #2 at: /usr/lib/spforth4/lib/ext/caseins-tools.f:1:49:
REQUIRE CHAR-UPPERCASE ~ac/lib/string/uppercase.f
^ ERROR #-2003

Looks like there is an path to some user's directory there.

- anton

Marcel Hendrix

unread,
Aug 30, 2009, 4:00:44 PM8/30/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: Application benchmark suite available

> an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>> This seems strange, given that lex_tokens is not immediate. Maybe an
>> iForth bug?

Well, let's say it is something on the list to be fixed. It necessitates
rewriting much, with little gain, so that I preferred to finish iForth64
first.

Note that I posted recently how to get binary updates. CDROM images
(passworded) are now also on www.qdrive.net. A new release of iForth
(and a demo version :-) is expected for later this month.

A temporary fix until then is NOT-IMMEDIATE (used like IMMEDIATE).

Here are some fixes and timings.

( all run on an Intel Core-Duo 2.66 GHz CPU )

FCP -- FIX needed: Change IS to [IS] when compile state
3.395 seconds elapsed. ok ( iForth32 same as iForth64 )

BENCHGC -- FIX needed: none
0.982 seconds elapsed. ok ( iForth32 )
1.056 seconds elapsed. ok ( iForth64 )

LEXEX -- FIX on line 419 of lexarrays.fth: create lex_tokens NOT-IMMEDIATE 0 , 0 , 1darray
Number of FSM states: 1153
Generating output data...
Saving data to file...
Run completed

4.310 seconds elapsed. Time taken: 4 seconds

Checking the output file
Output file is correct
run.fth completed successfully. ok


Brainless and brew are also in the iForth distribution, so there should not be
any unsurmountable problems.

VFX is *a lot* faster on FCP, but I *LOVE* it that FCP is 64-bit clean now.
It will be fun to see how Vfx got that speedup, too.

-marcel

Bernd Paysan

unread,
Aug 30, 2009, 4:25:14 PM8/30/09
to
Anton Ertl wrote:
>>just for
>>benchmark reasons.
>
> Well, why did you do native code in the first place?

To have fast programs, not to have fast benchmarks ;-). These problems
are usually easy to solve. Is it worth that much effort? Only if you
care about this sort of benchmarks - does it run programs fast that
don't have any thought put into about running fast on the target system?
I don't care that much about this kind of program. If you want to run
your program fast, you put at least some kinds of considerations into it
to run it faster on the system you like to use.

The reason what prevents me from simply implementing a sort of ROM-able
bigForth is that the module system in bigForth won't work as well with
two separated memory regions per module. However, I can probably use
the module system to implement an optional mode where code and data is
separated - this could help such benchmarks.

>>If you don't put all variables close to the code
>>that uses them, you won't suffer from that problem.
>
> The question is who should not put the variables close to the code?
> IMO it's the compiler.

One problem here is that it's not just the data - it is frequently
changing data. Just putting a table close to a program is not doing any
harm. Putting a frequently updated variable is. I suppose in cd16sim,
the culprit is that the CPU state and the logic is too close together.

Anton Ertl

unread,
Aug 31, 2009, 4:33:48 AM8/31/09
to
m...@iae.nl (Marcel Hendrix) writes:
>Note that I posted recently how to get binary updates. CDROM images
>(passworded) are now also on www.qdrive.net. A new release of iForth
>(and a demo version :-) is expected for later this month.

My impression was that I am no longer eligible for updates (but I have
not followed this closely).

>A temporary fix until then is NOT-IMMEDIATE (used like IMMEDIATE).

I am unwilling to change the source of the benchmark to work around
bugs of Forth system bugs, more so if these workarounds break on the
other systems. Is there a way to work around the bug by prefixing the
benchmarks with some setup file? E.g., would the following help?

: does> postpone does> non-immediate ;

That would be incorrect for code that does CREATE IMMEDIATE DOES>, but
hopefully that does not occur in the benchmarks, or the immediacy is
not essential (in compat/struct.fs).

>FCP -- FIX needed: Change IS to [IS] when compile state

Would prefixing the benchmark with the reference implementation for
X:defer help?

Anton Ertl

unread,
Aug 31, 2009, 4:45:46 AM8/31/09
to
Bernd Paysan <bernd....@gmx.de> writes:
>Anton Ertl wrote:
>>>just for
>>>benchmark reasons.
>>
>> Well, why did you do native code in the first place?
>
>To have fast programs, not to have fast benchmarks ;-). These problems
>are usually easy to solve. Is it worth that much effort?

They are not that hard to solve in the Forth system, and yet you
apparently don't find it worth the effort. Maybe the workaround for
each program is easy, but then one would have to do the workaround in
all the programs. If it's not worth doing in the Forth system, it's
not worth doing at all.

And why should the author of a portable program put a workaround in
for making your system look better than it is? If your system is slow
on his program, it's not his fault, as faster systems demonstrate.

In addition, reorganizing programs in the way you suggest either
reduces the modularity (you cannot define the data close to the code
that refers to it), or increases the memory consumption (by padding),
or both; oh, and the amount of padding necessary depends on the CPU,
so there is no good value to pick.

Finally, there's the practical consideration that programmers don't
know about this pitfall of IA32 and AMD64 CPUs and the shortcoming of
bigForth (and you probably don't mention it in the documentation, do
you?). So they simply will have no idea why their program is running
slowly on bigForth. And if it runs only on bigForth, they may have no
idea that it is running slowly. OTOH, if it also runs on a system
that does not have this problem, they will just conclude that bigForth
is slow, and move on.

>Only if you
>care about this sort of benchmarks - does it run programs fast that
>don't have any thought put into about running fast on the target system?

I.e., portable programs. If someone develops a portable program on
Gforth, they probably won't put much thought into working around
bigForth performance bugs; they will most likely not know about them.

>The reason what prevents me from simply implementing a sort of ROM-able
>bigForth is that the module system in bigForth won't work as well with
>two separated memory regions per module.

Hmm, the module system is bigForth-specific anyway, so portable
programs won't use it. For bigForth-specific programs it's a little
more reasonable to expect programmers to work around this performance
bug; however, the practical considerations above still apply.

>One problem here is that it's not just the data - it is frequently
>changing data. Just putting a table close to a program is not doing any
>harm.

On the Pentium and K6 it does.

Bernd Paysan

unread,
Aug 31, 2009, 7:00:32 AM8/31/09
to
Anton Ertl wrote:
> And why should the author of a portable program put a workaround in
> for making your system look better than it is? If your system is slow
> on his program, it's not his fault, as faster systems demonstrate.

As an example: Marcel Hendrix wondered why GCC was so much faster on
Wurstkessel than Forth. He compiled the code in iForth64, and made a
few trivial changes - and then achieved about the same speed as GCC.

I found the problem in cd16sim:

In cd16pkg.vdl, line 19, there is:

: w: ( <name> -- ) CREATE -1 , DOES> ; \ wire

Delete the DOES> so that you get

: w: ( <name> -- ) CREATE -1 , ; \ wire

and the performance jumps up (~2s on 2.5GHz Phenom, gforth-fast with the
patched version is ~3s). Reason: The DOES> here creates a) unnecessary
overhead, and b) introduces a code/data problem (probably the only one
here). I could get rid of the code/data problem, by compiling DOES>
code like Gforth does (this is on my list of things to do now), but it
still would create a superfluous empty call/return, unless I take
special care to drop that as well (that's already quite close to
benchmark-microoptimization).

This is the sort of "trivial changes" I mean: It's just removing one
superfluous or stupid thing, and your program runs fine. About the same
thing happened with my Wurstkessel code/data problem: It was also a
DOES> part that slowed things down, it went away when I redefined this
as macro. Now iForth and VFX don't need such a redefinition, they
inline DOES> parts anyway, but using a system with an inliner like VFX
requires more changes to my programs than the other way round (and these
are changes to make it work, instead of changes to make it run faster -
especially the now abandoned source inliner was really a pain to use).

I prefer a compiler that occasionally becomes slow to a compiler that
frequently breaks my code.

Andrew Haley

unread,
Aug 31, 2009, 7:54:21 AM8/31/09
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:

> > One problem here is that it's not just the data - it is frequently
> > changing data. Just putting a table close to a program is not
> > doing any harm.

> On the Pentium and K6 it does.

"Did", surely, not "does". Or are we having fun with retrocomputing?
;-)

Andrew.

Stephen Pelc

unread,
Aug 31, 2009, 8:19:02 AM8/31/09
to
On Mon, 31 Aug 2009 13:00:32 +0200, Bernd Paysan <bernd....@gmx.de>
wrote:

>Now iForth and VFX don't need such a redefinition, they
>inline DOES> parts anyway, but using a system with an inliner like VFX
>requires more changes to my programs than the other way round (and these
>are changes to make it work, instead of changes to make it run faster -
>especially the now abandoned source inliner was really a pain to use).

The parts of your code that still have problems with are now those
parts of your code that are not compliant to the ANS or Forth200x
standards.

>I prefer a compiler that occasionally becomes slow to a compiler that
>frequently breaks my code.

If you insist on writing non-compliant code, you will have problems
when porting code. One approach is to move those portions into a
layer that is stated to be system-dependent. In the cases I have seen
of your code these are small pieces of code.

In dealing with standards, you should not expect to have it both ways.
If you expect a Forth system to be standards-compliant, your library
code should be standards-compliant. If the standard does not permit
a particular technique, then isolation is required. The solution
may then be considered for standardisation.

Stephen


--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

Stephen Pelc

unread,
Aug 31, 2009, 8:24:50 AM8/31/09
to
On Mon, 31 Aug 2009 06:54:21 -0500, Andrew Haley
<andr...@littlepinkcloud.invalid> wrote:

>"Did", surely, not "does". Or are we having fun with retrocomputing?
>;-)
>
>Andrew.

I only retired a P4 two weeks ago! The most common host for VFX Forth
for Linux is embedded. Many of these are using 386/486 class CPUs such
as the Vortex series from
http://dmp.com.tw
and the Geode family still goes on - ugh!

Stephen Pelc

unread,
Aug 31, 2009, 8:29:01 AM8/31/09
to
On Sun, 30 Aug 2009 19:26:20 +0000 (UTC), ygrek <yg...@forth.org.ru>
wrote:

>PS (to MPE people): VFX deb repository is unusable.

I'm aware that the .spec file had CR/LF pairs in it. If you have other
problems please send a note with more details to:
tech-s...@mpeforth.com
We cannot fix problems that we cannot replicate!

Andrew Haley

unread,
Aug 31, 2009, 9:39:39 AM8/31/09
to
Stephen Pelc <steph...@mpeforth.com> wrote:
> On Mon, 31 Aug 2009 06:54:21 -0500, Andrew Haley
> <andr...@littlepinkcloud.invalid> wrote:

> >"Did", surely, not "does". Or are we having fun with retrocomputing?
> >;-)

> I only retired a P4 two weeks ago!

Ha! They don't call him Steve "generous" Pelc for nothing...
:-)

> The most common host for VFX Forth for Linux is embedded. Many of
> these are using 386/486 class CPUs such as the Vortex series from
> http://dmp.com.tw and the Geode family still goes on - ugh!

Fair enough, but do these embedded CPUs have the same cache
weirdnesses as the Pentia et al?

Andrew.

Anton Ertl

unread,
Aug 31, 2009, 9:04:26 AM8/31/09
to

Some people have; I think it's pretty popular in Forth circles.
Moreover, these CPUs may still be delivered these days in embedded
systems. And such things sometimes come back (e.g., gcc PR15242 is
back with gcc 4.4.0); has anybody checked the Atom yet?

Anton Ertl

unread,
Aug 31, 2009, 11:24:59 AM8/31/09
to
steph...@mpeforth.com (Stephen Pelc) writes:
>I only retired a P4 two weeks ago!

With Pentium I meant P5-based systems, i.e., the original Pentium and
the Pentium MMX. The P6 (Pentium Pro, Pentium II, III, etc.) and
Pentium 4 are only slow on writes close to code.

Ian Osgood

unread,
Aug 31, 2009, 12:03:53 PM8/31/09
to
On Aug 31, 1:33 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:

> m...@iae.nl (Marcel Hendrix) writes:
>
> >FCP -- FIX needed:  Change IS to [IS] when compile state
>
> Would prefixing the benchmark with the reference implementation for
> X:defer help?
>
> - anton

Pushed upstream, since I notice that my main test platform GNU Forth
0.7.0 already has [IS]. How prevalent is [IS] among other modern Forth
distributions? What would be a good shim for systems having only a
state-smart IS?

Also, what is keeping FCP from working on vfxlin?

Ian

Anton Ertl

unread,
Aug 31, 2009, 3:13:15 PM8/31/09
to
Ian Osgood <ia...@quirkster.com> writes:
>On Aug 31, 1:33=A0am, an...@mips.complang.tuwien.ac.at (Anton Ertl)

>wrote:
>> m...@iae.nl (Marcel Hendrix) writes:
>>
>> >FCP -- FIX needed: =A0Change IS to [IS] when compile state

>>
>> Would prefixing the benchmark with the reference implementation for
>> X:defer help?
>>
>> - anton
>
>Pushed upstream, since I notice that my main test platform GNU Forth
>0.7.0 already has [IS]. How prevalent is [IS] among other modern Forth
>distributions? What would be a good shim for systems having only a
>state-smart IS?

Given that IS has been standardized in Forth200x (with compilation
semantics equivalent to the compilation of [IS]), and [IS] has not,
the way to go for portability seems to use IS.

>Also, what is keeping FCP from working on vfxlin?

It seems to crash in .SEARCHSTATUS, apparently because your definition
for MS@ if you find none of the timer words does not work together
with the stuf in .MS. The first time that the number of nodes gets
lower (because you compute another turn), it tries to UM/MOD a
negative number by 1000, and that results in an overflow in UM/MOD.

ygrek

unread,
Aug 31, 2009, 3:44:59 PM8/31/09
to
Mon, 31 Aug 2009 12:29:01 +0000, Stephen Pelc wrote:

> I'm aware that the .spec file had CR/LF pairs in it. If you have other
> problems please send a note with more details to:
> tech-s...@mpeforth.com
> We cannot fix problems that we cannot replicate!

Just try to install something with aptitude. Mailed details to tech-support@

--
ygrek

Anton Ertl

unread,
Aug 31, 2009, 3:30:55 PM8/31/09
to
Bernd Paysan <bernd....@gmx.de> writes:
>Anton Ertl wrote:
>> And why should the author of a portable program put a workaround in
>> for making your system look better than it is? If your system is slow
>> on his program, it's not his fault, as faster systems demonstrate.
>
>As an example: Marcel Hendrix wondered why GCC was so much faster on
>Wurstkessel than Forth. He compiled the code in iForth64, and made a
>few trivial changes - and then achieved about the same speed as GCC.

And this demonstrates what? He did not compile the same program with
gcc and with iForth, so the situation is different from what I
discussed.

>Reason: The DOES> here creates a) unnecessary
>overhead, and b) introduces a code/data problem (probably the only one
>here). I could get rid of the code/data problem, by compiling DOES>
>code like Gforth does (this is on my list of things to do now), but it
>still would create a superfluous empty call/return, unless I take
>special care to drop that as well (that's already quite close to
>benchmark-microoptimization).

Not if it's the result of a more general inliner.

>This is the sort of "trivial changes" I mean: It's just removing one
>superfluous or stupid thing, and your program runs fine.

And if you fix the code/data thing in your compiler, this program will
run pretty fast unchanged, and many others will, too. Eliminating the
DOES> afterwards will probably make it even faster on your system, but
that's minor compared to the code/data problem.

>but using a system with an inliner like VFX
>requires more changes to my programs than the other way round (and these
>are changes to make it work, instead of changes to make it run faster -
>especially the now abandoned source inliner was really a pain to use).
>
>I prefer a compiler that occasionally becomes slow to a compiler that
>frequently breaks my code.

That's a false dichotomy. Will fixing the code/data problem in the
compiler break your code? As for inlining, I would expect you to
implement an inliner in such a way that preserves the properties your
code needs.

ygrek

unread,
Aug 31, 2009, 3:52:56 PM8/31/09
to
Sun, 30 Aug 2009 19:49:49 +0000, Anton Ertl wrote:

> Exception #2 at: /usr/lib/spforth4/lib/ext/caseins-tools.f:1:49: REQUIRE
> CHAR-UPPERCASE ~ac/lib/string/uppercase.f
> ^ ERROR #-2003

Sorry for that.

Here is a quick fix :
Get two files from CVS and put in /usr/lib/spforth4/lib/ext/
http://spf.cvs.sourceforge.net/*checkout*/spf/lib/ext/uppercase.f
http://spf.cvs.sourceforge.net/*checkout*/spf/lib/ext/caseins-tools.f

Deb package will be updated some day. Thanks for pointing this out.

Also, setup-spf.f needs update for the fcp benchmark :

\ $10
: NOTFOUND
OVER C@ [CHAR] $ =
IF BASE @ >R HEX 1 /STRING ['] ?SLITERAL CATCH R> BASE ! THROW EXIT THEN
NOTFOUND ;

--
ygrek

Anton Ertl

unread,
Aug 31, 2009, 3:58:53 PM8/31/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:

>Ian Osgood <ia...@quirkster.com> writes:
>>Also, what is keeping FCP from working on vfxlin?
>
>It seems to crash in .SEARCHSTATUS, apparently because your definition
>for MS@ if you find none of the timer words does not work together
>with the stuf in .MS. The first time that the number of nodes gets
>lower (because you compute another turn), it tries to UM/MOD a
>negative number by 1000, and that results in an overflow in UM/MOD.

I found a workaround for that:

FORTH="vfxlin variable x : ms@ x @ 1 x +! ;" BENCH=fcp ./test

That works.

I also tried both of the workarounds I suggested for iforth and they
did not work.

Bernd Paysan

unread,
Aug 31, 2009, 4:11:23 PM8/31/09
to
Stephen Pelc wrote:

> On Mon, 31 Aug 2009 13:00:32 +0200, Bernd Paysan <bernd....@gmx.de>
> wrote:
>
>>Now iForth and VFX don't need such a redefinition, they
>>inline DOES> parts anyway, but using a system with an inliner like VFX
>>requires more changes to my programs than the other way round (and
>>these are changes to make it work, instead of changes to make it run
>>faster - especially the now abandoned source inliner was really a pain
>>to use).
>
> The parts of your code that still have problems with are now those
> parts of your code that are not compliant to the ANS or Forth200x
> standards.

This is a GCC-maintainer-like interpretation of the standard. Your
Forth system provides a real return stack, therefore it shouldn't have
problems with programs that use the return stack - including the return
address. I understand that using the return stack might cause problems
on arcane Forth systems such as F-PC, and I therefore avoid arcane Forth
systems, despite them (possibly) being standard to the letter.
Actually, none of these arcane systems made the effort to become ANS
compatible. The ANS compatible Forth system from Tom Zimmer is
Win32Forth, and it has a real return stack.

My interpretation of standard ambiguities like that is that they are in
a standard to allow arcane systems to claim being standard. They are
not there as excuse for sloppy implementations. If you have a return
stack that looks like a return stack and feels like a return stack, you
better provide it fully. If you have a sloppy implementation, it's a
QoI issue (quality of implementation). It's something you have to
discuss with your users.

However, I'm quite confident that I can do what you are asking; I've
already some ideas how to poison the inliner in an insulated way. The
fact that all these words are inside my OOF system should help a lot.

> In dealing with standards, you should not expect to have it both ways.
> If you expect a Forth system to be standards-compliant, your library
> code should be standards-compliant. If the standard does not permit
> a particular technique, then isolation is required. The solution
> may then be considered for standardisation.

The standard warns indeed about accessing the return stack below what
the program put there itself. However, I make other assumptions, as
well. For example, my MINOS library is pretty hard-coded to expect
Char=Byte. This is an environmental dependency. It also depends on
return stack=real return stack. Also something like an environmental
dependency, even though the standard does not tell you more about it
(the standard allows a char to be a byte, but it is so strict about
denying access to the return stack). Both very common features. The
standard allows systems to have such features, and programs can use such
features if they declare an environmental dependency. This is different
from system-specific extensions such as nested anonymous definitions, C-
library interfaces, or local float variables (all things I use, too).

We quibble about not having portable Forth libraries. I think one
reason is that people don't like libraries, but the other reason is that
our systems and programs are just not portable enough to support that.
Writing something like MINOS in standard C++ is not an issue. It has
been done, several times (and yes, these standard C++ programs certainly
have environmental dependencies, as well, like char=byte or
library=xlib). Writing it in pure standard Forth is impossible.

Therefore, porting something like MINOS is a valuable exercise. It's
clearly a non-toy example. When the standard makes porting this sort of
program difficult, the standard itself is part of the problem, not the
solution.

Ian Osgood

unread,
Aug 31, 2009, 4:25:16 PM8/31/09
to
On Aug 31, 12:58 pm, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:
> an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:

> >Ian Osgood <i...@quirkster.com> writes:
> >>Also, what is keeping FCP from working on vfxlin?
>
> >It seems to crash in .SEARCHSTATUS, apparently because your definition
> >for MS@ if you find none of the timer words does not work together
> >with the stuf in .MS.  The first time that the number of nodes gets
> >lower (because you compute another turn), it tries to UM/MOD a
> >negative number by 1000, and that results in an overflow in UM/MOD.
>
> I found a workaround for that:
>
> FORTH="vfxlin variable x : ms@ x @ 1 x +! ;" BENCH=fcp ./test
>
> That works.
>
> I also tried both of the workarounds I suggested for iforth and they
> did not work.
>
> - anton

Of course, what I really want is access to a millisecond clock for
VFX. I guess the Windows-specific GetTickCount doesn't exist in VFX
for Linux. What is the recommended replacement?

(and of course what I really REALLY want is a standard for subsecond
timing. Surely that would be a popular feature for embedded and hosted
platforms?)

Ian

Bernd Paysan

unread,
Aug 31, 2009, 5:25:50 PM8/31/09
to
Anton Ertl wrote:

> Bernd Paysan <bernd....@gmx.de> writes:
>>As an example: Marcel Hendrix wondered why GCC was so much faster on
>>Wurstkessel than Forth. He compiled the code in iForth64, and made a
>>few trivial changes - and then achieved about the same speed as GCC.
>
> And this demonstrates what? He did not compile the same program with
> gcc and with iForth, so the situation is different from what I
> discussed.

This demonstrates that other systems can improve performance with some
trivial changes, as well. And after all, it *is* the same program in
GCC and iForth, one is generated Forth from Forth, the other generated C
from Forth.

> That's a false dichotomy. Will fixing the code/data problem in the
> compiler break your code?

I switch to "single space" in VFX Forth with "-idata". It breaks pretty
soon when I don't do that. Gforth has it better, because there, the
code still is data, and the separated instruction space just accelerates
how the threaded code is executed. A native Forth makes it a lot more
difficult to separate code and data without funny results (like e.g.
embedding a string literal into a definition, what I do in i18n.fs, the
first place where +idata breaks).

For cd16sim, it is probably completely sufficient to implement a Gforth-
like DOES> treatment on compilation.

Sidenode: Why don't I simply use SLiteral in i18n.fs? Because the
compiled strings aren't just string literals - they are part of a
translation data base. The string has a native form, and pointers to
translated forms, which are patched in later. The code there would be
even easier, if I knew that I have completely separated instruction and
code. But then, porting to Gforth would require changing that code
again.

If separating code and data would be a no-side-effect issue, I would
have done it long ago. It is not, unless you do it like in Gforth.

Elizabeth D Rather

unread,
Aug 31, 2009, 5:46:10 PM8/31/09
to
Ian Osgood wrote:
...

>
> (and of course what I really REALLY want is a standard for subsecond
> timing. Surely that would be a popular feature for embedded and hosted
> platforms?)
>
> Ian

You do have 10.6.2.1905 MS (FACILITY EXT). Many systems provide it. It
times <n> milliseconds, to whatever accuracy the underlying platform can
provide. It is, indeed, very popular! On most embedded systems it's
possible to get good ms accuracy; hosted platforms are less consistent
for reasons beyond anyone's control.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

Albert van der Horst

unread,
Aug 31, 2009, 7:17:05 PM8/31/09
to
In article <4a9bbfd6....@192.168.0.50>,

Stephen Pelc <steph...@INVALID.mpeforth.com> wrote:
>On Mon, 31 Aug 2009 06:54:21 -0500, Andrew Haley
><andr...@littlepinkcloud.invalid> wrote:
>
>>"Did", surely, not "does". Or are we having fun with retrocomputing?
>>;-)
>>
>>Andrew.
>
>I only retired a P4 two weeks ago! The most common host for VFX Forth
>for Linux is embedded. Many of these are using 386/486 class CPUs such
>as the Vortex series from
> http://dmp.com.tw
>and the Geode family still goes on - ugh!

My main system with all my cvs/rcs archive is still a pentium 90.
(That is a Pentium 1, isn't it?)
My ftp/http server is a Pentium MMX 150.
Why retire a good work horse?

>
>Stephen

>--
>Stephen Pelc, steph...@mpeforth.com

Groetjes Albert

--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Stephen Pelc

unread,
Aug 31, 2009, 6:34:35 PM8/31/09
to
On Mon, 31 Aug 2009 19:58:53 GMT, an...@mips.complang.tuwien.ac.at
(Anton Ertl) wrote:

>I found a workaround for that:
>
>FORTH="vfxlin variable x : ms@ x @ 1 x +! ;" BENCH=fcp ./test
>
>That works.

: ms@ ( -- ums ) ticks ;

RTFM is your friend.

Stephen

--
Stephen Pelc, steph...@mpeforth.com

Stephen Pelc

unread,
Aug 31, 2009, 6:52:28 PM8/31/09
to
On Mon, 31 Aug 2009 22:11:23 +0200, Bernd Paysan <bernd....@gmx.de>
wrote:

>This is a GCC-maintainer-like interpretation of the standard. Your

>Forth system provides a real return stack, therefore it shouldn't have
>problems with programs that use the return stack - including the return
>address.

VFX is remarkably tolerant of return stack issues. Where uour code
has caused problems is that some your words effectively split a
single definition into two or more words. Your conversions did not
manage to tell the VFX compiler what was going on.

>> In dealing with standards, you should not expect to have it both ways.
>> If you expect a Forth system to be standards-compliant, your library
>> code should be standards-compliant. If the standard does not permit
>> a particular technique, then isolation is required. The solution
>> may then be considered for standardisation.
>
>The standard warns indeed about accessing the return stack below what
>the program put there itself.

It also warns you about defining words inside words.

>Therefore, porting something like MINOS is a valuable exercise. It's
>clearly a non-toy example. When the standard makes porting this sort of
>program difficult, the standard itself is part of the problem, not the
>solution.

There I do agree with you, but when you are dealing with multiple
Forth systems written by other people, your tag-line gets you into
trouble. The bigforth version of /STRING conflicts with at least
VFX, SwiftForth, iForth and probably with Win32Forth. As you well
know, the port process has revealed bugs in Minos and Theseus.

I will be presenting a paper on porting at EuroForth 2009 next
weekend.

Stephen Pelc

unread,
Aug 31, 2009, 6:56:01 PM8/31/09
to
On Mon, 31 Aug 2009 19:44:59 +0000 (UTC), ygrek <yg...@forth.org.ru>
wrote:

>Mon, 31 Aug 2009 12:29:01 +0000, Stephen Pelc wrote:

Received and many thanks. It'll be looked after EuroForth.

Andreas

unread,
Sep 1, 2009, 1:42:22 PM9/1/09
to
Elizabeth D Rather schrieb:

> You do have 10.6.2.1905 MS (FACILITY EXT). Many systems provide it. It
> times <n> milliseconds, to whatever accuracy the underlying platform can
> provide.

Does it?? I thought MS just waits??

Andreas

Elizabeth D Rather

unread,
Sep 1, 2009, 4:42:32 PM9/1/09
to

It waits, yes. Isn't that what the op was asking for? However,
virtually all implementations of MS run a counter that's accessible. If
you want to time benchmarks, it'd probably be straightforward to
standardize it.

FORTH, Inc. systems have the words:

COUNTER ( -- d ) \ Returns the current value of a double-length timer.

TIMER ( d -- n ) \ Takes a timer value (from a prior call to COUNTER,
reads the new value, and returns the difference in milliseconds.

The timer itself is just a double-length free-running counter that is
incremented by whatever clock interrupts the platform has access to.
The size of the maximum measurable interval is (obviously) a function of
how often the clock ticks and the size of a double integer.

Brad Eckert

unread,
Sep 2, 2009, 4:02:11 PM9/2/09
to
On Sep 1, 1:42 pm, Elizabeth D Rather <erat...@forth.com> wrote:
>
> COUNTER ( -- d ) \ Returns the current value of a double-length timer.
>
Windows has calls that return the number of clocks elapsed since
startup and the clock speed. gForth's UTIME ( -- d ) returns
microseconds elapsed since startup. That could be aliased as COUNTER.
Having better than 1 ms resolution on COUNTER makes sense for 32-bit
systems since they are pretty fast (1 ms is a long time) and 64 bits
represents a very long time even in nanoseconds.

>
> TIMER ( d -- n ) \ Takes a timer value (from a prior call to COUNTER,
> reads the new value, and returns the difference in milliseconds.
>
What's missing here is a constant that tells the precision of COUNTER.
Let's call it COUNTER-HZ. I think COUNTER-HZ should be a compile-time
constant (or EQU) that returns the COUNTER rate in Hz. 16-bit systems
would support up to a 65kHz COUNTER rate and 32-bit systems would have
no practical limit.

To convert milliseconds to COUNTER time units, you could scale like
this:

: MS>ticks ( n -- d )
[ COUNTER-HZ 1000 / ] LITERAL UM* \ only for multiples of 1kHz
;

The scaling would be more sophisticated for odd values of COUNTER-HZ,
but the appropriate algorithm can be picked at compile time.

-
Brad

Andreas

unread,
Sep 2, 2009, 4:19:50 PM9/2/09
to
Brad Eckert schrieb:

> What's missing here is a constant that tells the precision of COUNTER.
> Let's call it COUNTER-HZ. I think COUNTER-HZ should be a compile-time
> constant (or EQU) that returns the COUNTER rate in Hz. 16-bit systems
> would support up to a 65kHz COUNTER rate and 32-bit systems would have
> no practical limit.
>
> To convert milliseconds to COUNTER time units, you could scale like
> this:
>
> : MS>ticks ( n -- d )
> [ COUNTER-HZ 1000 / ] LITERAL UM* \ only for multiples of 1kHz
> ;
>
> The scaling would be more sophisticated for odd values of COUNTER-HZ,
> but the appropriate algorithm can be picked at compile time.
>
> -
> Brad

In C the clock() function and the CLOCKS_PER_SEC macro provide similar
data that can be used for rough timing.

However I admit it would be nicer to have a consensus here. RESET-TIMER
and .ELAPSED seem to be used by more than one system.

Andreas

Marcel Hendrix

unread,
Sep 2, 2009, 4:58:35 PM9/2/09
to
Brad Eckert <bit...@gmail.com> writes Re: Application benchmark suite available
[..]

> To convert milliseconds to COUNTER time units, you could scale like
> this:

> : MS>ticks ( n -- d )
> [ COUNTER-HZ 1000 / ] LITERAL UM* \ only for multiples of 1kHz
> ;

This is hopeless on current desktops. Multi-core CPU's and advanced
power-saving, sleep, and dynamic clock-scaling algorithms interfere.
Hiding the details with TIMER-RESET ( -- ) and .ELAPSED or MS? ( -- u )
is better. COUNTER ( -- d ) has the problem that it is needlessly
imprecise when returning ms, or could overflow for long intervals
(or for long system up-times).

With the porting of Jack audio connection kit to iForth we decided upon
a COUNTER/TIMER scheme with a floating-point return value (ns).

-marcel

Elizabeth D Rather

unread,
Sep 2, 2009, 5:06:13 PM9/2/09
to
Brad Eckert wrote:
> On Sep 1, 1:42 pm, Elizabeth D Rather <erat...@forth.com> wrote:
>> COUNTER ( -- d ) \ Returns the current value of a double-length timer.
>>
> Windows has calls that return the number of clocks elapsed since
> startup and the clock speed. gForth's UTIME ( -- d ) returns
> microseconds elapsed since startup. That could be aliased as COUNTER.
> Having better than 1 ms resolution on COUNTER makes sense for 32-bit
> systems since they are pretty fast (1 ms is a long time) and 64 bits
> represents a very long time even in nanoseconds.

Yes, <1ms resolution is now possible on a number of platforms, and we
support it where possible. Our megahertz equivalents are uCOUNTER and
uTIMER, which returns an elapsed time in microseconds.

But if we're talking about standards, we have to consider all the
possible platforms, many of which do not have high-speed clocks.

>> TIMER ( d -- n ) \ Takes a timer value (from a prior call to COUNTER,
>> reads the new value, and returns the difference in milliseconds.
>>
> What's missing here is a constant that tells the precision of COUNTER.
> Let's call it COUNTER-HZ. I think COUNTER-HZ should be a compile-time
> constant (or EQU) that returns the COUNTER rate in Hz. 16-bit systems
> would support up to a 65kHz COUNTER rate and 32-bit systems would have
> no practical limit.
>
> To convert milliseconds to COUNTER time units, you could scale like
> this:
>
> : MS>ticks ( n -- d )
> [ COUNTER-HZ 1000 / ] LITERAL UM* \ only for multiples of 1kHz
> ;
>
> The scaling would be more sophisticated for odd values of COUNTER-HZ,
> but the appropriate algorithm can be picked at compile time.

I don't think it's appropriate to expect the application to deal with
the conversion. We have experimented with several approaches.
Currently, we have COUNTER simply return its value in MS, with the
conversion in the interrupt routine OR in the word COUNTER, depending.
I don't see an advantage in making this simple function any more
transparent than that.

Albert van der Horst

unread,
Sep 3, 2009, 5:44:39 AM9/3/09
to
In article <4a9ed366$0$31331$9b4e...@newsspool4.arcor-online.net>,

Andreas <a....@nospam.org> wrote:
>Brad Eckert schrieb:
>> What's missing here is a constant that tells the precision of COUNTER.

I have TICKS ( -- d ). I don't think COUNTER is a good name, too overloaded.
You can count everything. COUNTER must not be associated with COUNT.

Otoh, TICKS or CLOCKS is more specific.

>> Let's call it COUNTER-HZ. I think COUNTER-HZ should be a compile-time
>> constant (or EQU) that returns the COUNTER rate in Hz. 16-bit systems
>> would support up to a 65kHz COUNTER rate and 32-bit systems would have
>> no practical limit.

Why not just call it what it is: TICKS-PER-SECOND ?
It is a CONSTANT , but an EQU constant?
I like it that after ``WANT TICKS-PER-SECOND '' ciforth has available
the right value. No need to burn it into the executable.
The trick is something like
TICKS 1000 MS TICKS 2SWAP D-

>>
>> To convert milliseconds to COUNTER time units, you could scale like
>> this:
>>
>> : MS>ticks ( n -- d )
>> [ COUNTER-HZ 1000 / ] LITERAL UM* \ only for multiples of 1kHz
>> ;
>>
>> The scaling would be more sophisticated for odd values of COUNTER-HZ,
>> but the appropriate algorithm can be picked at compile time.

/ Scaling in Forth has always been straightforward:

1000 CONSTANT MS-PER-SECOND
: MS>TICKS TICKS-PER-SECOND MS-PER-SECOND */ ;
: TICKS>MS MS-PER-SECOND TICKS-PER-SECOND */ ;

There are overflow issues here, but at least not in the
intermediate results.

>>
>> -
>> Brad
>
>In C the clock() function and the CLOCKS_PER_SEC macro provide similar
>data that can be used for rough timing.
>
>However I admit it would be nicer to have a consensus here. RESET-TIMER
>and .ELAPSED seem to be used by more than one system.

I have: MARK-TIME and ELAPSED , then the choice of .mS or .uS .
I hate the situation that standard programs could only print,
not put results in tables.
(Single precision is ample for ELAPSED . ciforth counts ELAPSED in
ticks, but the units could be implementation defined. A 64-bit
system could count to 10^18 in nS, e.g.)

>
>Andreas

Krishna Myneni

unread,
Sep 3, 2009, 5:21:23 AM9/3/09
to
On Aug 31, 5:34 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
> On Mon, 31 Aug 2009 19:58:53 GMT, an...@mips.complang.tuwien.ac.at
>
> (Anton Ertl) wrote:
> >I found a workaround for that:
>
> >FORTH="vfxlin variable x : ms@ x @ 1 x +! ;" BENCH=fcp ./test
>
> >That works.
>
> : ms@ ( -- ums )  ticks  ;
>
> RTFM is your friend.
>

kForth implements MS@ to return the number of ms elapsed since startup
of the Forth system. At one point, I had proposed to Guido Draheim to
implement MS@ into PFE, but I don't know the status of that anymore.

Krishna

Elizabeth D Rather

unread,
Sep 3, 2009, 12:15:57 PM9/3/09
to
Albert van der Horst wrote:
> In article <4a9ed366$0$31331$9b4e...@newsspool4.arcor-online.net>,
> Andreas <a....@nospam.org> wrote:
>> Brad Eckert schrieb:
>>> What's missing here is a constant that tells the precision of COUNTER.
>
> I have TICKS ( -- d ). I don't think COUNTER is a good name, too overloaded.
> You can count everything. COUNTER must not be associated with COUNT.
>
> Otoh, TICKS or CLOCKS is more specific.
>
>>> Let's call it COUNTER-HZ. I think COUNTER-HZ should be a compile-time
>>> constant (or EQU) that returns the COUNTER rate in Hz. 16-bit systems
>>> would support up to a 65kHz COUNTER rate and 32-bit systems would have
>>> no practical limit.
>
> Why not just call it what it is: TICKS-PER-SECOND ?
> It is a CONSTANT , but an EQU constant?

That's kinda verbose. We call it T/S (pronounced ticks-per-second).
But I still don't think it's necessary to expose that. User words
should deliver user units.

Ian Osgood

unread,
Sep 3, 2009, 1:49:56 PM9/3/09
to
On Aug 31, 3:34 pm, stephen...@mpeforth.com (Stephen Pelc) wrote:
>
> : ms@ ( -- ums )  ticks  ;
>
> RTFM is your friend.
>
> Stephen
>
> --
> Stephen Pelc, stephen...@mpeforth.com

> MicroProcessor Engineering Ltd - More Real, Less Time
> 133 Hill Lane, Southampton SO15 5AF, England
> tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
> web:http://www.mpeforth.com- free VFX Forth downloads

Thank you. This modification has been made to FCP. My timing code is
now:

[UNDEFINED] ms@ [IF]
[DEFINED] ?MS [IF] ( -- ms )
: ms@ ?MS ; \ iForth
[ELSE] [DEFINED] cputime [IF] ( -- Dusec )
: ms@ cputime d+ 1000 um/mod nip ; \ gforth: Anton Ertl
[ELSE] [DEFINED] timer@ [IF] ( -- Dusec )
: ms@ timer@ >us 1000 um/mod nip ; \ bigForth
[ELSE] [DEFINED] gettimeofday [IF] ( -- usec sec )
: ms@ gettimeofday 1000 MOD 1000 * SWAP 1000 / + ; \ PFE
[ELSE] [DEFINED] counter [IF]
: ms@ counter ; \ swiftForth
[ELSE] [DEFINED] GetTickCount [IF]
: ms@ GetTickCount ; \ VFX Forth (Windows)
[ELSE] [DEFINED] ticks [IF]
: ms@ ticks ; \ VFX Forth (Linux)
[ELSE] [DEFINED] MICROSECS [IF]
: ms@ microsecs 1000 UM/MOD nip ; \ MacForth
[ELSE]
CR .( Warning! need definition for a millisecond timer ms@ )
10 CONSTANT npms
: ms@ ( -- n ) nodes npms / ; \ bogus
[THEN] [THEN] [THEN] [THEN] [THEN] [THEN] [THEN] [THEN]
[ELSE]
\ Win32Forth microsecond counter rolls over every day
1000 60 * 60 * 24 * constant MaxMsDay
[THEN]

0 VALUE msStart
: startTimer ms@ TO msStart ;
: readTimer ( -- ms ) ms@ msStart - ;

[DEFINED] MaxMsDay [IF]
: readTimer ( -- ms ) \ >>> Also right when 00:00 passes
readTimer DUP 0< IF MaxMsDay + THEN ;
[THEN]

I look forward to any standardization of a subsecond timer, either as
direct counter access or some sort of COUNTER/TIMER pair.

Ian

Brad Eckert

unread,
Sep 4, 2009, 11:36:46 AM9/4/09
to
On Sep 2, 2:06 pm, Elizabeth D Rather <erat...@forth.com> wrote:
>
> Currently, we have COUNTER simply return its value in MS, with the
> conversion in the interrupt routine OR in the word COUNTER, depending.
> I don't see an advantage in making this simple function any more
> transparent than that.
Me neither. I have a lot of code that expects COUNTER to use msec.

Can the OS and host Forth be determined by ENVIRONMENT? If so, a
benchmark program could conditionally compile timer functions that use
available OS calls. It could supply versions for Win32(VFX), Win32
(SwiftForth), Win32(iForth), Linux(VFX), MAC(carbon), etc. Maybe for
the 200x standard we should be thinking about environment entries for
OS and host Forth.

Brad Eckert

unread,
Sep 4, 2009, 11:44:57 AM9/4/09
to
On Sep 3, 2:44 am, Albert van der Horst <alb...@spenarnc.xs4all.nl>
wrote:

>
> Why not just call it what it is: TICKS-PER-SECOND ?
> It is a CONSTANT , but an EQU constant?
> I like it that after ``WANT TICKS-PER-SECOND '' ciforth has available
> the right value. No need to burn it into the executable.
> The trick is something like
>   TICKS   1000 MS    TICKS    2SWAP D-

Maybe TICKS-PER-SECOND is variable. The Win32 call that returns the
total elapsed clock cycles was most likely thrown in for benchmark
geeks. If such metrics are available, why not use them?

It might be better to display benchmark results in clock cycles
instead of time.

-
Brad

Elizabeth D Rather

unread,
Sep 4, 2009, 1:32:37 PM9/4/09
to
Brad Eckert wrote:
> On Sep 3, 2:44 am, Albert van der Horst <alb...@spenarnc.xs4all.nl>
> wrote:
...

> Maybe TICKS-PER-SECOND is variable. The Win32 call that returns the
> total elapsed clock cycles was most likely thrown in for benchmark
> geeks. If such metrics are available, why not use them?
>
> It might be better to display benchmark results in clock cycles
> instead of time.

At least ms is a cross-platform measure that everyone understands, while
clock cycles are far too varying from one platform to another.

Charles Turner

unread,
Sep 4, 2009, 5:59:33 PM9/4/09
to
On Sep 4, 11:36 am, Brad Eckert <bitb...@gmail.com> wrote:
> Can the OS and host Forth be determined by ENVIRONMENT? If so, a
> benchmark program could conditionally compile timer functions that use
> available OS calls. It could supply versions for Win32(VFX), Win32
> (SwiftForth), Win32(iForth), Linux(VFX), MAC(carbon), etc. Maybe for
> the 200x standard we should be thinking about environment entries for
> OS and host Forth.

Not to contradict anything in Marcel's previous response, but having
written the iForth Mach timing routines, Apple's code is supposed to
return timing results unaffected by the performance properties of
modern CPUs. Given CoreAudio's dependence on these routines, and James
McCartney's involvement with Apple audio infrastructure, I would
imagine those assertions are true. There are specific techniques for
converting Mach timing results into nanoseconds. These Mac routines
are available throughout OSX, and not just limited to Carbon.

Best, Charles

Jerry Avins

unread,
Sep 6, 2009, 9:58:20 AM9/6/09
to
Elizabeth D Rather wrote:
> Brad Eckert wrote:
>> On Sep 3, 2:44 am, Albert van der Horst <alb...@spenarnc.xs4all.nl>
>> wrote:
> ...
>> Maybe TICKS-PER-SECOND is variable. The Win32 call that returns the
>> total elapsed clock cycles was most likely thrown in for benchmark
>> geeks. If such metrics are available, why not use them?
>>
>> It might be better to display benchmark results in clock cycles
>> instead of time.
>
> At least ms is a cross-platform measure that everyone understands, while
> clock cycles are far too varying from one platform to another.

Why must one have to choose? Timing results in clock cycles say
something about the efficiency of an algorithm that is independent of
the processor's clock speed.

Jerry
--
Engineering is the art of making what you want from things you can get.
�����������������������������������������������������������������������

Albert van der Horst

unread,
Sep 7, 2009, 4:43:03 PM9/7/09
to
In article <XdPom.156267$O23....@newsfe11.iad>,

Jerry Avins <j...@ieee.org> wrote:
>Elizabeth D Rather wrote:
>> Brad Eckert wrote:
>>> On Sep 3, 2:44 am, Albert van der Horst <alb...@spenarnc.xs4all.nl>
>>> wrote:
>> ...
>>> Maybe TICKS-PER-SECOND is variable. The Win32 call that returns the
>>> total elapsed clock cycles was most likely thrown in for benchmark
>>> geeks. If such metrics are available, why not use them?
>>>
>>> It might be better to display benchmark results in clock cycles
>>> instead of time.
>>
>> At least ms is a cross-platform measure that everyone understands, while
>> clock cycles are far too varying from one platform to another.
>
>Why must one have to choose? Timing results in clock cycles say
>something about the efficiency of an algorithm that is independent of
>the processor's clock speed.

And about the clock-efficieny of processors. OTOH in estimating
how long it takes to clean up a directory with 1 Gbyte of spam
I'm interested in wall clock time.

So, you're right both are of interest.

>
>Jerry

Robert Epprecht

unread,
Sep 14, 2009, 6:41:53 AM9/14/09
to
Hi Anton

Please excuse my late reply. I was not subscribed to clf any more,
just found your benchmark suite by accident on google...
Thanks for including brew in the suite.


> bigForth. The failure of brew is mysterious.

I had a quick look. My impression is that something is wrong with
[defined] and defined? in bigforth 2.3.1. (The benchmark was running
fine on bigforth 2.1.0).

As I cannot reach Chaossolutions and the bigforth ml I post it here:

\ ***********************************************
\ something.fs

\ create something

[DEFINED] something [IF]
.( 'something' is defined) cr
[ELSE]
.( 'something' is not defined) cr
[ENDIF]

.( I got here)
\ ***********************************************

f@e901$ bigforth
ANS bigFORTH 386-Linux rev. 2.3.1

see something ? something
include something.fs 'something' is not defined
don't know [ENDIF]
create something ok
include something.fs 'something' is defined
ok
bye ok
the system is unusable and just says ok to any input... ok
i have to ^C ok
Segmentation fault


regarding brew and 64bit:

I installed a Debian/Lenny 64bit system this morning to be able to
test brew on a 64 bit system and built gforth 0.7.0. My very first
test results look like brew is doing fine on 64bit (I was very aware
of different cell sizes when writing brew).

That the benchmarks do not give the same results on 32bit and 64bit
was to be expected due to integer math overflow. Nothing in brew will
prevent the mutation process to produce gens that play tricks with
integer overflow. This is fully intended. Nevertheless it should be
possible to construct a benchmark where no 32bit integer overflow
happens but it's not an easy task. Another possibility could be to
change the used gene primitives so that this will not happen. I will
think about and do some tests. Feedback welcome.


But there is another problem: gforth and gforth-fast behave different
on my 64bit system.

Please try the following two comands to check on your system
~/brew$ gforth -e "CREATE transit-12-bench" brew.s
~/brew$ gforth-fast -e "CREATE transit-12-bench" brew.s
I had no time to investigate yet.


Regarding other FORTH systems.

pfe
brew was also compatible with pfe versions of the time I wrote it.
Did not test an up-to-date version yet.

iForth
brew run on some iForth versions that Marcel Hendrix gave me, but they
where never fully compatible to each other. I don't have a current version
to try, but would certainly like to do so.

I don't have any of the commercial FORTH systems to try to make brew
compatible to them. I'd be interested to do so.

Robert Epprecht

Bernd Paysan

unread,
Sep 14, 2009, 6:59:41 AM9/14/09
to
Robert Epprecht wrote:
> don't know [ENDIF]

Maybe this should ring your bell - there's no [ENDIF] in bigForth. There's
one in Gforth, as alias to [THEN], which is the standard end to an [IF]
clause. Should I add [ENDIF] to bigForth? It's fairly straight-forward,
anyway, and may improve portability from Gforth.

Chaossolutions.org still seems to be down, I suppose I'll have to use some
other mailman (e.g. forth-ev.de) as mailing list server.

Robert Epprecht

unread,
Sep 14, 2009, 7:15:18 AM9/14/09
to
Bernd Paysan <bernd....@gmx.de> writes:

> Robert Epprecht wrote:
>> don't know [ENDIF]
>
> Maybe this should ring your bell - there's no [ENDIF] in bigForth.

Ah, sorry. ;) I forgot that I define it in brew. So I'm back to square
one in finding out why brew has problems on current bigforth.

> Should I add [ENDIF] to bigForth?

sure, please do.

Robert Epprecht

Bernd Paysan

unread,
Sep 14, 2009, 7:38:22 AM9/14/09
to
Robert Epprecht wrote:

> Bernd Paysan <bernd....@gmx.de> writes:
>
>> Robert Epprecht wrote:
>>> don't know [ENDIF]
>>
>> Maybe this should ring your bell - there's no [ENDIF] in bigForth.
>
> Ah, sorry. ;) I forgot that I define it in brew. So I'm back to square
> one in finding out why brew has problems on current bigforth.

You can't define [ENDIF] without knowing precisely how the [IF] parser
works. In bigForth, it uses a separate vocabulary where all bracketed
control structure words just increment or decrement a counter.

>> Should I add [ENDIF] to bigForth?
>
> sure, please do.

Done, at least in the svn repository.

Robert Epprecht

unread,
Sep 14, 2009, 8:20:27 AM9/14/09
to
Bernd Paysan <bernd....@gmx.de> writes:

>>> Robert Epprecht wrote:
>>>> don't know [ENDIF]
>>>
>>> Maybe this should ring your bell - there's no [ENDIF] in bigForth.

It looks like I have decided to make a fool of myself ;)

I don't know what devil drove me to write [ENDIF] instead of [THEN]
and not realizing that difference until right now. It shows that I
did not do much FORTH work lately...

Sorry for the noise,
Robert Epprecht

Robert Epprecht

unread,
Sep 14, 2009, 10:01:24 AM9/14/09
to
Robert Epprecht <eppr...@solnet.ch> writes:

>> bigForth. The failure of brew is mysterious.

indeed...

ANS bigFORTH 386-Linux rev. 2.3.1

The " ' false is key? " part does not work when i start it from the shell:
time bigforth -d 16M -e ": page ; ' false is key? CREATE noterm \
CREATE transit-12-bench include brew.fs"
[...]
Bus Error ! brew
real 0m0.289s
user 0m0.256s
sys 0m0.028s

It works without:
time bigforth -d 16M -e ": page ; CREATE noterm \
CREATE transit-12-bench include brew.fs"
Result is valid.
real 0m52.215s (times on a slow cpu)
user 0m51.799s
sys 0m0.420s


But changing benchstrings and starting from the benchmark suite still fails:

runbrew=": page ; CREATE noterm CREATE transit-12-bench include brew.fs"
BENCH="brew" FORTH=bigforth ./run
[0.004 0.004 0.008 ] brew

strange...

Robert Epprecht

Robert Epprecht

unread,
Sep 14, 2009, 10:46:36 AM9/14/09
to
Robert Epprecht <eppr...@solnet.ch> writes:

> But there is another problem: gforth and gforth-fast behave different
> on my 64bit system.

I found the time to test gforth-fast from cvs now. It's doing fine.

Robert Epprecht

Bernd Paysan

unread,
Sep 14, 2009, 11:37:37 AM9/14/09
to
Robert Epprecht wrote:

> Robert Epprecht <eppr...@solnet.ch> writes:
>
>>> bigForth. The failure of brew is mysterious.
> indeed...
>
> ANS bigFORTH 386-Linux rev. 2.3.1
>
> The " ' false is key? " part does not work when i start it from the shell:
> time bigforth -d 16M -e ": page ; ' false is key? CREATE noterm \
> CREATE transit-12-bench include brew.fs"

KEY? is not deferred in bigFORTH, it goes through a vector table. You could
make a fast dummy-input table with

: blocker BEGIN AGAIN ;
Input: none blocker false 0< blocker false [

and then use NONE to switch to that input.

Better: If you want brew to check for KEY? in normal mode and not in
benchmark mode, simply define : KEY? FALSE ; before compiling the benchmark.
No need to mess around with the system's key, all you want is brew's use of
KEY? to return false. This should be ultra-portable.

Robert Epprecht

unread,
Sep 14, 2009, 11:58:03 AM9/14/09
to
Bernd Paysan <bernd....@gmx.de> writes:

> KEY? is not deferred in bigFORTH,

yes, I have seen hat

' false is key?
is from Antons benchmark suite, not from brew.

> No need to mess around with the system's key, all you want is brew's use of
> KEY? to return false. This should be ultra-portable.

> If you want brew to check for KEY? in normal mode and not in
> benchmark mode, simply define : KEY? FALSE ; before compiling the benchmark.

Yes, that's what I thought too.

Robert Epprecht

Robert Epprecht

unread,
Sep 15, 2009, 2:57:47 AM9/15/09
to
(Sorry for broken references/threading, the news server does not carry
the original posting any more)

>> bigForth. The failure of brew is mysterious.

The following small change in 'benchstrings' from Antons suite works well
here for brew with ANS bigFORTH 386-Linux rev. 2.3.1 and should not harm
on other FORTH systems.

runbrew=": page ; : key? false ; CREATE noterm CREATE transit-12-bench\
include brew.fs"

Robert Epprecht

Albert van der Horst

unread,
Sep 15, 2009, 7:00:20 AM9/15/09
to
In article <874or54...@e901.home>,

Robert Epprecht <eppr...@solnet.ch> wrote:
>Robert Epprecht <eppr...@solnet.ch> writes:
>
>>> bigForth. The failure of brew is mysterious.
>indeed...
>
>ANS bigFORTH 386-Linux rev. 2.3.1
>
>The " ' false is key? " part does not work when i start it from the shell:
>time bigforth -d 16M -e ": page ; ' false is key? CREATE noterm \
> CREATE transit-12-bench include brew.fs"
>[...]
> Bus Error ! brew
>real 0m0.289s
>user 0m0.256s
>sys 0m0.028s

This brings up the issue what KEY? is supposed to do if input is
from a stream.

For example INDEX traditionally can be stopped by pressing a
key. (INDEX shows the first lines of a series of blocks.)

echo 1 300 INDEX | lina > indexlines.txt

doesn't print the 300 index lines, but stops with a system error
message.

This looks like a reasonable policy:
KEY? returns FALSE if it can be established that input is
not from a normal interactive terminal.

(The intended purpose in INDEX is interruption. Most Forth's
can interrupt an infinite loop nowadays without breaking off
the Forth itself. )

>Robert Epprecht

Bernd Paysan

unread,
Sep 15, 2009, 7:31:22 AM9/15/09
to
Albert van der Horst wrote:
> This brings up the issue what KEY? is supposed to do if input is
> from a stream.
>
> For example INDEX traditionally can be stopped by pressing a
> key. (INDEX shows the first lines of a series of blocks.)
>
> echo 1 300 INDEX | lina > indexlines.txt
>
> doesn't print the 300 index lines, but stops with a system error
> message.
>
> This looks like a reasonable policy:
> KEY? returns FALSE if it can be established that input is
> not from a normal interactive terminal.
>
> (The intended purpose in INDEX is interruption. Most Forth's
> can interrupt an infinite loop nowadays without breaking off
> the Forth itself. )

I have a word called STOP? for this purpose: if you press a key, it looks at
that key, and if the key is escape or ctlr-c, it stops. Otherwise, it
pauses, i.e. it waits for another key to continue. Typical use: INDEX or
WORDS display lots of information, you press space to pause and another
space to continue or escape to stop (not very useful with today's computer
speed, because WORDS completes before you can press a key ;-).

My suggestion: STOP? should not check the keyboard when the input is not
from an interactive terminal.

Anton Ertl

unread,
Sep 14, 2009, 4:34:22 PM9/14/09
to
Bernd Paysan <bernd....@gmx.de> writes:

>Anton Ertl wrote:
>
>> Bernd Paysan <bernd....@gmx.de> writes:
>>>As an example: Marcel Hendrix wondered why GCC was so much faster on
>>>Wurstkessel than Forth. He compiled the code in iForth64, and made a
>>>few trivial changes - and then achieved about the same speed as GCC.
>>
>> And this demonstrates what? He did not compile the same program with
>> gcc and with iForth, so the situation is different from what I
>> discussed.
>
>This demonstrates that other systems can improve performance with some
>trivial changes, as well.

So what? This has nothing to do with the situation of having a
portable program that runs on several systems, and runs slow on one of
them.

>And after all, it *is* the same program in
>GCC and iForth, one is generated Forth from Forth, the other generated C
>from Forth.

I think the compilers see it differently. Neither would work as
desired if you fed it the other output.

>> That's a false dichotomy. Will fixing the code/data problem in the
>> compiler break your code?
>
>I switch to "single space" in VFX Forth with "-idata". It breaks pretty
>soon when I don't do that.

VFX in its default mode works and run fast on the application
benchmarks, at least four of them. For those where it does not work,
there are words missing:

benchgc: FALIGNED is missing
brew: XT>STRING is missing

So VFX does not appear to break pretty quickly with the default
switch.

>A native Forth makes it a lot more
>difficult to separate code and data without funny results (like e.g.
>embedding a string literal into a definition, what I do in i18n.fs, the
>first place where +idata breaks).

Oh, so you are talking about your code that breaks in VFX. Well, how
about making a small change to your program in order to make it more
portable; that's IMO much more reasonable than to ask people to bother
with finding out how the performance quirks of various systems affect
their working program, and then to implement workarounds for these
performance quirks in their program.

>Sidenode: Why don't I simply use SLiteral in i18n.fs? Because the
>compiled strings aren't just string literals - they are part of a
>translation data base. The string has a native form, and pointers to
>translated forms, which are patched in later. The code there would be
>even easier, if I knew that I have completely separated instruction and
>code. But then, porting to Gforth would require changing that code
>again.

Ah, that explains it. I was wondering what the problem is. SLITERAL
would be simpler and much cleaner in Gforth if we did not mix data and
threaded code. Still, as far as I can see the current SLITERAL in
Gforth would continue to work if we separated the threaded code from
the data. So what's the problem in your more capable variant?

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2009: http://www.euroforth.org/ef09/

Anton Ertl

unread,
Sep 14, 2009, 4:23:56 PM9/14/09
to
You can download the new version at the old place:

http://www.complang.tuwien.ac.at/forth/appbench.zip

(you can also still download the old version under appbench-1.0.zip).

The new version contains the same benchmarks, and they run in the same
time, but there have been some tweaks in both the way that some of the
benchmarks are invoked, and in the ways that (I suggest) the Forth
systems are invoked. Many of these changes were suggested by helpful
postings here. Thank you!

In addition, the benchmark suite contains a graph showing the results
I measured with various systems on a 2GHz Opteron 270 box. You can
also find this graph on

http://www.complang.tuwien.ac.at/forth/appbench/Results.eps

(view with a Postscript viewer).

And here's the README:

This is a set of Forth application benchmarks, in contrast to the
small benchmarks that are usually used for benchmarking Forth systems.

This is version 1.1 of the benchmark suite. The benchmarks are the
same, so the results should be comparable. The changes are some
improvements in the calling sequences for the Forth systems and the
benchmarks, increasing the number of successful system/benchmark
combinations. There are also now results shown in Results.eps.

Most of these applications (except cross and vmgen, which are not run
by default) should be portable between Forth systems, but a test with
Gforth (several versions), bigForth 2.3.1, iforth 2.1.2541, SP-Forth
4.20 Build 001 and vfxlin 4.05 Alpha 8 [build 0207] showed the
following systems to be working:

Benchmark Systems
benchgc gforth iforth
brainless bigforth gforth vfxlin
brew bigforth gforth
cd16sim bigforth gforth iforth spf4 vfxlin
fcp bigforth gforth spf4 vfxlin
lexex bigforth gforth vfxlin

That's with various workarounds for various systems (see below). It
may be easy for knowledgeable users to enable options in the systems
to make them work with more benchmarks, though.


HOW TO RUN THE BENCHMARKS

There is a bash script "run" that makes it easy. cd into the
appbench directory, then say, e.g.:

BENCH="cd16sim lexex" FORTH=vfxlin ./run

and after a while you will see output like:

[0.500 0.500 0.512 ] cd16sim
[4.040 4.048 4.052 ] lexex

These are the user time from three runs of the benchmarks; the results
for each benchmark are sorted to make it easier to see or compute the
median, best, and worst results. The standard output of the
benchmarks is suppressed. To make it easier to see what's going on,
there is also another script "test" that performs only one run and
shows the standard output. Use it, e.g., like this:

BENCH="cd16sim lexex" FORTH=vfxlin ./test

In my testing I used the following variants for the FORTH variable:

FORTH="bigforth -d 16M -r 8k -e "
FORTH="gforth-fast -m 16M ../setup/gforth.fs -e " #default
FORTH="iforth"
FORTH="spf4 ../setup/spf.f"
FORTH="vfxlin : ms@ ticks ; : 0. 0 0 ;"

The benchmark names possible in BENCH are:

BENCH="benchgc brainless brew cd16sim fcp lexex cross vmgen"

The default is all but cross and vmgen.

You can change the number of runs by setting RUNS:

RUNS=5 BENCH="cd16sim lexex" FORTH=vfxlin ./run

The default number of RUNS is 3.

You can also change the command used for timing by setting TIME, but
that command should produce only a single number on stderr as output.
The default is TIME, and the TIMEFORMAT="%U" per default to report
only user time.


DOWNLOADING AND INSTALLING

You can download this package from
http://www.complang.tuwien.ac.at/forth/appbench.zip

Just unpack it anywhere, then cd into the appbench-1.1 directory and
benchmark away.


ABOUT THE BENCHMARKS

Benchmark Author Purpose, Remarks
bench-gc 1.0 Anton Ertl Garbage Collector
brainless 0.0.2 David Kuehling Chess
brew 0.2.0 Robert Epprecht Evolutionary playground
cd16sim v11 Brad Eckert CPU emulator
cross 0.7.x Bernd Paysan Forth cross compiler, Gforth only, short run, unstable performance
fcp 1.31-64 Ian Osgood Chess
lexex Gerry Jackson Scanner Generator
vmgen 0.7.x Anton Ertl Interpreter generator, Gforth-only, short run

Brainless and brew produce different results for 32-bit and 64-bit systems.

If you want to see how the benchmarks are invoked on the Forth level,
look into the file benchstrings.


RESULTS

Some results from Gforth (gforth-fast) 0.7.0, bigForth 2.3.1, iforth
2.1.2541, SP-Forth 4.20 Build 001 and vfxlin 4.05 Alpha 8 [build 0207]
are shown in Results.eps. This is an Encapsulated Postscript file, so
you need a Postscript viewer like gv or GSview to view it. The
scaling of the results is Gforth-centric, that's because this chart
was originally created to illustrate Gforth performance.


ACKNOWLEDGMENTS

Thanks to all the authors of the applications that serve here as
benchmarks for making them available and portable.


FEEDBACK

If you have any feedback (problem reports, fixes, new benchmarks
etc.), you can contact me by email at
an...@mips.complang.tuwien.ac.at.

Anton Ertl

Anton Ertl

unread,
Sep 14, 2009, 3:00:53 PM9/14/09
to
steph...@mpeforth.com (Stephen Pelc) writes:
>On Mon, 31 Aug 2009 19:58:53 GMT, an...@mips.complang.tuwien.ac.at
>(Anton Ertl) wrote:
>
>>I found a workaround for that:
>>
>>FORTH="vfxlin variable x : ms@ x @ 1 x +! ;" BENCH=fcp ./test
>>
>>That works.
>
>: ms@ ( -- ums ) ticks ;
>
>RTFM is your friend.

I looked for quite a while in the manual for the following things:

1) Something appropriate for MS@.

2) How to make "0." work.

3) How to make FALIGNED work.

I did not find anything in the manual that helped me with 1) and 2),
resulting in my definition above for MS@ and also the definition

: 0. 0 0 ;

The lack of a concept index was no help, so I had to make do with the
table of contents, but I still did not find what I needed.

For problem 3) I got the impression that I should load one of the FP
package files mentioned in the manual, but none of them comes with the
vfxlin packages I tried.

Independent of VFX, the definition of MS@ I gave above is a better
fallback for fcp than the current fallback.

- anton

Anton Ertl

unread,
Sep 14, 2009, 1:22:03 PM9/14/09
to
Robert Epprecht <eppr...@solnet.ch> writes:
>' false is key?
>is from Antons benchmark suite, not from brew.

Sorry, I forgot to take that our from the brew strings like I did for
the other benchmarks.

>> No need to mess around with the system's key, all you want is brew's use of
>> KEY? to return false. This should be ultra-portable.
>
>> If you want brew to check for KEY? in normal mode and not in
>> benchmark mode, simply define : KEY? FALSE ; before compiling the benchmark.
>
>Yes, that's what I thought too.

I thought that some of the terminal control stuff on Gforth uses KEY?
internally, but brew works with ": KEY? FALSE ;". Good.

Anton Ertl

unread,
Sep 14, 2009, 11:14:50 AM9/14/09
to
Robert Epprecht <eppr...@solnet.ch> writes:
>regarding brew and 64bit:
>
>I installed a Debian/Lenny 64bit system this morning to be able to
>test brew on a 64 bit system and built gforth 0.7.0. My very first
>test results look like brew is doing fine on 64bit (I was very aware
>of different cell sizes when writing brew).
>
>That the benchmarks do not give the same results on 32bit and 64bit
>was to be expected due to integer math overflow.

I was confused by the difference in outputs, where brew says on a
32-bit system: "Result is valid." while it complains about a lot of
differences in the result on 64-bit systems.

>Nothing in brew will
>prevent the mutation process to produce gens that play tricks with
>integer overflow. This is fully intended. Nevertheless it should be
>possible to construct a benchmark where no 32bit integer overflow
>happens but it's not an easy task. Another possibility could be to
>change the used gene primitives so that this will not happen. I will
>think about and do some tests. Feedback welcome.

If you implement the arithmetic that may overflow as, say

: +32 + $ffffffff and ;

etc., you should get the same results.

But for many purposes it does not matter if the results are comparable
between 32-bit and 64-bit systems, as long as I know that the 64-bit
results are correct. Maybe you should just adapt the
validity-checking code, and not bother with the other stuff.
Brainless and an older version of benchgc have similar problems. I
managed to solve them for benchgc, because there it came only from
alignment and cell size issues.

>But there is another problem: gforth and gforth-fast behave different
>on my 64bit system.
>
>Please try the following two comands to check on your system
>~/brew$ gforth -e "CREATE transit-12-bench" brew.s
>~/brew$ gforth-fast -e "CREATE transit-12-bench" brew.s

On my AMD64 system with Gforth 0.7.0 these produce the same output.

Anton Ertl

unread,
Sep 14, 2009, 10:47:12 AM9/14/09
to
Robert Epprecht <eppr...@solnet.ch> writes:
>Robert Epprecht <eppr...@solnet.ch> writes:
>
>>> bigForth. The failure of brew is mysterious.
>indeed...
>
>ANS bigFORTH 386-Linux rev. 2.3.1
>
>The " ' false is key? " part does not work

Yes, that's a Gforth feature.

>But changing benchstrings and starting from the benchmark suite still fails:
>
>runbrew=": page ; CREATE noterm CREATE transit-12-bench include brew.fs"
>BENCH="brew" FORTH=bigforth ./run
>[0.004 0.004 0.008 ] brew

I guess you should use it with FORTH="bigforth -d 16M -e".

Use ./test instead of ./run to see what is happening.

Bernd Paysan

unread,
Sep 17, 2009, 11:07:04 AM9/17/09
to
Anton Ertl wrote:

> steph...@mpeforth.com (Stephen Pelc) writes:
>>On Mon, 31 Aug 2009 19:58:53 GMT, an...@mips.complang.tuwien.ac.at
>>(Anton Ertl) wrote:
>>
>>>I found a workaround for that:
>>>
>>>FORTH="vfxlin variable x : ms@ x @ 1 x +! ;" BENCH=fcp ./test
>>>
>>>That works.
>>
>>: ms@ ( -- ums ) ticks ;
>>
>>RTFM is your friend.
>
> I looked for quite a while in the manual for the following things:
>
> 1) Something appropriate for MS@.

I find TICKS horribly inaccurate, but it actually gives "milliseconds" (in
10ms granularity). Also ms waits for "milliseconds" with the same
inaccuracy. I therefore added the necessary code to my bigForth harness,
where I use gettimeofday. This should work:

LocalExtern: gettimeofday int gettimeofday ( int * , int * );

Create timeval 0 , 0 ,
Create timezone 0 , 0 ,

: ms@ ( -- ms ) timeval timezone gettimeofday drop
timeval 2@ 1000 * swap 1000 / + ;

> 2) How to make "0." work.

char . dp-char !

> 3) How to make FALIGNED work.

It's a NOP. It shouldn't cause problems other than that it won't align
floats very good.

> For problem 3) I got the impression that I should load one of the FP
> package files mentioned in the manual, but none of them comes with the
> vfxlin packages I tried.

I use

include %lib%/Ndp387.fth

Set

basepath = /usr/share/doc/VfxForth

in ~/.VfxForth.ini

otherwise the %lib% expansion won't work. Stephen: VfxForth creates a
.VfxForth.ini when there's none in your home directory. This should set
basepath to something reasonable (i.e. the default location of the
distribution), not to an empty string.

Bernd Paysan

unread,
Sep 17, 2009, 11:11:49 AM9/17/09
to
Anton Ertl wrote:
>>Sidenode: Why don't I simply use SLiteral in i18n.fs? Because the
>>compiled strings aren't just string literals - they are part of a
>>translation data base. The string has a native form, and pointers to
>>translated forms, which are patched in later. The code there would be
>>even easier, if I knew that I have completely separated instruction and
>>code. But then, porting to Gforth would require changing that code
>>again.
>
> Ah, that explains it. I was wondering what the problem is. SLITERAL
> would be simpler and much cleaner in Gforth if we did not mix data and
> threaded code. Still, as far as I can see the current SLITERAL in
> Gforth would continue to work if we separated the threaded code from
> the data. So what's the problem in your more capable variant?

Using AHEAD and THEN to hide the allocated memory would indeed work for both
settings.

Albert van der Horst

unread,
Sep 17, 2009, 6:17:40 PM9/17/09
to
In article <17192246....@elfi.zetex.de>,

Bernd Paysan <bernd....@gmx.de> wrote:
>
>I find TICKS horribly inaccurate, but it actually gives "milliseconds" (in
>10ms granularity). Also ms waits for "milliseconds" with the same
>inaccuracy. I therefore added the necessary code to my bigForth harness,
>where I use gettimeofday. This should work:

I get around that by using the Pentium cycle counter for TICKS.
Then wait 1000 MS (depending on the windows timer) to get
a reasonable value for TICKS-PER-SECOND.

Later MS@ is based on TICKS and TICKS-PER-SECOND , not on MS.

<SNIP>

>
>--
>Bernd Paysan

Groetjes Albert

Robert Epprecht

unread,
Sep 18, 2009, 6:04:25 AM9/18/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:

> Robert Epprecht <eppr...@solnet.ch> writes:
>> regarding brew and 64bit:
>>
>> I installed a Debian/Lenny 64bit system this morning to be able to
>> test brew on a 64 bit system and built gforth 0.7.0. My very first
>> test results look like brew is doing fine on 64bit (I was very aware
>> of different cell sizes when writing brew).
>>
>> That the benchmarks do not give the same results on 32bit and 64bit
>> was to be expected due to integer math overflow.
>
> I was confused by the difference in outputs, where brew says on a
> 32-bit system: "Result is valid." while it complains about a lot of
> differences in the result on 64-bit systems.

Brews evolutionary process is highly chaotical. Even a tiny difference
anywhere in the process is likely to produce *completely* different
results after a while. So small differences will most often produce
*a lot* of differences when checking results. I wrote that code too
detect differences when using different FORTH implementations.

>> Nothing in brew will
>> prevent the mutation process to produce gens that play tricks with
>> integer overflow. This is fully intended. Nevertheless it should be
>> possible to construct a benchmark where no 32bit integer overflow
>> happens but it's not an easy task. Another possibility could be to
>> change the used gene primitives so that this will not happen. I will
>> think about and do some tests. Feedback welcome.
>
> If you implement the arithmetic that may overflow as, say
>
> : +32 + $ffffffff and ;
>
> etc., you should get the same results.

Sure, but that's not the way I want to deal with it, if better
possibilities do work.

> But for many purposes it does not matter if the results are comparable
> between 32-bit and 64-bit systems, as long as I know that the 64-bit
> results are correct. Maybe you should just adapt the
> validity-checking code, and not bother with the other stuff.

Yes, that's part of what I plan to do. But there is more involved.

> Brainless and an older version of benchgc have similar problems. I
> managed to solve them for benchgc, because there it came only from
> alignment and cell size issues.

Brew should not have cell size issues, I hope.

BTW: brew has the option of counting how many times each application
defined word was executed during the run (including compilation) of
the benchmark. Search for COUNTING-WORDS if someone is interested
what exactly is done during the bench. I did not test this in the
version Anton made up for the benchmark suite, but I intend to do
so for a next version. It would be quite easy to tailor benchmarks
for specific issues like integer/float maths, speed of compilation
or evaluation and so on. Please tell me, if there's interest in such
benchmarks.

Robert Epprecht

Robert Epprecht

unread,
Sep 18, 2009, 6:54:51 AM9/18/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:

> VFX in its default mode works and run fast on the application
> benchmarks, at least four of them. For those where it does not work,
> there are words missing:
>
> benchgc: FALIGNED is missing
> brew: XT>STRING is missing

I wasn't aware of the possibility to download a VFX version for Linux.
I will try to adapt brew to it.

Brew needs a word to find the name of a word when given an xt:
XT>STRING ( xt --- addr count )

How would one define that in VFX?

No need for special cases, brew will not call that words i.e. for an xt
from NONAME: or in cases where there are different names associated with
one xt.

Robert Epprecht

Stephen Pelc

unread,
Sep 18, 2009, 1:29:07 PM9/18/09
to
On Fri, 18 Sep 2009 12:54:51 +0200, Robert Epprecht
<eppr...@solnet.ch> wrote:

>How would one define that in VFX?

>NAME ( xt -- nfa )

e.g.

' dup >name count type

Stephen


--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

Robert Epprecht

unread,
Sep 19, 2009, 6:50:10 AM9/19/09
to
steph...@mpeforth.com (Stephen Pelc) writes:

> On Fri, 18 Sep 2009 12:54:51 +0200, Robert Epprecht
> <eppr...@solnet.ch> wrote:
>
>>How would one define that in VFX?
>
>>NAME ( xt -- nfa )

> ' dup >name count type

Ah, so the common way works in vfx, thank you.


I have downloaded the vfxlin evaluation version and am trying to
make brew compatible to it. I have tons of questions now...

I could not find the documentation yet.
Do I have to generate it with DocGen first? (how?).

How do I make 'HELP <name>' work?
It does neither display help nor any error message here.

How can an application find out if it's running on vfx?
I have tried many variations of things like
s" VFX" environment? .
but could not find the right string yet.

How do I activate floating point words?

Robert Epprecht

Anton Ertl

unread,
Sep 19, 2009, 8:22:21 AM9/19/09
to
Robert Epprecht <eppr...@solnet.ch> writes:
>I have downloaded the vfxlin evaluation version and am trying to
>make brew compatible to it. I have tons of questions now...
>
>I could not find the documentation yet.

/usr/share/doc/VfxLin.pdf

The problem I have is finding something in the documentation:-).

>How do I activate floating point words?

include /usr/share/doc/VfxForth/Lib/Ndp387.fth

Robert Epprecht

unread,
Sep 19, 2009, 2:56:47 PM9/19/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:

> Robert Epprecht <eppr...@solnet.ch> writes:
>>I have downloaded the vfxlin evaluation version and am trying to
>>make brew compatible to it. I have tons of questions now...

>>I could not find the documentation yet.
> /usr/share/doc/VfxLin.pdf

Thank you, must be my dislike of the pdf format that I had
overlooked this one.

> The problem I have is finding something in the documentation:-).

Same here...
Currently I try to find out how to OPEN-DIR in vfx.

>>How do I activate floating point words?
> include /usr/share/doc/VfxForth/Lib/Ndp387.fth

But this one now was really well hidden...
I would never have searched /usr/share/doc for that and the filename
doesn't sound too much like the thing I was loking for.

Thanks so much for the hint ;)

Robert

Gerry

unread,
Sep 19, 2009, 3:31:15 PM9/19/09
to
Anton Ertl wrote:
[...]

> Benchmark Systems
> benchgc gforth iforth
> brainless bigforth gforth vfxlin
> brew bigforth gforth
> cd16sim bigforth gforth iforth spf4 vfxlin
> fcp bigforth gforth spf4 vfxlin
> lexex bigforth gforth vfxlin
>
> That's with various workarounds for various systems (see below). It
> may be easy for knowledgeable users to enable options in the systems
> to make them work with more benchmarks, though.

I've just been looking at why lexex doesn't run with SP-Forth and it
appears that both stacks are too small and there is insufficient
dataspace available. I've emailed the developers to see if there is a
way to increase the sizes of these and am stuck until they reply,
unless anyone else knows how to do it.

Gerry

Stephen Pelc

unread,
Sep 21, 2009, 6:46:59 AM9/21/09
to
On Sat, 19 Sep 2009 12:50:10 +0200, Robert Epprecht
<eppr...@solnet.ch> wrote:

>I could not find the documentation yet.
>Do I have to generate it with DocGen first? (how?).

No. The VFX tree usually ends up /usr/share/doc.

>How do I make 'HELP <name>' work?
>It does neither display help nor any error message here.

Within the VFX tree is VfxLin.pdf - that's the manual and VfxLin.vix,
the index file. Some versions may call these VfxMan.*. Once you
have found the manual, use it to configure the PDF help system,
your editor of choice, and set the BASEPATH text macro if it isn't
right on the *second* run. The VFXPATH macro is for the source tree.
Evaluation system users often set it to point to the root of the
VFX install directory.

>How can an application find out if it's running on vfx?
>I have tried many variations of things like
>s" VFX" environment? .
>but could not find the right string yet.

[defined] VFXforth ...
is always good.

there are also
Target_386_Windows
Target_386_Linux
...

>How do I activate floating point words?

include %vfxpath%/lib/Ndp387.fth

We'll be having another pass over the packaging scripts over the
next few weeks. Having to make five packages is a real PITA.

Robert Epprecht

unread,
Sep 22, 2009, 3:34:13 AM9/22/09
to
Thanks a lot for your informations.

steph...@mpeforth.com (Stephen Pelc) writes:

> On Sat, 19 Sep 2009 12:50:10 +0200, Robert Epprecht
> <eppr...@solnet.ch> wrote:

> and set the BASEPATH text macro if it isn't right on the *second* run.

It was still empty. I did set it to /usr/share/doc/VfxForth, is this right?
(No reference to BASEPATH found in the documenation)

> VFXPATH macro is for the source tree.
> Evaluation system users often set it to point to the root of the
> VFX install directory.

/usr/share/doc/VfxForth works for me.

>>How do I activate floating point words?

> include %vfxpath%/lib/Ndp387.fth
^
I had to write %vfxpath%/Lib/Ndp387.fth with capital L in .../Lib/...
^ ^
Is this just a typo or do I have to use .../lib/... for windows user?
^

> We'll having another pass over the packaging scripts over the
> next few weeks.
Great, in the .deb the dependencies are not right yet, I think.

> Having to make five packages is a real PITA.

Must be a similar feeling like trying to make a FORTH application
of some complexity run on different FORTH systems ;)

Right now I am struggling with the following issues:

How do I get the return value from system calls, after using a word
like ShellCmd?

How do I define (or activate?) open-dir and close-dir?

Robert Epprecht

Gerry

unread,
Sep 22, 2009, 5:53:06 AM9/22/09
to

Investigating further on a simpler example I found a bug in SP-Forth
4.20 which makes lexex fail by entering an infinite loop even if stack
sizes etc are adjusted. In a simplified form the bug is:

: x >r begin r@ . r@ -255 0 within while r> 1+ >r repeat r> drop ;
Ok
-3 x
-3 -2 -1 -256 Ok

It should output:

-3 -2 -1 0 Ok

The problem is that r> 1+ >r inside the loop increments -1 to -256
I've reported it to the developers.

Gerry


Stephen Pelc

unread,
Sep 22, 2009, 7:56:09 AM9/22/09
to
>> include %vfxpath%/lib/Ndp387.fth
> ^
>I had to write %vfxpath%/Lib/Ndp387.fth with capital L in .../Lib/...
> ^ ^
>Is this just a typo or do I have to use .../lib/... for windows user?

Typo!


^
>> We'll having another pass over the packaging scripts over the
>> next few weeks.
>Great, in the .deb the dependencies are not right yet, I think.
>
>> Having to make five packages is a real PITA.
>Must be a similar feeling like trying to make a FORTH application
>of some complexity run on different FORTH systems ;)

It's almost worse! Read the Debian Policy Manual for a good laugh.

>Right now I am struggling with the following issues:
>
>How do I get the return value from system calls, after using a word
>like ShellCmd?

In the current version, use:

[undefined] (>Shell) [if]
also system
: (>Shell) \ z$ -- ior
\ *G Execute the given zero-terminated string as a shell command.
PreSH ssystem PostSH
;
previous
[then]

It will all change in the next release and (>Shell) will be exposed.

>How do I define (or activate?) open-dir and close-dir?

Please contact me directly (remove the XXX) with a spec of what you
want.

ayc

unread,
Sep 23, 2009, 7:11:48 AM9/23/09
to
On 22 сен, 12:53, "Gerry" <ge...@jackson9000.fsnet.co.uk> wrote:

> Gerry wrote:
> The problem is that r> 1+ >r inside the loop increments -1 to -256
> I've reported it to the developers.

This bug was fixed 7 months ago,
http://spf.cvs.sourceforge.net/viewvc/spf/src/macroopt.f?r1=1.63&r2=1.64
please get CVS version for tests.
Thank you,

Gerry

unread,
Sep 23, 2009, 8:47:18 AM9/23/09
to
On 23 Sep, 12:11, ayc <chere...@gmail.com> wrote:

> On 22 ÓÅÎ, 12:53, "Gerry" <ge...@jackson9000.fsnet.co.uk> wrote:
>
> > Gerry wrote:
> > The problem is that r> 1+ >r inside the loop increments -1 to -256
> > I've reported it to the developers.
>
> This bug was fixed 7 months ago,http://spf.cvs.sourceforge.net/viewvc/spf/src/macroopt.f?r1=1.63&r2=1.64

> please get CVS version for tests.
> Thank you,

Well I downloaded the 4.20 Windows executable from http://spf.sourceforge.net/
last week. It would have been nice if that was a more recent version -
it would have saved me wasting my time.

Gerry

ygrek

unread,
Sep 26, 2009, 4:31:48 AM9/26/09
to
Wed, 23 Sep 2009 05:47:18 -0700, Gerry wrote:

> Well I downloaded the 4.20 Windows executable from
> http://spf.sourceforge.net/ last week. It would have been nice if that
> was a more recent version - it would have saved me wasting my time.

There will be 4.21 sometimes soon I think. Meanwhile it is really easy to
recompile with bug fixed, just replace src/macroopt.f with
http://spf.cvs.sourceforge.net/viewvc/spf/src/macroopt.f
and run src/compile.bat

> I've just been looking at why lexex doesn't run with SP-Forth and it
> appears that both stacks are too small and there is insufficient
> dataspace available.

Indeed, dataspace is too small. Solution -- run spf and
10000000 TO IMAGE-SIZE S" spf4-big.exe" SAVE
and use spf4-big for tests. Increasing stacks is more involved but appears
to be not needed in this particular case.

Now lexex runs fine, but compare-files fails because ref.tt has dos line endings
and stt.fth - unix eols (on linux), so one needs to use DOS-LINES for lexex
but not other tests.

Here are the updated results :

spf ../setup-spf.f
[2.304 2.316 2.452 ] cd16sim
[2.308 2.388 2.400 ] brainless
[3.024 3.068 3.096 ] fcp
[13.941 14.185 14.537 ] lexex
vfxlin
[0.816 0.816 0.836 ] cd16sim
[10.349 10.609 10.665 ] lexex
gforth-fast -m 16M ../setup-gforth.fs -e
[22.217 22.589 22.973 ] cd16sim
[180.751 181.815 182.551 ] lexex

script to launch :

FORTH="spf ../setup-spf.f "
echo $FORTH
BENCH="cd16sim brainless fcp" FORTH="$FORTH" ./run
BENCH="lexex" FORTH="$FORTH DOS-LINES" ./run

FORTH="vfxlin "
echo $FORTH
BENCH="cd16sim lexex" FORTH="$FORTH" ./run

FORTH="gforth-fast -m 16M ../setup-gforth.fs -e "
echo $FORTH
BENCH="cd16sim lexex" FORTH="$FORTH" ./run

and setup-spf.f :

lib/include/defer.f \ DEFER
lib/ext/case.f \ CASE
lib/include/facil.f \ TIME&DATE
lib/include/string.f \ /STRING
lib/include/core-ext.f \ 0>
lib/include/double.f \ 2CONSTANT
lib/include/float.f
lib/ext/caseins.f
lib/include/ansi-file.f
\ ~mak/place.f \ PLACE
\ lib/ext/struct.f

\ $10
: NOTFOUND
OVER C@ [CHAR] $ = IF
BASE @ >R HEX 1 /STRING ['] ?SLITERAL CATCH R> BASE ! THROW EXIT THEN
NOTFOUND ;

: bounds OVER + SWAP ;

\ hide REQUIRED
:NONAME
S" REQUIRED" FORTH-WORDLIST SEARCH-WORDLIST-NFA IF 1+ 1 SWAP C! THEN ; EXECUTE

: INCLUDED HEAP-COPY >R R@ ASCIIZ> INCLUDED R> FREE THROW ;
: INCLUDE ;
: PERFORM @ EXECUTE ;
\ : \G 0 PARSE 2DROP ; IMMEDIATE

\ 'c
: NOTFOUND
OVER C@ [CHAR] ' = OVER 2 = AND IF DROP 1+ C@ POSTPONE LITERAL EXIT THEN
NOTFOUND ;

> I've emailed the developers to see if there is a
> way to increase the sizes of these and am stuck until they reply,
> unless anyone else knows how to do it.

Looks like no one received this.. At least it appeared on bugtracker purely
by chance (after reading this newsgroup).

--
ygrek

Marcel Hendrix

unread,
Sep 27, 2009, 4:09:29 PM9/27/09
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote Re: Application benchmark suite v1.1 available
[..]

> The new version contains the same benchmarks, and they run in the same
> time, but there have been some tweaks in both the way that some of the
> benchmarks are invoked, and in the ways that (I suggest) the Forth
> systems are invoked. Many of these changes were suggested by helpful
> postings here. Thank you!

I found the time to analyse the old v1.0 and find out why some of the benches
didn't work with iForth.

A general remark is that iForth should be correctly setup ( environment variables
IFORTH and IFORTHBIN ) and started with the commandline "INCLUDE iforth.prf CR"
(no quotes). Without the commandline the results may not be representative.

Benchmark comment time (s)
--------- ----------------------------- -------------------
benchgc works as is 1.073/1.001 (513936/268624)
brainless patch (1) 0.518/0.515
brew wrong assumption (2) -- / --
cd16sim works as is 0.376/0.383
fcp patch (3) 3.047/2.999
lexex will work in next release (4) 7.193/4.609

( run on a 2.66 GHz Intel Core2-Duo E8200 using iForth64/iForth32 )


(1)
-- run.frt ----------------------------------------------------------------
WARNING @ WARNING OFF
ANEW -run

: cputime ( -- dus dns ) ?MS #1000 UM* 0. ;
: IS STATE @ IF POSTPONE [IS] ELSE ['] IS EXECUTE ENDIF ; IMMEDIATE

include benchmark.fs
benchmark

-run
WARNING !
-- --------------------------------------------------------------------------

(2)
Brew can not work because it uses the word xt>string ( xt -- c-addr u ) on
inlined code fragments (names are unfindable). A source code change is needed.
There is also a 5 second delay in the files especially for iForth (terminal
>> 25 x 80 ), and iforth.prf is reloaded without testing if it's there
already (it will work for the benchmark).

(3)
-- run.frt ------------------------------------------------------------------
WARNING @ WARNING OFF

ANEW -run
include fcp-1.31-64.f
TIMER-RESET bench CR .ELAPSED

-run
WARNING !
-- --------------------------------------------------------------------------

(4)
In principle : CREATE CREATE DOES> ; fixes lexex, however, in the current
iForth release DOES> has a bug when used interpretively. In the next release
CREATEd words will not be immediate anymore.

-marcel

Robert Epprecht

unread,
Sep 28, 2009, 4:40:57 AM9/28/09
to
m...@iae.nl (Marcel Hendrix) writes:

> I found the time to analyse the old v1.0 and find out why some of
> the benches didn't work with iForth.

> A general remark is that iForth should be correctly setup
> ( environment variables IFORTH and IFORTHBIN )

In private discussions with you about making brew compatible to the new
iForth version you suspected that IFORTH and IFORTHBIN could be set wrong
on my system (which I do not think is the case, btw).

Could you give us a test scenario so that a user can doublecheck if these
environment variables are set to the right path?

> started with the commandline "INCLUDE iforth.prf CR" (no quotes).
> Without the commandline the results may not be representative.

> Benchmark comment time (s)
> --------- ----------------------------- -------------------

> brew wrong assumption (2) -- / --

> (2)


> Brew can not work because it uses the word xt>string ( xt -- c-addr u ) on
> inlined code fragments (names are unfindable).
> A source code change is needed.


We are discussing the needed changes in pm, but the following applies
for all optimizing compilers.

Even the cleverest compiler can possibly do things, that in some rare
cases will not work with some application code. I think this is even
more the case with a language like FORTH, where the programmer has any
freedom to do things programmers of most other languages would hardly
dream of. System programmers can not forsee what application programmers
might try to do on their systems.

In my opinion it is *very essential*, that it remains possible to switch
certain compiler optimizers off, before compiling the critical code
segments and back on again later.


> There is also a 5 second delay in the files especially for iForth
> (terminal >>> 25 x 80 ),

Oh, sorry for that!
This was an archaic relict from from the very beginning of our tests
with brew on iForth. It was only the case with iForth, btw. I have
removed it now.

> iforth.prf is reloaded without testing if it's there alreay

How do I test that?


I am working on more brew compatibility with Antons benchmark suite.
Feedback welcome. A new test version should be ready quite soon.

Robert Epprecht

Marcel Hendrix

unread,
Sep 28, 2009, 2:47:45 PM9/28/09
to
Robert Epprecht <eppr...@solnet.ch> writes Re: Application benchmark suite v1.1 available

> m...@iae.nl (Marcel Hendrix) writes:

>> I found the time to analyse the old v1.0 and find out why some of
>> the benches didn't work with iForth.

>> A general remark is that iForth should be correctly setup
>> ( environment variables IFORTH and IFORTHBIN )

> In private discussions with you about making brew compatible to the new
> iForth version you suspected that IFORTH and IFORTHBIN could be set wrong
> on my system (which I do not think is the case, btw).

> Could you give us a test scenario so that a user can doublecheck if these
> environment variables are set to the right path?

Responses typical for Windows:

FORTH> s" IFORTHBIN" SEARCH-ENV$ 0= THROW cr TYPE
C:\dfwforth\ifwinnt\bin\iforth.img ok
FORTH> s" IFORTH" SEARCH-ENV$ 0= THROW cr TYPE
C:\dfwforth ok


A level 2 check tests if these strings are reasonable:


FORTH> dir C:\dfwforth\ifwinnt\bin\iforth.img Volume in drive C has no label.
Volume Serial Number is F44B-12ED

Directory of C:\dfwforth\ifwinnt\bin

09/27/2009 08:13 8,585,216 iforth.img
1 File(s) 8,585,216 bytes
0 Dir(s) 36,216,233,984 bytes free
ok
FORTH> dir C:\dfwforth Volume in drive C has no label.
Volume Serial Number is F44B-12ED

Directory of C:\dfwforth

09/27/2009 22:35 <DIR> .
09/27/2009 22:35 <DIR> ..
11/04/2007 13:40 421 authors
09/14/2009 07:10 160,337 bugs.txt
06/29/2008 13:18 <DIR> config
06/29/2008 13:19 <DIR> config64
09/27/2009 12:30 <DIR> dataf
09/27/2009 13:45 709 distribution.txt
09/27/2009 22:35 <DIR> examples
05/12/2008 11:44 4,698 faq.txt
08/05/2009 22:25 <DIR> generaldocs
01/09/2009 02:29 <DIR> iflinux
12/03/2005 10:24 <DIR> iforth
01/16/2006 07:31 20,059 iforth.jpg
05/30/2008 23:32 1,366,528 iforth3glossary_a4_vsn2.doc
05/30/2008 23:32 891,793 iforth3glossary_a4_vsn2.pdf
05/30/2008 22:41 726,469 iforth3glossary_ltr.pdf
12/03/2005 10:25 <DIR> ifwinnt
07/19/2009 23:48 <DIR> ifwinnt64
09/27/2009 15:05 <DIR> include
07/01/2006 09:41 378 install.cmd
08/10/2009 19:17 <DIR> install-linux
09/27/2009 12:15 310 install-linux.sh
08/08/2009 11:48 4,552 readme
08/11/2009 10:04 7,525 todo.txt
12 File(s) 3,183,779 bytes
13 Dir(s) 36,216,233,984 bytes free


> We are discussing the needed changes in pm, but the following applies
> for all optimizing compilers.

> Even the cleverest compiler can possibly do things, that in some rare
> cases will not work with some application code. I think this is even
> more the case with a language like FORTH, where the programmer has any
> freedom to do things programmers of most other languages would hardly
> dream of. System programmers can not forsee what application programmers
> might try to do on their systems.

> In my opinion it is *very essential*, that it remains possible to switch
> certain compiler optimizers off, before compiling the critical code
> segments and back on again later.

You would need to very clearly define what you consider an "optimization."
I consider that an impossible task, given all the possible ways Forth can
be implemented. The standard tells you what guarantees a programmer has, all
other things are features. If you identify an essential feature it may be
useful to other programmers, so please factor it in a system dependency
file. Maybe it will be standardized in due time.

The iForth feature you discovered has stopped working, but a more general
mechanism (access to any word header information) has come to replace it.
Doubtlessly, other big Forths have similar mechanisms. Now brew has become
a standard benchmark, it has high chances of catalyzing unified syntax.

>> iforth.prf is reloaded without testing if it's there alreay

> How do I test that?

iForth.prf should always be loaded (but it can be empty). I think the
offending line was there in order to be able to use NEEDS -terminal.
NEEDS is currently a kernel word.

> I am working on more brew compatibility with Antons benchmark suite.
> Feedback welcome. A new test version should be ready quite soon.

I hope to see it very soon.

-marcel

0 new messages