Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #52178 > unrolled thread

Stack Operator Symbols

Started bytrans <transfire@gmail.com>
First post2016-10-24 20:42 -0700
Last post2016-10-30 18:19 +0100
Articles 20 on this page of 65 — 19 participants

Back to article view | Back to comp.lang.forth


Contents

  Stack Operator Symbols trans <transfire@gmail.com> - 2016-10-24 20:42 -0700
    Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-25 01:58 -0700
    Re: Stack Operator Symbols november.nihal@gmail.com - 2016-10-25 10:52 -0700
    Re: Stack Operator Symbols Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> - 2016-10-27 19:13 -0400
      Re: Stack Operator Symbols "Elizabeth D. Rather" <erather@forth.com> - 2016-10-27 17:08 -1000
        Re: Stack Operator Symbols "HAA" <someone@microsoft.com> - 2016-10-28 21:53 +1000
          Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-28 20:42 -0700
            Re: Stack Operator Symbols Walter Banks <walter@bytecraft.com> - 2016-10-29 17:15 -0400
              Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-29 17:27 -0700
          Re: Stack Operator Symbols "Elizabeth D. Rather" <erather@forth.com> - 2016-10-28 20:56 -1000
        Re: Stack Operator Symbols Paul Rubin <no.email@nospam.invalid> - 2016-10-29 00:46 -0700
          Re: Stack Operator Symbols Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-10-29 04:30 -0500
            Re: Stack Operator Symbols rickman <gnuarm@gmail.com> - 2016-10-29 16:58 -0400
            Re: Stack Operator Symbols Paul Rubin <no.email@nospam.invalid> - 2016-10-29 14:21 -0700
              Re: Stack Operator Symbols Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-10-30 04:03 -0500
                Re: Stack Operator Symbols Paul Rubin <no.email@nospam.invalid> - 2016-10-30 18:06 -0700
                  Re: Stack Operator Symbols Spiros Bousbouras <spibou@gmail.com> - 2016-10-31 01:43 +0000
                    Re: Stack Operator Symbols Paul Rubin <no.email@nospam.invalid> - 2016-10-30 19:23 -0700
                      Re: Stack Operator Symbols Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-10-31 05:13 -0500
                        Re: Stack Operator Symbols albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-10-31 12:42 +0100
                        Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-10-31 12:12 +0000
                          Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-10-31 14:49 +0000
                            Re: Stack Operator Symbols mhx@iae.nl - 2016-10-31 13:17 -0700
                            Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-11-03 16:38 +0000
                      Re: Stack Operator Symbols Spiros Bousbouras <spibou@gmail.com> - 2016-11-20 14:33 +0000
                  Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-10-31 08:35 +0000
              Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-10-30 11:01 +0000
                Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-30 10:01 -0700
              Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-11-03 14:46 -0700
                Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-11-04 23:04 +0000
                  Re: Stack Operator Symbols Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> - 2016-11-05 03:16 -0400
          Re: Stack Operator Symbols peter.m.falth@gmail.com - 2016-10-29 09:13 -0700
            Re: Stack Operator Symbols "HAA" <someone@microsoft.com> - 2016-10-30 08:47 +1100
              Re: Stack Operator Symbols trans <transfire@gmail.com> - 2016-10-29 14:57 -0700
                Re: Stack Operator Symbols "HAA" <someone@microsoft.com> - 2016-10-30 09:20 +1100
          Re: Stack Operator Symbols Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> - 2016-10-29 18:46 -0400
            Re: Stack Operator Symbols Paul Rubin <no.email@nospam.invalid> - 2016-10-29 19:45 -0700
              Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-29 20:29 -0700
                Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-29 20:47 -0700
                  Re: Stack Operator Symbols Cecil Bayona <cbayona@cbayona.com> - 2016-10-29 23:15 -0500
                    Re: Stack Operator Symbols "Elizabeth D. Rather" <erather@forth.com> - 2016-10-29 21:37 -1000
                      Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-30 10:07 -0700
              Re: Stack Operator Symbols "Elizabeth D. Rather" <erather@forth.com> - 2016-10-29 21:35 -1000
                Re: Stack Operator Symbols "HAA" <someone@microsoft.com> - 2016-10-31 13:11 +1100
                  Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-30 20:02 -0700
                  Re: Stack Operator Symbols "Elizabeth D. Rather" <erather@forth.com> - 2016-10-30 22:08 -1000
                  Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-10-31 09:02 +0000
                    Re: Stack Operator Symbols "HAA" <someone@microsoft.com> - 2016-11-03 20:49 +1100
                      Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-11-03 15:33 +0000
                        Re: Stack Operator Symbols Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> - 2016-11-03 16:55 -0400
                          Re: Stack Operator Symbols anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-11-03 22:21 +0000
    Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-27 20:31 -0700
      Re: Stack Operator Symbols november.nihal@gmail.com - 2016-10-28 09:52 -0700
        Re: Stack Operator Symbols hughaguilar96@gmail.com - 2016-10-28 20:32 -0700
    Re: Stack Operator Symbols Mark Wills <markwills1970@gmail.com> - 2016-10-30 04:49 -0700
      Re: Stack Operator Symbols Coos Haak <htrofhc@gmail.com> - 2016-10-30 14:49 +0100
        Re: Stack Operator Symbols Matthias Koch <matthias.koch@hot.uni-hannover.de> - 2016-10-31 13:31 +0100
          Re: Stack Operator Symbols Coos Haak <htrofhc@gmail.com> - 2016-10-31 14:12 +0100
            Re: Stack Operator Symbols Matthias Koch <matthias.koch@hot.uni-hannover.de> - 2016-10-31 15:03 +0100
          Re: Stack Operator Symbols Mark Wills <markwills1970@gmail.com> - 2016-11-03 14:22 -0700
            Re: Stack Operator Symbols Coos Haak <htrofhc@gmail.com> - 2016-11-04 00:46 +0100
          Re: Stack Operator Symbols "HAA" <someone@microsoft.com> - 2016-11-05 13:14 +1100
      Re: Stack Operator Symbols trans <transfire@gmail.com> - 2016-10-30 06:50 -0700
        Re: Stack Operator Symbols trans <transfire@gmail.com> - 2016-10-30 08:56 -0700
        Re: Stack Operator Symbols albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-10-30 18:19 +0100

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#52335

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-10-31 12:12 +0000
Message-ID<2016Oct31.131235@mips.complang.tuwien.ac.at>
In reply to#52331
Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>Paul Rubin <no.email@nospam.invalid> wrote:
>> Spiros Bousbouras <spibou@gmail.com> writes:
>>> "you wouldn't write code like this in Forth for any other purpose than
>>> a benchmark".
>> 
>> Would you code that function differently if it were for some purpose
>> other than benchmarking?
>
>Perhaps.  To start with, the outermost recursive call could be turned
>into a while loop and the args reordered to (z y x) to simplify stack
>handling.

Given that the arguments are rotated all the way, I don't see how z y
x would help.  Please enlighten me with code.

>Also, the stack depth might be prohibitively large on some
>systems, so maybe further action would be required.

Not a problem on the systems I tried, but a stack effect of

( a b c -- a b c r )

might not just reduce stack depth, but also have other benefits.

