Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #52178 > unrolled thread
| Started by | trans <transfire@gmail.com> |
|---|---|
| First post | 2016-10-24 20:42 -0700 |
| Last post | 2016-10-30 18:19 +0100 |
| Articles | 20 on this page of 65 — 19 participants |
Back to article view | Back to comp.lang.forth
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 →
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-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]
| From | mhx@iae.nl |
|---|---|
| Date | 2016-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-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]
| From | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2016-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-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]
| From | Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> |
|---|---|
| Date | 2016-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]
| From | peter.m.falth@gmail.com |
|---|---|
| Date | 2016-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]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2016-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]
| From | Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> |
|---|---|
| Date | 2016-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]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2016-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-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]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-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]
| From | Cecil Bayona <cbayona@cbayona.com> |
|---|---|
| Date | 2016-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