Robot Game: C vs Forth vs Assembly
Re: Robot Game: C vs Forth vs Assembly
Quote:
You can get 90% of the performance of assembly language with only 10% done in assembly, provided it's the right 10%, the critical 10%
Re: Robot Game: C vs Forth vs Assembly
Druzyek wrote:
Quote:
And like they say, "You can get 90% of the performance of assembly language with only 10% done in assembly, provided it's the right 10%, the critical 10%," or something like that. The actual numbers will depend on the application; but the principle holds. And it's so easy to mix some 65xx assembly into Forth.
I was actually playing around with a 6809 Forth on the Color Computer a of months ago. Its claimed strength was having some CoCo specific libraries for plotting pixels and such. So I added some FORTH79 words that eased stack access and wrote some simple words to draw horizontal and vertical lines and fill in rectangles using the pixel plot word. All in Forth. Not very impressive, even with my new clever stack manipulation words.
On the other hand, I've spent considerable time writing some hires graphics libraries for PLASMA. These routines aren't all that big, but are fairly optimized (I don't like saying highly optimized because someone will come in and speed up my code considerably
To use another example from PLASMA involves the major feature added to 2.0: the Just In Time native compiler. It takes the guess work out of choosing which routines should be written in assembly by actually profiling them at runtime. With just a 4K buffer dedicated to JIT compiled routines, the time to compile a significant source module using PLASM, the PLASMA source->bytecode compiler, can be halved. Talking about JIT compiling the AOT compiler gets a little recursive, pun intended. Ok, so not 90%, but the point is a small percentage of routines can impact performance a great deal.
Even Woz used an interpreter for 16 bit operations. Mostly to save space, but he was also careful where he used it so as to not impact performance too much. IIRC, he said Sweet16 ran 10% the speed of his hand optimized code but made minimal impact on overall performance.
Re: Robot Game: C vs Forth vs Assembly
How much of that 23K is code, vs how much is graphics or other assets?
Re: Robot Game: C vs Forth vs Assembly
Agumander wrote:
How much of that 23K is code, vs how much is graphics or other assets?
Re: Robot Game: C vs Forth vs Assembly
Quote:
I suspect the loop constructs Tali2 uses to be a lot of the slowness. The loop index is held on the return stack while the loop is running. Tali2 has to pop it into A/Y, add to it, and then push it back. LOOP is implemented as assembly that puts a 1 on the data stack and then falls right into +LOOP.
Re: Robot Game: C vs Forth vs Assembly
Druzyek wrote:
That is a nice sentiment but even mixing in a lot of assembly, I think it's absolutely not true on the 6502. I hear stuff like this all the time online. Someone was claiming here for example that the overhead is only about 25% more than assembly. It seems like people became convinced of how fast Forth is and have just been quoting this for decades without proof. When you actually look at the data and compare the cycles executed, it's more like Forth is 10% the performance, not 90%.
Druzyek wrote:
The Forth version especially will probably have a lot of room for improvement since I'm a Forth beginner.
You mentioned in your game summary that you considered Forth to be unreadable.
Quote:
The chief annoying thing is how unreadable the code turns out to be. Consider this short Forth program:
foo bar baz
Without parenthesis or commas, there is no way to tell just by looking at the code which of those are functions, which ones are variables, which of them are inputs to the others, or what any of them return. Forth fans will say that that information is available in the stack comment for the word's declaration, but that assumes that the programmer bothered to create one. Even if they did, you have to search in several places in the file to figure out what is instantly obvious if the same code were written in a language like C or Python. It's easy to see why people criticize Forth for being "write only." If you translated the line above into C, it could be doing any of the following:
* foo(); bar(); baz();
* foo(); baz(bar());
* foo(); bar(baz);
* foo(bar()); baz();
* foo(bar(),baz());
* bar(foo()); baz();
* bar(foo(),baz());
* bar(foo(baz()));
* bar(baz(foo()));
* baz(foo(),bar());
* baz(foo(bar()));
* baz(bar(foo()));
foo bar baz
Without parenthesis or commas, there is no way to tell just by looking at the code which of those are functions, which ones are variables, which of them are inputs to the others, or what any of them return. Forth fans will say that that information is available in the stack comment for the word's declaration, but that assumes that the programmer bothered to create one. Even if they did, you have to search in several places in the file to figure out what is instantly obvious if the same code were written in a language like C or Python. It's easy to see why people criticize Forth for being "write only." If you translated the line above into C, it could be doing any of the following:
* foo(); bar(); baz();
* foo(); baz(bar());
* foo(); bar(baz);
* foo(bar()); baz();
* foo(bar(),baz());
* bar(foo()); baz();
* bar(foo(),baz());
* bar(foo(baz()));
* bar(baz(foo()));
* baz(foo(),bar());
* baz(foo(bar()));
* baz(bar(foo()));
Not knowing if a word is a colon definition ( a function ) or a variable, constant, or some other type of Forth word is not a disadvantage. On the contrary, it is an advantage. Consider some actual code from my Forth for the C64:
Code: Select all
: FREE ( -- D )
MRU 0 PAD 0 D- ;
Code: Select all
<number of buffers> TO #BUF CONFIGURE
Another example: Some of the words in my Forth that seem to be constants ( 0 , 1 , TRUE , FALSE for example ) are not actually constants. They are words with a code field and no body. Each one's code field points to the correct code to execute ( in another code word ). The colon definitions that use these 'constants' don't need to be any different because these four words are not really constants.
Re: Robot Game: C vs Forth vs Assembly
Quote:
If by 'data' you mean the data from your game, that just means your Forth programming is 10% the performance.
Quote:
Not knowing if a word is a colon definition ( a function ) or a variable, constant, or some other type of Forth word is not a disadvantage. On the contrary, it is an advantage.
Quote:
Is MRU a VALUE that only CONFIGURE can alter? Is it a colon definition? It does not matter. All that matters is that it returns the address of the start of the buffer table.
Quote:
Another example: Some of the words in my Forth that seem to be constants ( 0 , 1 , TRUE , FALSE for example ) are not actually constants.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Robot Game: C vs Forth vs Assembly
As a total noob, I tend to put stack comments after each source line:
Forth hasn't "clicked" in my tired old brain yet, but I find it so appealing that I want to give it as many chances as I can, limited spare time permitting.
[Edit: it looks like I could have factored out the sequence @ - dup 0< 1 or swap abs dup , but I have no clue what kind of name I would give that little slice of goodness ... maybe HUH ?]
Code: Select all
...
y @ - \ calculate .y ( 'x .y )
dup 0< 1 or swap \ ~.y ( 'x ~y .y )
abs dup >r \ |.y ( 'x ~y |y ) ( R: |y )
rot x @ - \ calculate .x ( ~y |y .x )
dup 0< 1 or swap \ ~.x ( ~y |y ~x .x )
abs \ |.x ( ~y |y ~x |x )
dup \ c is slope accum. ( ~y |y ~x |x c )
dup r> + \ k is loop counter ( ~y |y ~x |x c k ) ( R: )
...
[Edit: it looks like I could have factored out the sequence @ - dup 0< 1 or swap abs dup , but I have no clue what kind of name I would give that little slice of goodness ... maybe HUH ?]
Last edited by barrym95838 on Thu Jul 23, 2020 6:36 am, edited 2 times in total.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: Robot Game: C vs Forth vs Assembly
Druzyek wrote:
Quote:
If by 'data' you mean the data from your game, that just means your Forth programming is 10% the performance.
Surely you don't mean that as a Forth beginner you can write Forth nearly as well as an experienced Forth programmer?
Quote:
The Forth version especially will probably have a lot of room for improvement since I'm a Forth beginner.
Quote:
but the source is on github if you wanna take a stab.
Quote:
Quote:
Not knowing if a word is a colon definition ( a function ) or a variable, constant, or some other type of Forth word is not a disadvantage. On the contrary, it is an advantage.
Quote:
I guess if you get everything right on your first draft you can get away with write only programming
Quote:
but when you try to understand someone else's code or your own after enough time has gone by or you need to modify existing code, what that word does to the stack is VERY important.
Quote:
If you are low-level enough to care what is actually on the stack, you need to understand what every single word adds or removes
Quote:
and you just don't have that information at a glance the way you do in C.
Quote:
Quote:
Is MRU a VALUE that only CONFIGURE can alter? Is it a colon definition? It does not matter. All that matters is that it returns the address of the start of the buffer table.
Quote:
Another example: Some of the words in my Forth that seem to be constants ( 0 , 1 , TRUE , FALSE for example ) are not actually constants.
Code: Select all
static void func1(void)
Re: Robot Game: C vs Forth vs Assembly
Quote:
I didn't say the improvement would be tenfold.
Surely you don't mean that as a Forth beginner you can write Forth nearly as well as an experienced Forth programmer?
Surely you don't mean that as a Forth beginner you can write Forth nearly as well as an experienced Forth programmer?
Quote:
If by 'data' you mean the data from your game, that just means your Forth programming is 10% the performance.
Quote:
But then how would you learn to be a better Forth programmer?
Quote:
A Forth word should never remove an unknown number of items from the data stack. Nor should it add an unknown number of items. When a Forth word is written, a stack comment should be written right after the name. The word should then be tested to insure it functions properly. Once the word works, make sure the stack comment is still accurate.
Quote:
Quote:
and you just don't have that information at a glance the way you do in C.
Quote:
You can always add stack comments anywhere in your source. The stack comments alone will not tell you what a word does any more than a C function prototype. This function:
Code:
static void func1(void)
Could do anything. All the function prototype tells me is that it takes no arguments and returns none. How do I know it doesn't call malloc() without freeing the allocated memory before it returns?
Code:
static void func1(void)
Could do anything. All the function prototype tells me is that it takes no arguments and returns none. How do I know it doesn't call malloc() without freeing the allocated memory before it returns?
Re: Robot Game: C vs Forth vs Assembly
Druzyek wrote:
The number of words is not unknown to the programmer in the moment they write it
Do you mean the number of cells?
Quote:
but it is unknown to someone else reading what they wrote or to themselves if enough time has gone by until they hunt down the stack comment. This is what I mean by unreadable.
Funny, I've never had that problem.
Quote:
If you have to go somewhere else in the file or into another file to find the stack comment then that is not what I mean by "at a glance."
Does your editor of choice display the function declaration when you type the name of a C function you've already declared elsewhere? Mine never did. Then again, I was using VI so yes I did have to go look elsewhere for the function declaration if I wasn't sure of the arguments it required.
Quote:
No, it could not be doing anything. As you noticed, it cannot return anything and it can't take any arguments.
There's more than one way to get arguments.
Code: Select all
#include <stdio.h>
static void func1(void);
int main(void)
{
func1();
return 0;
}
static void func1(void)
{
int i;
int j;
printf("\nEnter a number: ");
scanf(" %d",&i);
printf("\nEnter another number: ");
scanf(" %d",&j);
int k;
k=i*j;
printf("\n %d times %d is %d.\n", i, j, k);
return ;
}
Quote:
This is a promise that will never be broken.
Yeah.
Code: Select all
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
int sum(int, ...);
int main(void){
int a=2;
int b=42;
int c=137;
int d=43;
int e=-22;
int f=11;
int g=0;
printf("%d\n",sum(3, a, b, c));
printf("%d\n",sum(5, c, d, e, f, g));
return 0;
}
int sum(int n_args, ...){
register int i;
int a, accum;
va_list ap;
va_start(ap, n_args);
accum = va_arg(ap, int);
for(i = 2; i <= n_args; i++) {
accum += va_arg(ap, int);
}
va_end(ap);
return accum;
}
I suppose it did keep that promise. In this case the promise was one argument of type int plus an unknown number of arguments. No, the initial argument, n_args, does not tell you how many additional arguments the function requires, A different function with a variable number of arguments could, for example, take n_args number of pairs, or triplets.
Quote:
In Forth, you don't know what happens to the stack without the comment, the comment could be wrong (because you've changed the code and forgot to update the comment) or it might not exist if it's someone else's code. This never happens to the stack in C. Ever. Also, having to copy the stack comment down to where the word it relates to is used just to keep things straight is absurd enough to illustrate the point.
I've never actually had to do that. It was a suggestion to help a new Forth programmer who seemed to be in over his head.
Quote:
Yes, the function could call malloc but that has nothing to do with being able to tell what goes onto and comes off of the stack. There are always things you don't instantly know. My point is that what happens to the stack is not one of them in C but it is in Forth.
It could also call fork(). Is that function even available with a C compiler that compiles for the 65C02?
Knowing what a function does is extremely important in any programming language.
I don't have a problem with keeping up with what is on the data stack in Forth. Although my Forth has .S to display the contents of the data stack, I rarely use it. I don't have a problem reading and understanding Forth. I find Forth very readable.
I know C. I've used C. If need be, I'll use it again, but I prefer Forth.
Forth allows me to prototype, to flesh out an idea with a word, or a few words, and interactively test and refine said idea.
Quote:
I suppose I could build the words interactively but it doesn't seem any faster that way.
But it would allow you to prototype. To experiment with different algorithms and test them interactively with the interpreter.
Quote:
Sometimes I feel like a human C compiler
Why not a human python compiler? Or some other language?
Six years ago you said:
Quote:
Hi! I just started with 6502 assembly and I find myself often trying to translate from C
As I suggested earlier, you may be doing the same with Forth. Forth and C are so different that a direct translation (even if it is unintentional because you think 'C' when it comes to programming) yields poor results.
Quote:
Do you mean my Forth programming is 10% the performance it would be if it were rewritten?
What I meant was that in this game your Forth programming is 10% the performance of your assembly language programming.
Quote:
No, I don't think I write Forth nearly as well as an experienced Forth programmer
You don't. Have you read "Starting Forth" and "Thinking Forth" by Leo Brodie?
What about issues of the "Forth Dimensions" magazine?
Quote:
How about another example you could point to then that would better reflect the performance difference than the example I've given? That would eliminate my skill as a Forth programmer from the equation.
The only programs I know of for the 6502 family would be programs for the Commodore 64 and I do not know what language was used to write these except one. Starflight was written in Forth and Assembly language.
Quote:
I decided on Tali because I wanted to generate the fastest forth code possible even if it's larger.
But in the previous post, scotws told you,
Quote:
Tali was written for clarity (in other words, it needed to fit my Forth beginner's brain), not max speed or min size
leepivonka said,
Quote:
There are several places where Tali could be modifed or extended to generate significantly smaller but slightly slower code
followed by examples. In that same post:
Quote:
The phrase 2 * takes 6 bytes for each use.
The application could be recoded to use 2* to use 3 or 4 bytes & run much faster.
The application could be recoded to use 2* to use 3 or 4 bytes & run much faster.
And your reply:
Quote:
I don't plan to change any of the words like leeviponka suggests.
I see that you showed an interest in Forth in this forum over five years ago, yet you didn't familiarize yourself with the core words of the Ansi Forth Standard (the Forth you chose to use conforms to that standard) nor with the core extentsion words like 2>R and 2R> .
It seems like you are resisting doing what is natural in Forth. You didn't like the behavior of 2>R and 2R> so you came up with this:
Code: Select all
: >>r r> -rot >r >r >r ; compile-only
: >>>r r> swap >r -rot >r >r >r ; compile-only
: r>> r> r> r> rot >r ; compile-only
: r>>> r> r> r> rot r> swap >r ; compile-only
In one place you used r>> like this:
Code: Select all
r>> swap
which could have been replaced with:
Code: Select all
2R>
which is much smaller and faster.
To summarize:
It is not my intention to debate the relative merits of the two languages and I'm not criticizing C. I'm not trying to criticize your programming ability. I'm not trying to convert you to Forth, you took on this project. I am trying to get you to think "outside the box" of C programming to help you.
Hard to read code can be written in any language. Once you become comfortable with Forth, it will be easier to write efficient and readable programs.
If you think that only unreadable code can be written in Forth, how will you be able to write readable code?
If you think the data stack is difficult to keep track of, how will you get comfortable with postfix notation?
If you don't get comfortable with programming in ways that are natural to Forth, if you can't set aside the 'C' mindset when writing Forth then it will be difficult to make progress.
I'm suggesting you set aside your preconceptions. Download and read "Starting Forth" then "Thinking Forth". Keep an open mind when reading these books.
This is my advice if you are still interested in learning Forth.
Re: Robot Game: C vs Forth vs Assembly
JimBoyd wrote:
Quote:
In Forth, you don't know what happens to the stack without the comment, the comment could be wrong (because you've changed the code and forgot to update the comment) or it might not exist if it's someone else's code. This never happens to the stack in C. Ever. Also, having to copy the stack comment down to where the word it relates to is used just to keep things straight is absurd enough to illustrate the point.
Sure, Forth has a few peccadillos... and it doesn't bother me to hear them mentioned. Fair comment, I say. In the overall tradeoff Forth is still a big win for me!
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Robot Game: C vs Forth vs Assembly
Druzyek wrote:
Quote:
Quote:
with stuff like "drop 5" where you have useless runs like DEX / DEX / INX / INX.
Ah, of course. I don't know why I missed something so simple. In that case, if it's in a performance-critical part, it's no trouble to make it a primitive, something like (for the 65816)
Code: Select all
HEADER "DROP_5", NOT_IMMEDIATE ( n -- 5 )
DROP5: PRIMITIVE
LDA #5
STA 0,X
JMP NEXTThe header can always be omitted if the target system doesn't need to find it for new compilation.
The above is what I would do for putting it in the kernel which goes in ROM. It's for the assembly-language source code. To do it interactively on the running system and putting it in RAM, I would do:
Code: Select all
CODE DROP_5 ( n -- 5 )
LDA# 5 ,
STA_ZP,X 0 C,
JMP NEXT ,Code: Select all
CODE DROP_5 ( n -- 5 )
LDA# 5 ,
JMP PUT ,Quote:
Quote:
You can always add primitives as the need might justify, which amount to a degree of optimization, combining commonly used pairs or sets of words into a single primitive. A list of many of my own '816 ones is at viewtopic.php?p=72734#p72734 .
If I were to need something like that, I would make only the one instance I needed into a primitive, not all 15 possible ones.
Quote:
Quote:
And like they say, "You can get 90% of the performance of assembly language with only 10% done in assembly, provided it's the right 10%, the critical 10%," or something like that. The actual numbers will depend on the application; but the principle holds. And it's so easy to mix some 65xx assembly into Forth.
Sure. The point is not that you can make the whole thing run 90% as fast as assembly, but rather that with a little assembly, you can get the speed-critical parts to perform as needed, while it doesn't matter for the rest. "The rest" may be, for example, routines that scan and debounce a keypad, take care of auto key repeat delay and repeat speed, take in data or instructions on an RS-232 port and interpret them, etc..
An example from my own work is that I've had a machine-language ISR on my workbench computer playing back sampled aircraft audio at 24,000 samples per second while in Forth I was trying things by having the computer accept instructions as text over the RS-232 port and interpreting them. The instructions could do things like change the sampling rate, move around in the recording, even modify the ISR on the fly. So even though only a tiny percentage of it was not in Forth, I was producing the audio with 24,000 samples per second and doing other stuff at the same time, on my 5MHz workbench computer which was fast enough for it all.
Quote:
Quote:
but it is unknown to someone else reading what they wrote or to themselves if enough time has gone by until they hunt down the stack comment. This is what I mean by unreadable.
Neither have I. Unless the stack effect is extremely obvious, you always have the stack comment right there on the first line of the definition along with the name. And while you might edit the way the innards work, it's very rare that the top-line stack-effect comment would ever need to change.
Quote:
Code: Select all
: >>r r> -rot >r >r >r ; compile-only
: >>>r r> swap >r -rot >r >r >r ; compile-only
: r>> r> r> r> rot >r ; compile-only
: r>>> r> r> r> rot r> swap >r ; compile-onlyMy ITC '816 Forth's 2>R and 2R> are defined as
Code: Select all
HEADER "2>R", NOT_IMMEDIATE ; ( d -- )
_2TO_R: PRIMITIVE
LDA 0,X ; High cell goes on return stack first.
PHA ; This takes 3 more bytes as a primitive
LDA 2,X ; than it would as a secondary, but it
PHA ; might be used often enough to warrant
JMP POP2 ; it for performance. Same as >R >R
;-------------------
HEADER "2R>", NOT_IMMEDIATE ; ( -- d ) Same as R> R>
_2R_FR: PRIMITIVE
PLA
DEX
DEX
STA 0,X
PLA
JMP PUSH
;-------------------where POP2 is defined as basically
Code: Select all
POP2: INX
INX
POP: INX
INX
JMP NEXT
;-------------------Code: Select all
PUSH: DEX
DEX
PUT_TOS: STA 0,X
JMP NEXT
;-------------------http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Robot Game: C vs Forth vs Assembly
JimBoyd wrote:
Druzyek wrote:
The number of words is not unknown to the programmer in the moment they write it
Quote:
Quote:
but it is unknown to someone else reading what they wrote or to themselves if enough time has gone by until they hunt down the stack comment. This is what I mean by unreadable.
Quote:
Does your editor of choice display the function declaration when you type the name of a C function you've already declared elsewhere? Mine never did. Then again, I was using VI so yes I did have to go look elsewhere for the function declaration if I wasn't sure of the arguments it required.
Quote:
There's more than one way to get arguments.
Code: Select all
#include <stdio.h>
static void func1(void);
int main(void)
{
func1();
return 0;
}
static void func1(void)
{
int i;
int j;
printf("\nEnter a number: ");
scanf(" %d",&i);
printf("\nEnter another number: ");
scanf(" %d",&j);
int k;
k=i*j;
printf("\n %d times %d is %d.\n", i, j, k);
return ;
}
Code: Select all
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
int sum(int, ...);
int main(void){
int a=2;
int b=42;
int c=137;
int d=43;
int e=-22;
int f=11;
int g=0;
printf("%d\n",sum(3, a, b, c));
printf("%d\n",sum(5, c, d, e, f, g));
return 0;
}
int sum(int n_args, ...){
register int i;
int a, accum;
va_list ap;
va_start(ap, n_args);
accum = va_arg(ap, int);
for(i = 2; i <= n_args; i++) {
accum += va_arg(ap, int);
}
va_end(ap);
return accum;
}
Quote:
I suppose it did keep that promise. In this case the promise was one argument of type int plus an unknown number of arguments. No, the initial argument, n_args, does not tell you how many additional arguments the function requires, A different function with a variable number of arguments could, for example, take n_args number of pairs, or triplets.
Quote:
Quote:
In Forth, you don't know what happens to the stack without the comment, the comment could be wrong (because you've changed the code and forgot to update the comment) or it might not exist if it's someone else's code. This never happens to the stack in C. Ever. Also, having to copy the stack comment down to where the word it relates to is used just to keep things straight is absurd enough to illustrate the point.
Quote:
I don't have a problem with keeping up with what is on the data stack in Forth. Although my Forth has .S to display the contents of the data stack, I rarely use it. I don't have a problem reading and understanding Forth. I find Forth very readable.
I know C. I've used C. If need be, I'll use it again, but I prefer Forth.
Forth allows me to prototype, to flesh out an idea with a word, or a few words, and interactively test and refine said idea.
I know C. I've used C. If need be, I'll use it again, but I prefer Forth.
Forth allows me to prototype, to flesh out an idea with a word, or a few words, and interactively test and refine said idea.
Quote:
I suppose I could build the words interactively but it doesn't seem any faster that way.
Quote:
Quote:
Sometimes I feel like a human C compiler
Quote:
Six years ago you said:
As I suggested earlier, you may be doing the same with Forth. Forth and C are so different that a direct translation (even if it is unintentional because you think 'C' when it comes to programming) yields poor results.
Quote:
Hi! I just started with 6502 assembly and I find myself often trying to translate from C
Quote:
Quote:
Do you mean my Forth programming is 10% the performance it would be if it were rewritten?
Quote:
Quote:
No, I don't think I write Forth nearly as well as an experienced Forth programmer
What about issues of the "Forth Dimensions" magazine?
Quote:
Quote:
How about another example you could point to then that would better reflect the performance difference than the example I've given? That would eliminate my skill as a Forth programmer from the equation.
Quote:
Quote:
I decided on Tali because I wanted to generate the fastest forth code possible even if it's larger.
Quote:
Tali was written for clarity (in other words, it needed to fit my Forth beginner's brain), not max speed or min size
Quote:
leepivonka said,
followed by examples. In that same post:And your reply:
Quote:
There are several places where Tali could be modifed or extended to generate significantly smaller but slightly slower code
Quote:
The phrase 2 * takes 6 bytes for each use.
The application could be recoded to use 2* to use 3 or 4 bytes & run much faster.
The application could be recoded to use 2* to use 3 or 4 bytes & run much faster.
Quote:
I don't plan to change any of the words like leeviponka suggests.
Quote:
I see that you showed an interest in Forth in this forum over five years ago, yet you didn't familiarize yourself with the core words of the Ansi Forth Standard (the Forth you chose to use conforms to that standard) nor with the core extentsion words like 2>R and 2R>.
Quote:
It seems like you are resisting doing what is natural in Forth. You didn't like the behavior of 2>R and 2R> so you came up with this:
In one place you used r>> like this:
which could have been replaced with:
which is much smaller and faster.
Code: Select all
: >>r r> -rot >r >r >r ; compile-only
: >>>r r> swap >r -rot >r >r >r ; compile-only
: r>> r> r> r> rot >r ; compile-only
: r>>> r> r> r> rot r> swap >r ; compile-only
Code: Select all
r>> swap
Code: Select all
2R>
Quote:
To summarize:
It is not my intention to debate the relative merits of the two languages and I'm not criticizing C. I'm not trying to criticize your programming ability. I'm not trying to convert you to Forth, you took on this project. I am trying to get you to think "outside the box" of C programming to help you.
Hard to read code can be written in any language. Once you become comfortable with Forth, it will be easier to write efficient and readable programs.
If you think that only unreadable code can be written in Forth, how will you be able to write readable code?
If you think the data stack is difficult to keep track of, how will you get comfortable with postfix notation?
If you don't get comfortable with programming in ways that are natural to Forth, if you can't set aside the 'C' mindset when writing Forth then it will be difficult to make progress.
I'm suggesting you set aside your preconceptions. Download and read "Starting Forth" then "Thinking Forth". Keep an open mind when reading these books.
This is my advice if you are still interested in learning Forth.
It is not my intention to debate the relative merits of the two languages and I'm not criticizing C. I'm not trying to criticize your programming ability. I'm not trying to convert you to Forth, you took on this project. I am trying to get you to think "outside the box" of C programming to help you.
Hard to read code can be written in any language. Once you become comfortable with Forth, it will be easier to write efficient and readable programs.
If you think that only unreadable code can be written in Forth, how will you be able to write readable code?
If you think the data stack is difficult to keep track of, how will you get comfortable with postfix notation?
If you don't get comfortable with programming in ways that are natural to Forth, if you can't set aside the 'C' mindset when writing Forth then it will be difficult to make progress.
I'm suggesting you set aside your preconceptions. Download and read "Starting Forth" then "Thinking Forth". Keep an open mind when reading these books.
This is my advice if you are still interested in learning Forth.
It's strange that you say you're not debating the merits of the languages since that's the reason I started the thread, and you've spent pages doing just that. In any case, I think you could use a good dose of the "thinking outside the box" that you prescribe above. Like most of the Forth fans I've met online outside of this forum, you're convinced of the greatness of the language and if anything disagrees with that, then it must be wrong. Hence your suggestion that I read books I've already read and "learn" Forth despite having written thousands of lines of it. How have you determined that my Forth code is slow because I'm used to programming in C versus my Forth code being slow because Forth is slow? You don't seem to see how it could be that someone could know enough to understand the situation and still disagree with you. That's backwards. First, let's look at the data (again happy to consider alternatives if you don't like mine) then determine the language's greatness rather than taking the greatness of the language for granted and dismissing anything that doesn't agree out of hand.
Thanks for the debate. I'm enjoying the discussion and happy to continue if you have more thoughts.
Re: Robot Game: C vs Forth vs Assembly
Everything I've said in these posts has been based on the assumption that I was helping someone new to Forth who was having difficulty "getting it". A major part of that assumption was that this person actually wanted to learn Forth. I am sorry, for it appears that I was wrong.
This entire conversation, every single post I've made to your robot game topic, could have been avoided if I'd noticed five words on your website that I somehow overlooked.
Quote:
Forth is not for me.
If I had noticed these five words, or better yet, if YOU had responded with them at any time during this exercise in futility ( trying to help someone learn something they really don't want to learn ) would have been over.
Druzyek wrote:
That's interesting. Do you read other people's Forth code?
Does the source for Win32Forth count?
I don't have a problem reading Forth. Apparently, that is a skill I have that you don't. Blaming your inability to read Forth, or any other language, on the design of the language is like when someone who can not drive a car with a manual transmission blames his lack of skill on the design of the transmission. Some of us can drive a vehicle with a manual transmission and some of us can read Forth source without difficulty. I was hoping to help you develop that skill, but that is irrelevant now.
Quote:
Quote:
Quote:
How about another example you could point to then that would better reflect the performance difference than the example I've given? That would eliminate my skill as a Forth programmer from the equation.
You consider Starflight to be nothing?
When I said Starflight was programmed in Forth and Assembly language, I meant that it was programmed in a combination of Forth and Assembly language. This is why Forth includes an assembler.
Your game isn't even in the same league as Starflight. If you wish to run another comparison, I would suggest you try porting Starflight to C or Assembly language for a comparison.
Quote:
Quote:
Quote:
I decided on Tali because I wanted to generate the fastest forth code possible even if it's larger.
Quote:
Tali was written for clarity (in other words, it needed to fit my Forth beginner's brain), not max speed or min size
You claim to have the proficiency in Forth to write a Forth version of your game to compare with C and Assembler. Writing a Forth system is not that difficult. Scotws was a beginner when he started TaliForth. That is what I would suggest if you were actually interested in Forth.
Quote:
I see below you found a few improvements
That's only in the source you shared on the 6502 forum.
Quote:
but it's a leap to say I didn't bother familiarizing myself with the core words.
Then why this post:
Quote:
If you mean defining a word called count that does "dup c@ swap 1+ swap" then you are no better off if your goal is performance. Either Tali Forth 2 will inline the word, which is essentially what I am doing by hand, or it will keep count and you lose performance jumping into it and out of it. The only improvement, if I understand you right, is making the source slightly more readable but possibly at the cost of speed.
COUNT is a CODE word in my Forth's kernel but I checked the source for COUNT in TaliForth2 before I made the suggestion. Honestly, how difficult would it have been to check the TaliForth2 source before posting your reply?
Quote:
I'm working on a project now that involves Forth because despite the disadvantages mentioned above, I still think it's a good fit.
What?!! You have got to be kidding me! That's Amazing!
What happened to "Forth is not for me" ?
I can't help but wonder if it is a good idea for you to use Forth since you have such difficulty reading it. Could that offset the advantage of it being a good fit?
Quote:
My objection is to the misinformation (or maybe even dishonesty) about the capabilities of the language that are floating around. This project is partly about trying to put those claims to the test, at least for the 6502.
I've seen your Forth source on github. There is not a single CODE word anywhere. It is all high level Forth.
When did I ever say that Forth without an appropriate amount of CODE words would have anywhere near the performance of C or Assembly language?
Where did anyone on this forum make that claim.
The claim was that with the right parts ( the time critical parts ) written as CODE words ( assembly language ) Forth could achieve such performance. That is why Forth has an Assembler. That is why it is so easy to mix Assembly language into Forth. Given two Forth words that do the same thing, one high level and the other a CODE word, the CODE word can be used the same as its high level counterpart. None of the rest of the code that uses said word needs to be changed.
Quote:
It's strange that you say you're not debating the merits of the languages since that's the reason I started the thread, and you've spent pages doing just that.
Based on some of your questions in the other thread you started, I honestly thought I was helping someone who wanted to learn Forth in spite of its uniqueness. My apologies for making an unwarranted assumption.
Quote:
In any case, I think you could use a good dose of the "thinking outside the box" that you prescribe above.
What do you mean? I'm not a C newbie. I grok C. Even though I prefer Forth, I don't have a problem with C, just some of the practitioners. No, I don't necessarily mean you.
Quote:
Like most of the Forth fans I've met online outside of this forum, you're convinced of the greatness of the language and if anything disagrees with that, then it must be wrong.
You seem to think that I am a Forth fanatic and no other language will do. For your information, Python is another favorite of mine, but I obviously can't fit a Python interpreter on a 6502 based system. I can only use it on my Linux box.
Quote:
Hence your suggestion that I read books I've already read and "learn" Forth despite having written thousands of lines of it.
How am I supposed to know what books you have and haven't read? My assumption was based on the level of proficiency reflected in your comments in both threads. As for having written thousands of lines of Forth, do you think that's all it takes to master a new language? If that's true, you should be able to write a very optimal Forth for that project you said you are working on.
Quote:
How have you determined that my Forth code is slow because I'm used to programming in C versus my Forth code being slow because Forth is slow?
Good question. It may not be because you are used to programming in C. Not having any CODE words in your source is making it slow, and would make it slow no matter how well you wrote your game. Consider eforth. It is a Forth with very few primitives and it is very slow.
Quote:
You don't seem to see how it could be that someone could know enough to understand the situation and still disagree with you. That's backwards.
Ah but I don't disagree that Forth without suitable CODE words for the time critical parts such as graphics and bit manipulation would be slow. Do you disagree with me that an application written in Forth, especially a graphics intense one, would be slow without the support of CODE words for the graphics routines?
You don't seem to understand how adding CODE words to your source could dramatically speed things up and the lack of CODE words is what's making it so slow.
resman wrote:
It depends on what you're claiming is the 90% performance of assembly. I don't think anyone is saying Forth is outright 90% the performance of assembly. More like you can get 90% the performance of assembly if you chose the proper code to assembly-ize. For instance, in a video game the low level graphics routines better be written in assembly (on a 6502). The 6502 is a really great 8 bit CPU, but not so much when it comes to 16 bit operations. Not that it can't, it just gets tedious and the code size tends to grow quite fast.
GARTHWILSON wrote:
Sure. The point is not that you can make the whole thing run 90% as fast as assembly, but rather that with a little assembly, you can get the speed-critical parts to perform as needed, while it doesn't matter for the rest. "The rest" may be, for example, routines that scan and debounce a keypad, take care of auto key repeat delay and repeat speed, take in data or instructions on an RS-232 port and interpret them, etc..
An example from my own work is that I've had a machine-language ISR on my workbench computer playing back sampled aircraft audio at 24,000 samples per second while in Forth I was trying things by having the computer accept instructions as text over the RS-232 port and interpreting them. The instructions could do things like change the sampling rate, move around in the recording, even modify the ISR on the fly. So even though only a tiny percentage of it was not in Forth, I was producing the audio with 24,000 samples per second and doing other stuff at the same time, on my 5MHz workbench computer which was fast enough for it all.
An example from my own work is that I've had a machine-language ISR on my workbench computer playing back sampled aircraft audio at 24,000 samples per second while in Forth I was trying things by having the computer accept instructions as text over the RS-232 port and interpreting them. The instructions could do things like change the sampling rate, move around in the recording, even modify the ISR on the fly. So even though only a tiny percentage of it was not in Forth, I was producing the audio with 24,000 samples per second and doing other stuff at the same time, on my 5MHz workbench computer which was fast enough for it all.
I don't understand why you would ignore that advice.
Quote:
First, let's look at the data (again happy to consider alternatives if you don't like mine) then determine the language's greatness rather than taking the greatness of the language for granted and dismissing anything that doesn't agree out of hand.
I never dismissed the fact that Forth without the support of CODE words would be slow. Yes, let's look at the data. No CODE words anywhere. No wonder the Forth you wrote is slow. Even if you wrote the best possible high level Forth, it's going to be slow.
Nobody that I am aware of claimed that Forth would be anywhere near as fast as assembly without judiciously written Assembly words ( CODE words). I told you as much, Garth told you as much, and so did others on this forum. The claim that Forth can achieve 90 percent the performance of assembly is with an application with suitable CODE words. These could be defined as part of the application or provided by the system. As I recall, Blazin' Forth for the C64 included graphics support at the assembly level ( CODE words). You are comparing a Forth application without any low level support other than what TaliForth2 itself provides with Assembly and C. I certainly never said that such a handicapped program would be able to compete. It appears that you are chasing windmills.
Quote:
Thanks for the debate.
It was never my intention to debate. I somehow got off on a tangent trying to help someone who appeared to be a beginner in Forth who appeared to want to learn the language.
Quote:
I'm enjoying the discussion and happy to continue if you have more thoughts.
Someone who enjoys wasting the time of others. I don't know what to make of that. If you knew Forth was not for you, you should have posted that information right here.
At whatever point you didn't want advice or help learning Forth, you could have mentioned it here and ended this exercise in futility right there and then.