- 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 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#52339

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-10-31 14:49 +0000
Message-ID<2016Oct31.154903@mips.complang.tuwien.ac.at>
In reply to#52335
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>>Paul Rubin <no.email@nospam.invalid> wrote:
>>> Spiros Bousbouras <spibou@gmail.com> writes:
>>>> "you wouldn't write code like this in Forth for any other purpose than
>>>> a benchmark".
>>> 
>>> Would you code that function differently if it were for some purpose
>>> other than benchmarking?
>>
>>Perhaps.  To start with, the outermost recursive call could be turned
>>into a while loop and the args reordered to (z y x) to simplify stack
>>handling.
>
>Given that the arguments are rotated all the way, I don't see how z y
>x would help.  Please enlighten me with code.
>
>>Also, the stack depth might be prohibitively large on some
>>systems, so maybe further action would be required.
>
>Not a problem on the systems I tried, but a stack effect of
>
>( a b c -- a b c r )
>
>might not just reduce stack depth, but also have other benefits.

I took all these ideas, and did two new versions:

\ variation for reducing data stack depth
: tak1 ( z y x -- z y x r )
    2dup < if
	1- recurse >r 1+ -rot ( x z y )
	1- recurse >r 1+ -rot ( y x z )
	1- recurse >r 1+ -rot ( z y x )
	r> r> r> recurse nip nip nip
    else
	2 pick
    then ;

\ variation that stack-juggles directly and eliminates the tail call of tak
: tak2 ( z y x -- r )
    2dup < if
	begin
	    2dup 4 pick 1- recurse >r \ z'
	    dup 2over 1- recurse >r   \ y'
	    1- recurse
	    2r> rot
	2dup >= until
    then
    2drop ;

Don't forget to reverse the parameters when calling them.

TAK1 is cute, but not tail-recursive (but, judging from the results,
this does not really hurt).  For TAK2, it's interesting how 2DUP and
2OVER enable us to use only one PICK; there might be other ways to
arrange the parameters and the recursive calls that allow using even
fewer words, but I guess one would need an exhaustive search to find
them.

Here are the results (Core i7-6700K):

       3dup-builtin 3dup-2pick  3dup-locals locals      tak1       tak2
gforth              1160859139  1239191117  1023792580  816129237  816266680
sf      472184708    533401690  1753487060  4529954652  356164897  356006772
vfxlin  490283220    401685949   721040449   700320112  352936074  352709005

The new versions are the fastest versions on all three systems, and
there is no significant speed difference between them on any of the
systems, which is surprising given that they are not that similar.

Strangely, the locals version is even slower on sf than yesterday; if
I repeat the measurements, I get a lot of variation, from 3.2G cycles
to 6.2G cycles; none of the runs was as fast as yesterday (3.0G
cycles).  There is something strange going on there.

One variation that I also thought about keeps X Y Z in variables A B
C, and there are 6 variations of TAK, one for each possible assignment
of X Y Z to the variables; instead of rotating the values, you call
the appropriate version of TAK; you decrease and increase the
variables for the first three recursions as in TAK1.  E.g., one
version might look like:

: tak-abc ( -- r )
  \ a=x, b=y, c=z
  y @ x @ < if
    -1 a +! tak-abc 1 a +!
    -1 b +! tak-cab 1 b +!
    -1 c +! tak-bca 1 c +1
    a @ b @ c @ 2>r >r c ! b ! a ! tak-abc r> 2r> c ! b ! a !
  else
    c @
  then ;

Not clearer than the existing solutions, longer, and probably slower,
and certainly unidiomatic (at least for me), I'll spare myself the
effort to do the other versions.

- 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 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#52349

Frommhx@iae.nl
Date2016-10-31 13:17 -0700
Message-ID<1c38c999-3434-4a96-884d-aa44cf6fe8e7@googlegroups.com>
In reply to#52339
On Monday, October 31, 2016 at 4:47:49 PM UTC+1, Anton Ertl wrote:
> anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> >Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
> >>Paul Rubin <no.email@nospam.invalid> wrote:
> >>> Spiros Bousbouras <spibou@gmail.com> writes:
> >>>> "you wouldn't write code like this in Forth for any other purpose than
> >>>> a benchmark".
> >>> 
> >>> Would you code that function differently if it were for some purpose
> >>> other than benchmarking?
> >>
> >>Perhaps.  To start with, the outermost recursive call could be turned
> >>into a while loop and the args reordered to (z y x) to simplify stack
> >>handling.
> >
> >Given that the arguments are rotated all the way, I don't see how z y
> >x would help.  Please enlighten me with code.
> >
> >>Also, the stack depth might be prohibitively large on some
> >>systems, so maybe further action would be required.
> >
> >Not a problem on the systems I tried, but a stack effect of
> >
> >( a b c -- a b c r )
> >
> >might not just reduce stack depth, but also have other benefits.
> 
> I took all these ideas, and did two new versions:
> 
> \ variation for reducing data stack depth
> : tak1 ( z y x -- z y x r )
>     2dup < if
> 	1- recurse >r 1+ -rot ( x z y )
> 	1- recurse >r 1+ -rot ( y x z )
> 	1- recurse >r 1+ -rot ( z y x )
> 	r> r> r> recurse nip nip nip
>     else
> 	2 pick
>     then ;
> 
> \ variation that stack-juggles directly and eliminates the tail call of tak
> : tak2 ( z y x -- r )
>     2dup < if
> 	begin
> 	    2dup 4 pick 1- recurse >r \ z'
> 	    dup 2over 1- recurse >r   \ y'
> 	    1- recurse
> 	    2r> rot
> 	2dup >= until
>     then
>     2drop ;
> 
> Don't forget to reverse the parameters when calling them.
> 
> TAK1 is cute, but not tail-recursive (but, judging from the results,
> this does not really hurt).  For TAK2, it's interesting how 2DUP and
> 2OVER enable us to use only one PICK; there might be other ways to
> arrange the parameters and the recursive calls that allow using even
> fewer words, but I guess one would need an exhaustive search to find
> them.
> 
> Here are the results (Core i7-6700K):
> 
>        3dup-builtin 3dup-2pick  3dup-locals locals      tak1       tak2
> gforth              1160859139  1239191117  1023792580  816129237  816266680
> sf      472184708    533401690  1753487060  4529954652  356164897  356006772
> vfxlin  490283220    401685949   721040449   700320112  352936074  352709005
> 
> The new versions are the fastest versions on all three systems, and
> there is no significant speed difference between them on any of the
> systems, which is surprising given that they are not that similar.
> 
> Strangely, the locals version is even slower on sf than yesterday; if
> I repeat the measurements, I get a lot of variation, from 3.2G cycles
> to 6.2G cycles; none of the runs was as fast as yesterday (3.0G
> cycles).  There is something strange going on there.

[..]

Here are 7 more results. Surprisingly, I also found very 
little difference in runtime. The version with locals is 
faster than using the stack?

ANEW -taks

: tak0 ( z y x -- t )
	2DUP >= IF 2DROP EXIT ENDIF 
	LOCALS| x y z |
	z  y  x 1- RECURSE >R
	x  z  y 1- RECURSE >R
	y  x  z 1- RECURSE R> R> RECURSE ;


: tak1  ( x y z -- t )
   over 3 pick >= IF  nip nip EXIT  ENDIF
   2 pick 1- 2 pick 2 pick ( -- x-1 y z )  recurse >r
   over 1- over 4 pick     ( -- y-1 z x )  recurse >r
   1- -rot                 ( -- z-1 x y )  recurse
   2r> rot                 ( -- r1 r2 r3 ) recurse ;

: tak2 ( z y x -- n )
  LOCALS| x y z |
  y x >= IF  z exit  ENDIF
  y x z 1- recurse
  x z y 1- recurse
  z y x 1- recurse
  recurse ;

: tak3 ( F: z y x -- n )
  FLOCALS| x y z |
  y x f>= IF  z EXIT  ENDIF
  y x z 1e f- recurse
  x z y 1e f- recurse
  z y x 1e f- recurse
  recurse ;

: tak_1 ( x y z -- x1- y z )  rot  1- -rot      ;
: tak_2 ( x y z -- y1- z x )  swap 1- -rot swap ;
: tak_3 ( x y z -- z1- x y )       1- -rot      ;

: tak4 	( x y z -- t )
  over 3 pick >= IF  nip nip EXIT THEN
  3dup tak_1 recurse >r    ( x y z -- x y z ) ( R: -- t1 )
  3dup tak_2 recurse >r    ( x y z -- x y z ) ( R: t1 -- t1 t2 )
       tak_3 recurse	   ( x y z -- t3 )
  r> swap r> -rot recurse ;

\ Or with some more thinking ...
: tak5 ( z y x -- t )
	2DUP >= IF 2DROP EXIT ENDIF 
	PARAMS| z y x |
	z  y  x 1- RECURSE >R
	x  z  y 1- RECURSE >R
	y  x  z 1- RECURSE R> R> RECURSE ;

\ Still more ...
: tak6 ( z y x -- t )
	DUP 2 PICK <= IF  2DROP EXIT  ENDIF 
	PARAMS| z y x |
	BEGIN
	  y x z 1- RECURSE  ( z1)
	  x z y 1- RECURSE  ( y1)
	  z y x 1- RECURSE  ( x1)
	  DUP 2 PICK <= IF  2DROP EXIT  ENDIF 
	  TO x TO y TO z
	AGAIN ;

\ Still more ...
CREATE _tak  HERE #19 #19 * #19 * DUP ALLOT ERASE

: 'tak ( z y x -- addr )
	#19 #19 *  *  SWAP #19 * + +  _tak + ; PRIVATE

: tak7 ( z y x -- t )
	DUP 2 PICK <= IF  2DROP EXIT  ENDIF 
	PARAMS| z y x |
	x y z 'tak C@ ?DUP ?EXIT
	y x z 1- RECURSE ( z1)
	x z y 1- RECURSE ( y1)
	z y x 1- RECURSE ( x1)
		 RECURSE 
	DUP x y z 'tak C! ;

: .TAKS ( -- )
	CR TIMER-RESET 	0 #10000 0 DO  DROP 6 #12 #18 tak0  LOOP ." \ 10000 times TAK0, " .ELAPSED ."  Result = " . ." (7)" 
	CR TIMER-RESET  0 #10000 0 DO  drop #18 #12 6 tak1  LOOP ." \ 10000 times TAK1, " .ELAPSED ."  Result = " . ." (7)" 
	CR TIMER-RESET 	0 #10000 0 DO  DROP 6 #12 #18 tak2  LOOP ." \ 10000 times TAK2, " .ELAPSED ."  Result = " . ." (7)" 
	CR TIMER-RESET 0e #10000 0 DO FDROP 6e 12e 18e tak3 LOOP ." \ 10000 times TAK3, " .ELAPSED ."  Result = " F. ." (7)" 
	CR TIMER-RESET  0 #10000 0 DO  DROP #18 #12 6 tak4  LOOP ." \ 10000 times TAK4, " .ELAPSED ."  Result = " . ." (7)" 
	CR TIMER-RESET 	0 #10000 0 DO  DROP 6 #12 #18 tak5  LOOP ." \ 10000 times TAK5, " .ELAPSED ."  Result = " . ." (7)" 
 	CR TIMER-RESET 	0 #10000 0 DO  DROP 6 #12 #18 tak6  LOOP ." \ 10000 times TAK6, " .ELAPSED ."  Result = " . ." (7)" 
	CR TIMER-RESET 	0 #10000 0 DO  DROP 6 #12 #18 tak7  LOOP ." \ 10000 times TAK7, " .ELAPSED ."  Result = " . ." (7)" ;

CR .( Try: .TAKS )

With these results:
Try: .TAKS  ok
FORTH> .taks
\ 10000 times TAK0, 1.829 seconds elapsed. Result = 7 (7)
\ 10000 times TAK1, 1.931 seconds elapsed. Result = 7 (7)
\ 10000 times TAK2, 1.948 seconds elapsed. Result = 7 (7)
\ 10000 times TAK3, 8.111 seconds elapsed. Result = 7.000000 (7)
\ 10000 times TAK4, 2.183 seconds elapsed. Result = 7 (7)
\ 10000 times TAK5, 1.995 seconds elapsed. Result = 7 (7)
\ 10000 times TAK6, 1.677 seconds elapsed. Result = 7 (7)
\ 10000 times TAK7, 0.000 seconds elapsed. Result = 7 (7) ok

Machine: 
CPU: Intel(R) Core(TM) i7-4930K CPU @ 3.40GHz
Logical processors: 12
Total DRAM available = 32702.8 MB.
DRAM currently available = 28144.0 MB.

Forth: 
iForth x64 server 1.21 (console), May 29 2016, 16:32:47.

-marcel

[toc] | [prev] | [next] | [standalone]


#52414

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-11-03 16:38 +0000
Message-ID<2016Nov3.173816@mips.complang.tuwien.ac.at>
In reply to#52339
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>I took all these ideas, and did two new versions:
>
>\ variation for reducing data stack depth
>: tak1 ( z y x -- z y x r )
>    2dup < if
>	1- recurse >r 1+ -rot ( x z y )
>	1- recurse >r 1+ -rot ( y x z )
>	1- recurse >r 1+ -rot ( z y x )
>	r> r> r> recurse nip nip nip
>    else
>	2 pick
>    then ;
>
>\ variation that stack-juggles directly and eliminates the tail call of tak
>: tak2 ( z y x -- r )
>    2dup < if
>	begin
>	    2dup 4 pick 1- recurse >r \ z'
>	    dup 2over 1- recurse >r   \ y'
>	    1- recurse
>	    2r> rot
>	2dup >= until
>    then
>    2drop ;
>
>Don't forget to reverse the parameters when calling them.
...
>The new versions are the fastest versions on all three systems, and
>there is no significant speed difference between them on any of the
>systems, which is surprising given that they are not that similar.

The lack of a speed difference should have made me more suspicius; I
mistakenly timed tak1 for the tak2 results.  Here are is the table
with the correct tak2 results (cycles on Core i7-6700K):

       3dup-builtin 3dup-2pick  3dup-locals locals      tak1       tak2
gforth              1160859139  1239191117  1023792580  816129237  633233631
sf      472184708    533401690  1753487060  4529954652  356164897  253178697
vfxlin  490283220    401685949   721040449   700320112  352936074  238431403

So TAK2 is the fastest version on all systems, and significantly
faster than the others.

- 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 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#52762

FromSpiros Bousbouras <spibou@gmail.com>
Date2016-11-20 14:33 +0000
Message-ID<dviYz.337429$IO.260330@fx45.am4>
In reply to#52323
[Crossposting to  comp.theory ]

On Sun, 30 Oct 2016 19:23:44 -0700
Paul Rubin <no.email@nospam.invalid> wrote:
> Spiros Bousbouras <spibou@gmail.com> writes:
> > "you wouldn't write code like this in Forth for any other purpose than
> > a benchmark".
> 
> Would you code that function differently if it were for some purpose
> other than benchmarking?

For ease of reference we're talking about
    def tak( x, y, z)
      if y < x
        tak(
             tak(x-1, y, z),
             tak(y-1, z, x),
             tak(z-1, x, y)
           )
      else
        z
      end
    end

and

    def tarai( x, y, z)
      if y < x
        tarai(
             tarai(x-1, y, z),
             tarai(y-1, z, x),
             tarai(z-1, x, y)
           )
      else
        y          # not z!
      end
    end

as defined in  en.wikipedia.org/wiki/Tak_(function) .Note that the wikipedia
article does not give the definition in relation to any specific programming
language so we're assuming that the subtraction always gives the mathematically
correct result.


Moving to your question , my first reaction is that tak is so artificial that
it would never arise in "real" code so the short answer is that I wouldn't code
it all  :-D

But if amazingly enough it did arise then I would perform some kind of
mathematical analysis to understand its behaviour. At the very least this needs
to be done to see how deeply the recursion may go so that we don't run out of
stack space. Beyond that , I was hoping to understand which integer arguments
get called during the recursion (depending on the original arguments) with the
possibility of storing them in an array or hash table or something and see if
it makes things faster. But it turns out you can do better than that ; it's
possible to "solve" the recursion completely i.e. rewrite the function in a way
which doesn't involve recursion at all.

Before I describe the solution we need some notation. We will distinguish
various cases. I use labels for each (sub)case , things like "2.1.2.2.1" .Each
subcase is associated with a condition which triggers the subcase and the
condition which triggers for example "2.1.2.2.1" is the conjunction of the
conditions which label  2 , 2.1 , 2.1.2 , 2.1.2.2 and 2.1.2.2.1 .The return
value for each subcase follows after "->" .

So for all integers x , y , z we define  tak-nr(x,y,z) as follows :

(1) y>=x  -> z
(2) y<x
    (2.1) x<z
        (2.1.1) x = y+1  -> x
        (2.1.2) x > y+1
            (2.1.2.1) z = x+1  -> y
            (2.1.2.2) z > x+1
                (2.1.2.2.1) z-x is even  -> x
                (2.1.2.2.2) z-x is odd   -> y+1
    (2.2) x=z  -> y
    (2.3) x>z
        (2.3.1) z>=y  -> y
        (2.3.2) y>z
            (2.3.2.1) y = z+1  -> y
            (2.3.2.2) y > z+1
                (2.3.2.2.1) x-y is even  -> z+1
                (2.3.2.2.2) x-y is odd  -> y

And that's all ! I'll leave it to someone else to find an elegant way to code
the above in Forth. Sadly , real world programming problems hardly ever admit
a solution as neat as this.

A proof that  tak-nr() satisfies the recursive relations is straightforward but
tedious ; one must go through all the  2* subcases , see in which subcase each
recursive call falls , calculate the final result both directly and by using
the return value from each recursive call and verify they are the same. To
prove that  tak-nr()  is the unique function which satisfies the recursive
relations takes a bit more work but is not hard.

Note that  tarai() also has a non recursive definition and in fact a much simpler
one. Annoyingly , the wikipedia article does not mention it but it can be seen at
mathworld.wolfram.com/TAKFunction.html .


Returning to benchmarking , I don't see what advantage  tak() or  tarai() offer
relative to say good old Fibonacci. Or even coding an algorithm which naturally
gets expressed in a recursive manner like quicksort for example. With the
latter you even end up with a piece of code which is useful for something else
apart from benchmarking. The references given above do not provide any insights
or explain why Takeuti defined  tarai() .The  wolfram.com  page mentions some
mathematical connections but does not give specifics.

-- 
I guess I should warn you , if I turn out to be particularly clear ,
you've probably misunderstood what I've said.
  From a 1988 speech at the Economic Club of New York by
  Alan Greenspan, Chairman of the Federal Reserve.

[toc] | [prev] | [next] | [standalone]


#52328

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-10-31 08:35 +0000
Message-ID<2016Oct31.093537@mips.complang.tuwien.ac.at>
In reply to#52321
Paul Rubin <no.email@nospam.invalid> writes:
>Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>> But there isn't much point benchmarking Forth with something that only
>> gets written in Forth as a benchmark, I would have thought.  To each
>> their own.  :-)

The whole point of this function in any language is just as a
benchmark; both for the original y-returning function and the
(probably more widespread) z-returning version; and that's the reason
why the difference between these versions was not noticed immediately.

However, in my compiler course I use it as test for the correctness of
argument handling (in the student's compiler).

>I compared it to some other languages.  Gforth was slower than C++ or
>Luajit but faster than Python or regular Lua.  I have the timings around
>here somewhere and can probably find and post them if anyone cares.

I care.  For Gforth, what version did you use, and who built it?
Also, if you use the "run" parameters, most of the time spent in
Gforth is in Gforth startup; that's why I used 32 16 8 tak in my
benchmark.

- 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 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#52307

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-10-30 11:01 +0000
Message-ID<2016Oct30.120150@mips.complang.tuwien.ac.at>
In reply to#52291
Paul Rubin <no.email@nospam.invalid> writes:
>Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>> first I'd try to understand how I got into a situation which needed 3DUP.
>
>I implemented the Tak function which is a widely used Lisp benchmark:
>
>  https://en.wikipedia.org/wiki/Tak_(function)
>
>I wrote a Gforth version with and without locals:
>
>  : tak-locals { x y z -- n}
>      y x >= if z else
>          x 1- y z recurse
>          y 1- z x recurse
>          z 1- x y recurse
>          recurse then ; 
>
>  : 3dup ( a b c -- a b c a b c ) >r 2dup r@ -rot r> ;
>  : tak ( x y z -- n ) 
>      -rot 2dup <=
>      if
>          2drop ( z ) 
>      else ( z x y )
>          3dup rot 1- -rot recurse >r     \ tak (1- z) x y
>          3dup 1- -rot recurse >r         \ tak (1- y) z x
>          -rot 1- -rot recurse            \ tak (1- x) y z
>          r> r> recurse
>      then ;
>
>  : run 18 12 6 tak cr . cr  ;

While this is unidiomatic, I am still interested in the performance
(mostly because there is one locals and one stack-juggling variant,
and it shows the state of locals implementation in current Forth
systems.  With one fix and the inclusion of the "{" syntax for
SwiftForth, I get the following code (including calling setup);
results below.

0 [if]
for FORTH in "$HOME/gforth/gforth-fast -e" "sf include $HOME/gforth/compat/anslocal.fs" vfxlin; do echo $FORTH
perf stat -x" " -e cycles -e instructions $FORTH "include tak.4th 32 16 8 tak . cr bye"
perf stat -x" " -e cycles -e instructions $FORTH ": 3dup ( a b c -- a b c a b c ) >r 2dup r@ -rot r> ; include tak.4th 32 16 8 tak . cr bye"
perf stat -x" " -e cycles -e instructions $FORTH ": 3dup dup 2over rot ; include tak.4th 32 16 8 tak . cr bye"
perf stat -x" " -e cycles -e instructions $FORTH ": 3dup 2 pick 2 pick 2 pick ; include tak.4th 32 16 8 tak . cr bye"
perf stat -x" " -e cycles -e instructions $FORTH ": 3dup { a b c } a b c a b c ; include tak.4th 32 16 8 tak . cr bye"
perf stat -x" " -e cycles -e instructions $FORTH "include tak.4th 32 16 8 tak-locals . cr bye"
done
[then]

: tak-locals { x y z -- n }
    y x >= if z else
        x 1- y z recurse
        y 1- z x recurse
        z 1- x y recurse
        recurse then ; 

[undefined] 3dup [if]
    : 3dup abort ;
[then]

: tak ( x y z -- n ) 
    -rot 2dup <=
    if
        2drop ( z ) 
    else ( z x y )
        3dup rot 1- -rot recurse >r     \ tak (1- z) x y
        3dup 1- -rot recurse >r         \ tak (1- y) z x
        -rot 1- -rot recurse            \ tak (1- x) y z
        r> r> recurse
    then ;

: run 18 12 6 tak cr . cr  ;

And here are the results (in cycles on a Core i7-6700K):

       3dup-builtin 3dup->r     3dup-2over  3dup-2pick  3dup-locals locals
gforth              1169048859  1111954861  1126237778  1236484564  1040181611
sf      472184708    608648663   565610695   533060680  1754120881  3014151164
vfxlin  490283220    467571494   412437509   401428644   723363281   699419259

Interesting results:

In sf locals is slower than 3dup-locals, and both are slower than the
same programs running on gforth.

3dup-2dup is the fastest Forth-defined version on both sf and VFX.

VFX has a builtin 3DUP, but it is slower in this benchmark than all
the Forth-defined 3DUPs; my guess is that the Forth-defined versions
work better with the inliner.  For SF the builtin 3DUP is the fastest.

- 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 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#52312

Fromhughaguilar96@gmail.com
Date2016-10-30 10:01 -0700
Message-ID<ff4e39e8-b311-40b5-8d21-75dd70d8bfb7@googlegroups.com>
In reply to#52307
On Sunday, October 30, 2016 at 4:36:26 AM UTC-7, Anton Ertl wrote:
> In sf locals is slower than 3dup-locals, and both are slower than the
> same programs running on gforth.

I pretty much figured out how SwiftForth locals work when I ported my rquotations code from VFX to SwiftForth --- locals in SwiftForth are extremely inefficient --- they are way over-complicated, and they don't have a register dedicated to the local-frame pointer but instead use a user-variable.

This is my rquotation code:
----------------------------------------------------------------------------

\ My code ( VFX or SwiftForth only) requires that the HOF does have local variables.

: rexit     ( --   )    rdrop ; 
: (r:)      ( -- r )    r@ 5 + ;    \ 5 is the size of a JMP instruction in 32-bit x86 
: r[        ( -- r )    postpone (r:)  postpone ahead ;  immediate 
: ]r        ( --   )    postpone rexit  postpone then ;  immediate 

VFX? [if]

code rex    ( r -- )    \ HumptyDumpty called this RCALL
    push edi            \ this is the HOF's LF which won't be used by the quotation 
    mov edi, 0 [edi]    \ this is the parent's LF which will be used by the quotation 
    mov eax, ebx
    mov ebx, 0 [ebp]  lea ebp, w [ebp]
    call eax
    pop edi             \ restore HOF's LF 
    next, end-code 
    
[then]    

SwiftForth? [if]

156 constant lf-offset  \ this is the offset for the local-frame in the user-variables (ESI is the user-variable base)

code rex    ( r -- )    \ HumptyDumpty called this RCALL
    lf-offset [esi] edx mov  
    edx push                    \ this is the HOF's LF which won't be used by the quotation 
    -4 [edx] eax mov            \ this is the old ESP
    0 [eax] eax mov             \ this is the parent's LF which will be used by the quotation
    eax lf-offset [esi] mov
    ebx eax mov  [drop]
    eax call
    lf-offset [esi] pop         \ restore HOF's LF
    ret end-code 
        
[then]

----------------------------------------------------------------------------

> 3dup-2dup is the fastest Forth-defined version on both sf and VFX.
> 
> VFX has a builtin 3DUP, but it is slower in this benchmark than all
> the Forth-defined 3DUPs; my guess is that the Forth-defined versions
> work better with the inliner.  For SF the builtin 3DUP is the fastest.

This is my 3DUP code in the novice-package:
----------------------------------------------------------------------------

macro: rover ( a b c -- a b c a )               
    2 pick ;

macro: 3dup ( a b c -- a b c a b c )
    rover rover rover ;

----------------------------------------------------------------------------

I wrote MACRO: way back in 2009 --- apparently this is not idiomatic (meaning, that it has not been approved by Elizabeth Rather) --- instead you worry about what works better with the inliner.

I predict that you are going to complain about my MACRO: using late-binding (you usually do). As a practical matter, nobody is going to tick 3DUP etc.. Also, there is some irony here --- I originally ported my early-binding MACRO: from UR/Forth to ANS-Forth, but this worked on SwiftForth but not on gForth because FIND was broken (it doesn't work on a variety of standard words such as ; etc.), so you said that this proved that I didn't know anything about Forth programming --- then I wrote the late-binding version in response.

Now with my disambiguifiers, I have fixed the problem with FIND being broken. The irony here is that you actually invented the disambiguifiers in that same thread in which you said that I didn't know anything about Forth because I expected FIND to work on ; etc. (my background at that time was mostly Forth-83 and I expected FIND to work). Later on I came up with the disambiguifiers myself, and only later remembered that you had actually invented the disambiguifiers earlier. Also, later on when reading about Mini-OOF I found out that Bernd Paysan was using disambiguifiers too, so apparently the concept is well known. The irony here is that you and Bernd Paysan (both Forth-200x committee members) now refuse to acknowledge that disambiguifiers work for fixing FIND --- you don't want to admit that ANS-Forth is broken --- you can't admit this, because you are both appointed to the Forth-200x committee by Elizabeth Rather and hence have to say that ANS-Forth is flawless.

[toc] | [prev] | [next] | [standalone]


#52421

Fromhughaguilar96@gmail.com
Date2016-11-03 14:46 -0700
Message-ID<e8f51ed1-7535-48c2-85eb-b0fcfe714ea8@googlegroups.com>
In reply to#52291
On Saturday, October 29, 2016 at 2:21:56 PM UTC-7, Paul Rubin wrote:
> Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
> > first I'd try to understand how I got into a situation which needed 3DUP.
> 
> I implemented the Tak function which is a widely used Lisp benchmark:
> 
>   https://en.wikipedia.org/wiki/Tak_(function)
> 
> I wrote a Gforth version with and without locals:
> 
>   : tak-locals { x y z -- n}
>       y x >= if z else
>           x 1- y z recurse
>           y 1- z x recurse
>           z 1- x y recurse
>           recurse then ; 
> 
>   : 3dup ( a b c -- a b c a b c ) >r 2dup r@ -rot r> ;
>   : tak ( x y z -- n ) 
>       -rot 2dup <=
>       if
>           2drop ( z ) 
>       else ( z x y )
>           3dup rot 1- -rot recurse >r     \ tak (1- z) x y
>           3dup 1- -rot recurse >r         \ tak (1- y) z x
>           -rot 1- -rot recurse            \ tak (1- x) y z
>           r> r> recurse
>       then ;
> 
>   : run 18 12 6 tak cr . cr  ;
> 
> Using 3dup seems natural here.  Writing an asm version defeats the idea
> of benchmarking Forth with this function.

Here is yet another version:

: tak ( x y z -- n )  
    >r                          \ -- x y
    dup third >= if
        2drop  r>
    else
        over 1-     over        r@          recurse -rot    \ -- new-x x y
        dup 1-      r@          fourth      recurse -rot    \ -- new-x new-y x y
        r> 1-       rot         rot         recurse         \ -- new-x new-y new-z
        recurse  then ;

This was pretty meaningless, but I was bored...

[toc] | [prev] | [next] | [standalone]


#52447

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-11-04 23:04 +0000
Message-ID<2016Nov5.000427@mips.complang.tuwien.ac.at>
In reply to#52421
hughaguilar96@gmail.com writes:
>Here is yet another version:
>
>: tak ( x y z -- n )  
>    >r                          \ -- x y
>    dup third >= if
>        2drop  r>
>    else
>        over 1-     over        r@          recurse -rot    \ -- new-x x y
>        dup 1-      r@          fourth      recurse -rot    \ -- new-x new-y x y
>        r> 1-       rot         rot         recurse         \ -- new-x new-y new-z
>        recurse  then ;
>
>This was pretty meaningless, but I was bored...

       3dup-builtin 3dup-2pick  locals      tak1       tak2       tak-hugh
gforth              1160859139  1023792580  816129237  633233631  964385503
sf      472184708    533401690  4529954652  356164897  253178697  484259253
vfxlin  490283220    401685949   700320112  352936074  238431403  330347074

- 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 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#52452

FromRod Pemberton <NeedNotReplyHere@xrsevnneqk.cem>
Date2016-11-05 03:16 -0400
Message-ID<20161105031612.7c74c720@_>
In reply to#52447
On Fri, 04 Nov 2016 23:04:27 GMT
anton@mips.complang.tuwien.ac.at (Anton Ertl) wrote:

> hughaguilar96@gmail.com writes:

> >Here is yet another version:
> >
> >: tak ( x y z -- n )    
> >    >r                          \ -- x y  
> >    dup third >= if
> >        2drop  r>
> >    else
> >        over 1-     over        r@          recurse -rot    \ --
> > new-x x y dup 1-      r@          fourth      recurse -rot    \ --
> > new-x new-y x y  
> >        r> 1-       rot         rot         recurse         \ --
> >        r> new-x new-y new-z  
> >        recurse  then ;
> >
> >This was pretty meaningless, but I was bored...  
> 
>        3dup-builtin 3dup-2pick  locals      tak1       tak2
> tak-hugh gforth              1160859139  1023792580  816129237
> 633233631  964385503 sf      472184708    533401690  4529954652
> 356164897  253178697  484259253 vfxlin  490283220    401685949
> 700320112  352936074  238431403  330347074
>

As Hugh's code wasn't the fastest, I guess Hugh will need links to the
tak benchmark code to compare.

tak benchmark, code, and timings for various languages:
http://web.archive.org/web/20050306154941/http://www.lib.uchicago.edu/keith/crisis/benchmarks/tak/

tak for Forth (this4th link in "The Programs" section)
http://web.archive.org/web/20050306172823/http://www.lib.uchicago.edu/keith/crisis/benchmarks/tak/tak.4th


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#52287

Frompeter.m.falth@gmail.com
Date2016-10-29 09:13 -0700
Message-ID<4dbd03bc-5817-4908-a91c-3546d7676305@googlegroups.com>
In reply to#52283
On Saturday, 29 October 2016 09:46:21 UTC+2, Paul Rubin  wrote:
> "Elizabeth D. Rather" <erather@forth.com> writes:
> > I wrote Forth professionally for 30 years without using PICK, ROLL, or
> > -ROLL, suffering zero inconvenience.
> 
> I needed a 3DUP word recently, and wrote something like:
> 
>    : 3dup ( a b c -- a b c a b c ) >r 2dup r@ -rot r> ;
> 
> Later I saw someone else's implementation:
> 
>    : 3dup ( a b c -- a b c a b c ) 2 pick 2 pick 2 pick ;
> 
> which I thought was much more symmetric and natural.  Of course for
> non-purists,
> 
>    : 3dup { a b c } a b c a b c ;
> 
> is the simplest of all.

With a good code generator it should not matter. his is what mine get

: 3dup >r 2dup r@ -rot r> ; 3DUP redefined  ok
see 3dup
  A49E2C   40914E  19   C80000   5 normal  3DUP

  40914E 8B4500                 mov     eax , [ebp]
  409151 8945F4                 mov     [ebp-Ch] , eax
  409154 8B4504                 mov     eax , [ebp+4h]
  409157 8945F8                 mov     [ebp-8h] , eax
  40915A 895DFC                 mov     [ebp-4h] , ebx
  40915D 8D6DF4                 lea     ebp , [ebp-Ch]
  409160 C3                     ret     near
 ok
: 3dup 2 pick 2 pick 2 pick ; 3DUP redefined  ok
see 3dup
  A49E44   409161  19   C80000   5 normal  3DUP

  409161 8B4500                 mov     eax , [ebp]
  409164 8945F4                 mov     [ebp-Ch] , eax
  409167 8B4504                 mov     eax , [ebp+4h]
  40916A 8945F8                 mov     [ebp-8h] , eax
  40916D 895DFC                 mov     [ebp-4h] , ebx
  409170 8D6DF4                 lea     ebp , [ebp-Ch]
  409173 C3                     ret     near
 ok

: 3dup {: a b c :} a b c a b c ; 3DUP redefined  ok
see 3dup
  A49E74   409174  19   C80000   5 normal  3DUP

  409174 8B4500                 mov     eax , [ebp]
  409177 8945F4                 mov     [ebp-Ch] , eax
  40917A 8B4504                 mov     eax , [ebp+4h]
  40917D 8945F8                 mov     [ebp-8h] , eax
  409180 895DFC                 mov     [ebp-4h] , ebx
  409183 8D6DF4                 lea     ebp , [ebp-Ch]
  409186 C3                     ret     near

BR
Peter

[toc] | [prev] | [next] | [standalone]


#52293

From"HAA" <someone@microsoft.com>
Date2016-10-30 08:47 +1100
Message-ID<nv35fa$17ut$1@gioia.aioe.org>
In reply to#52287
peter.m.falth@gmail.com wrote:
> On Saturday, 29 October 2016 09:46:21 UTC+2, Paul Rubin  wrote:
> > "Elizabeth D. Rather" <erather@forth.com> writes:
> > > I wrote Forth professionally for 30 years without using PICK, ROLL, or
> > > -ROLL, suffering zero inconvenience.
> >
> > I needed a 3DUP word recently, and wrote something like:
> >
> >    : 3dup ( a b c -- a b c a b c ) >r 2dup r@ -rot r> ;
> >
> > Later I saw someone else's implementation:
> >
> >    : 3dup ( a b c -- a b c a b c ) 2 pick 2 pick 2 pick ;
> >
> > which I thought was much more symmetric and natural.  Of course for
> > non-purists,
> >
> >    : 3dup { a b c } a b c a b c ;
> >
> > is the simplest of all.
>
> With a good code generator it should not matter. his is what mine get
> [...]
>
> BR
> Peter

Even if you had such a code generator you must still settle on one.  I'd
choose the version that on most systems is likely to produce the best
result.  It will be PICK - no stack juggling and no locals overhead.


[toc] | [prev] | [next] | [standalone]


#52294

Fromtrans <transfire@gmail.com>
Date2016-10-29 14:57 -0700
Message-ID<749aac8c-d2ae-4476-b9c9-48d0310a57ff@googlegroups.com>
In reply to#52293
On Saturday, October 29, 2016 at 5:48:32 PM UTC-4, HAA wrote:

> Even if you had such a code generator you must still settle on one.  I'd
> choose the version that on most systems is likely to produce the best
> result.  It will be PICK - no stack juggling and no locals overhead.

I thought PICK was generally frond upon.

[toc] | [prev] | [next] | [standalone]


#52295

From"HAA" <someone@microsoft.com>
Date2016-10-30 09:20 +1100
Message-ID<nv37bh$1b13$1@gioia.aioe.org>
In reply to#52294
trans wrote:
> On Saturday, October 29, 2016 at 5:48:32 PM UTC-4, HAA wrote:
>
> > Even if you had such a code generator you must still settle on one.  I'd
> > choose the version that on most systems is likely to produce the best
> > result.  It will be PICK - no stack juggling and no locals overhead.
>
> I thought PICK was generally frond upon.

PICK is designed to access items deep in the stack.  The situations
you need this is rare but they happen as in this case.  PICK is fast
because it's just an indexed array fetch.


[toc] | [prev] | [next] | [standalone]


#52296

FromRod Pemberton <NeedNotReplyHere@xrsevnneqk.cem>
Date2016-10-29 18:46 -0400
Message-ID<20161029184635.4cd709eb@_>
In reply to#52283
On Sat, 29 Oct 2016 00:46:20 -0700
Paul Rubin <no.email@nospam.invalid> wrote:

> "Elizabeth D. Rather" <erather@forth.com> writes:

> > I wrote Forth professionally for 30 years without using PICK, ROLL,
> > or -ROLL, suffering zero inconvenience.  
> 
> I needed a 3DUP word recently, and wrote something like:
> 
>    : 3dup ( a b c -- a b c a b c ) >r 2dup r@ -rot r> ;
> 
> Later I saw someone else's implementation:
> 
>    : 3dup ( a b c -- a b c a b c ) 2 pick 2 pick 2 pick ;
> 
> which I thought was much more symmetric and natural.  Of course for
> non-purists,
> 
>    : 3dup { a b c } a b c a b c ;
> 
> is the simplest of all.

Alex McDonald has a solver based on code from Anton Ertl, IIRC.  I
also have another based on Java code by Peter Sovietov.

So, there are many ways to implement 3DUP depending on what Forth words
you want to use.  Here are a few:

: 3DUP DUP >R SWAP DUP >R SWAP >R >R DUP R> SWAP R> SWAP R> R> ;
: 3DUP OVER >R >R OVER R> SWAP OVER R> SWAP ;
: 3DUP >R OVER OVER R@ -ROT R> ;
: 3DUP >R NUP TUCK R@ -ROT R> ;
: 3DUP >R 2DUP R@ -ROT R> ;
: 3DUP >R R@ R> 2OVER ROT ;
: 3DUP DUP 2SWAP 2TUCK ROT ;
: 3DUP DUP 2OVER ROT ;


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#52300

FromPaul Rubin <no.email@nospam.invalid>
Date2016-10-29 19:45 -0700
Message-ID<87wpgqlfm9.fsf@nightsong.com>
In reply to#52296
Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> writes:
> : 3DUP DUP 2OVER ROT ;

Doh, I missed that one.  Nice.

[toc] | [prev] | [next] | [standalone]


#52301

Fromhughaguilar96@gmail.com
Date2016-10-29 20:29 -0700
Message-ID<1a2e8656-80a5-47b7-b401-b52e55ab0c13@googlegroups.com>
In reply to#52300
On Saturday, October 29, 2016 at 7:45:03 PM UTC-7, Paul Rubin wrote:
> Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> writes:
> > : 3DUP DUP 2OVER ROT ;
> 
> Doh, I missed that one.  Nice.

Here are some tests under VFX:

: test1  2 pick 2 pick 2 pick ;  ok
see test1 
TEST1 
( 004E98C0    8D6DF4 )                LEA       EBP, [EBP+-0C]
( 004E98C3    8B550C )                MOV       EDX, [EBP+0C]
( 004E98C6    895500 )                MOV       [EBP], EDX
( 004E98C9    8B5510 )                MOV       EDX, [EBP+10]
( 004E98CC    895504 )                MOV       [EBP+04], EDX
( 004E98CF    895D08 )                MOV       [EBP+08], EBX
( 004E98D2    C3 )                    NEXT,
( 19 bytes, 7 instructions )
 ok
: test2  dup 2over rot ;  ok
see test2 
TEST2 
( 004E98F0    8D6DF4 )                LEA       EBP, [EBP+-0C]
( 004E98F3    8B550C )                MOV       EDX, [EBP+0C]
( 004E98F6    895500 )                MOV       [EBP], EDX
( 004E98F9    8B5510 )                MOV       EDX, [EBP+10]
( 004E98FC    895504 )                MOV       [EBP+04], EDX
( 004E98FF    895D08 )                MOV       [EBP+08], EBX
( 004E9902    C3 )                    NEXT,
( 19 bytes, 7 instructions )
 ok

Here are the same tests under SwiftForth:

: test1  2 pick 2 pick 2 pick ;  ok
see test1
47903F   4 # EBP SUB                    83ED04
479042   EBX 0 [EBP] MOV                895D00
479045   8 [EBP] EBX MOV                8B5D08
479048   4 # EBP SUB                    83ED04
47904B   EBX 0 [EBP] MOV                895D00
47904E   8 [EBP] EBX MOV                8B5D08
479051   4 # EBP SUB                    83ED04
479054   EBX 0 [EBP] MOV                895D00
479057   8 [EBP] EBX MOV                8B5D08
47905A   RET                            C3 ok
: test2  dup 2over rot ;  ok
see test2
47906F   4 # EBP SUB                    83ED04
479072   EBX 0 [EBP] MOV                895D00
479075   8 # EBP SUB                    83ED08
479078   EBX 4 [EBP] MOV                895D04
47907B   10 [EBP] EAX MOV               8B4510
47907E   EAX 0 [EBP] MOV                894500
479081   C [EBP] EBX MOV                8B5D0C
479084   EBX ECX MOV                    8BCB
479086   4 [EBP] EBX MOV                8B5D04
479089   0 [EBP] EAX MOV                8B4500
47908C   EAX 4 [EBP] MOV                894504
47908F   ECX 0 [EBP] MOV                894D00
479092   RET                            C3 ok

Stephen Pelc's VFX generates quite good code --- Elizabeth Rather's SwiftForth, of course, is a joke.

It is very puzzling that Stephen Pelc continues to accept Elizabeth Rather as his leader. She appointed him to the Forth-200x committee, and he does what Leon Wagner tells him to do. An example is how Leon Wagner killed the use of { for defining locals (the John Hopkins format) which everybody in the Forth world (including Stephen Pelc) had been using since prior to ANS-Forth --- Leon Wagner insisted that Forth-200x use {: instead, because SwiftForth uses { for multi-line comments --- so Stephen Pelc did what Leon Wagner told him to do, and now everybody in the Forth-200x community is stuck with this ugly {: :} syntax (they can still use { } under VFX however, but their programs won't be standard, and they will have vendor lock-in with VFX).

The only explanation for Stephen Pelc kow-towing to Forth Inc., is that he relies on Elizabeth Rather to do his sales for him. She sells jobs using her schtick about being the second Forth programmer in the world after Charles Moore, and being the "leading expert" on Forth --- then Forth Inc. subs the work out to MPE because Forth Inc. doesn't employ any programmers --- Forth Inc. only employees sales-people.

Stephen Pelc is actually well aware of the flaws in ANS-Forth --- he fixes many of these in VFX --- he makes no effort to fix these in Forth-200x however, obviously because he wants Forth programmers to get trapped in vendor lock-in using VFX.

Forth-200x is all about supporting Forth Inc. and MPE --- they are not supporting the Forth community --- they are actively crippling the standard for the purpose of preventing the Forth community from writing Forth programs that are standard.

[toc] | [prev] | [next] | [standalone]


#52302

Fromhughaguilar96@gmail.com
Date2016-10-29 20:47 -0700
Message-ID<618725e8-cc91-48af-a9c1-b2f38ac6097b@googlegroups.com>
In reply to#52301
On Saturday, October 29, 2016 at 8:29:24 PM UTC-7, hughag...@gmail.com wrote:
> Forth-200x is all about supporting Forth Inc. and MPE --- they are not supporting the Forth community --- they are actively crippling the standard for the purpose of preventing the Forth community from writing Forth programs that are standard.

Elizabeth Rather says this:
---------------------------
I hate locals :-)
---------------------------

Elizabeth Rather's ANS-Forth provides LOCALS| for defining multiple locals, but the parameters are backwards. How could anybody be so dumb as to get the parameters backwards??? I think she purposely crippled LOCALS| because she hates local variables and she wants everybody to hate them as much as she does.

This strategy actually worked quite well. After I bought SwiftForth, I went for several years writing Forth code and not using locals. The parameters in LOCALS| are backwards, so it was useless (that would really make the source-code confusing). Also, in SwiftForth version-2 (what I bought), the (LOCAL) definer would crash SwiftForth when it was used. How does a bug like this get past the testers??? This is not a subtle bug that occurs only under certain circumstances --- any use of (LOCAL) crashes the system --- obviously, (LOCAL) was never tested even once. 

Most likely, Rick van Norman knew that Elizabeth Rather wasn't going to test (LOCAL) because she hates locals and refuses to use them, so he didn't bother to write working code but he just shipped code that didn't work and got paid for it. Another possibility however, is that Elizabeth Rather told him to put bugs in SwiftForth --- she may have done this because she hoped to make the customers pay an upgrade fee to obtain a version with the bugs fixed. When I called Forth Inc. to complain about version-2 being bug-ridden I never got put through to any programmer; I only talked to sales-people and they told me that I had to pay the $300 upgrade fee to get version-3. Also, Elizabeth Rather personally told me that I had to pay the $300 upgrade fee to get version-3. Later on, Leon Wagner gave me a DLL to fix the primary problem of the display not working on the new Windows version --- I never got any other bugs fixed though --- I still have version-2 that is full of major bugs, such as (LOCAL) crashing the system, and I just consider the money I spent to be lost.

Forth Inc. scams their customers --- Forth Inc. has ruined the reputation of the entire Forth community by scamming people --- the world is full of programmers who hate Forth and will never touch it again, and most of them got this impression of Forth from Forth Inc..

[toc] | [prev] | [next] | [standalone]


#52303

FromCecil Bayona <cbayona@cbayona.com>
Date2016-10-29 23:15 -0500
Message-ID<nv3s4b$ehs$1@dont-email.me>
In reply to#52302
On 10/29/2016 10:47 PM, hughaguilar96@gmail.com wrote:
> On Saturday, October 29, 2016 at 8:29:24 PM UTC-7, hughag...@gmail.com wrote:
>> Forth-200x is all about supporting Forth Inc. and MPE --- they are not supporting the Forth community --- they are actively crippling the standard for the purpose of preventing the Forth community from writing Forth programs that are standard.
>
> Elizabeth Rather says this:
> ---------------------------
> I hate locals :-)
> ---------------------------
>
> Elizabeth Rather's ANS-Forth provides LOCALS| for defining multiple locals, but the parameters are backwards. How could anybody be so dumb as to get the parameters backwards??? I think she purposely crippled LOCALS| because she hates local variables and she wants everybody to hate them as much as she does.
>
> This strategy actually worked quite well. After I bought SwiftForth, I went for several years writing Forth code and not using locals. The parameters in LOCALS| are backwards, so it was useless (that would really make the source-code confusing). Also, in SwiftForth version-2 (what I bought), the (LOCAL) definer would crash SwiftForth when it was used. How does a bug like this get past the testers??? This is not a subtle bug that occurs only under certain circumstances --- any use of (LOCAL) crashes the system --- obviously, (LOCAL) was never tested even once.
>

Didn't it come with the source so you can fix it? I bought SwiftForth 
Version 3 a long time ago and it came with the source, although I have 
not kept up with it is an older 3.2.1 version. One day I might get a one 
year maintenance so I can get the Linux and Mac versions which I don't 
have, but money is something I'm don't have in abundance.

The reason I bought MPE VFX Professional Forth and VFX ARM Professional 
Forth with source is because things happen in life that one can't 
foresee, and after spending a lot of money I don't want to become 
stranded with expensive software that is no longer supported.

MPE has a good deal with the free lite versions for ARM, and MSP430, it 
has limits but you can get a lot done within the limits, such as 
non-commercial use, and memory limits. They also have a demo version of 
VFX for Windows with some limits such as not being able to save the 
system image, and for non-commercial use only but those are minor limits.


-- 
Cecil - k5nwa

[toc] | [prev] | [next] | [standalone]


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

Back to top | Article view | comp.lang.forth


csiph-web