jlg@lanl-a.UUCP (06/28/84)
Does anyone know of a FORTH compiler which does ANY optimization on the generated code? Contrary to the claims about FORTH, it's been my experience that threaded programming languages are quite slow compared to proceedural languages. Most of this problem is caused by redundant stack manipulation when 'words' are invoked. For example, if I want to do the equivalent of the Fortran expression (A+B)*C in FORTH, I do "@A @B + @C *" (it's been a long time, so please forgive if the syntax is slightly wrong). This causes values of A and B to be pushed on the stack, then '+' pops them off and adds them - pushing the result back on the stack. Then the value of C get pushed on, and finally '*' pops both args off and multiplies. So the total memory activity is 5 pushes and 4 pops. In Fortran, the values of A and B are loaded, the add goes, the value of C is loaded, the multiply goes, and the result is stored - 3 loads, one store. FORTH also had to do the 3 loads and one store in addition to the stack manipulation, so that's 9 stack operations which were redundant. I don't know of any FORTH implementation which does better than this. Claims that FORTH is real efficient seem to be unfounded when compared to good compiled code from other languages. FORTH does seem to produce very compact code, and once you get used to it, it's fairly easy to write. But, to be efficient, the compiler must unthread the code and compactness is lost. Even advanced forms of FORTH in which the basic math operations were optimized suffer from this problem since all user defined 'words' are treated as external calls. This prevents peephole optimization to eliminate redundant loads and stores, as well as introducing call and return instructions where they aren't needed. This would be like writing Pascal with every statement being a proceedure call! Even the control structures in FORTH such as conditionals and loop control are usually treated as externals. This analysis may be a little old since I haven't used FORTH for some time. If there are versions of FORTH in which these problems are corrected, I'd like to know. Otherwise, please don't keep up the pretense that FORTH is faster than other languages. J.L.Giles Los Alamos Nat'l Lab ...!cmcl2!lanl-a!jlg
bruce@godot.UUCP (Bruce Nemnich) (06/30/84)
Forth is efficient in terms of space more than time. I don't remember the whole Forth history, but it goes back to the early 70s, when it was used with early microcomputer chips to control industrial machines. In that day, 4k was a lot of memory. Forth in incredibly compact, often much more so than hand-optimized machine code. I did an 8080 implementation once and remember writing an 8080 assembler for it which took up about 600 bytes. In terms of time-efficiency, it was much better than other interpreted languages available and usually compared reasonably with the basic and fortran compilers available for the larger 8-bit systems. Yes, a good compiler can usually create somewhat faster code (but not more compact!). Remember, the compilers for small machines were often produced pretty primitive code, since the compiler itself had to be small. But most of all, forth is fun and convenient: having the "compiler" and dislay editor and all the system commands resident is great! I also like it as a language a lot more than those two. I have only used forth on small machines; its space advantages are pretty meaningless in a large-address-space machine like the vax. But I'll install it, because its a language I like to play with. It is also has a lot of educational value. Oops, shouldn't have said that! -- --Bruce Nemnich, Thinking Machines Corporation, Waltham, MA {decvax!cca,ihnp4!mit-eddie,allegra!ias}!godot!bruce, BJN@MIT-MC.ARPA
dgary@ecsvax.UUCP (07/09/84)
<> The referenced article notes that FORTH is often not efficient when compared to compiled languages, giving as an example the phrase A @ B @ + C ! and its FORTRAN equivalent C=A+B. Two comments: First, FORTH is properly advertised as a fast, space-efficient interactive development language. The operative word is 'interactive' which almost (obviously, not quite) implies 'interpretive'. FORTH is rather speedy as interpretive languages go. Furthermore, all 'real' FORTHs include an assembler so that time-critical routines (typically a small part of most applications) can be coded in assembler and then tested interactively. FORTH is often best used as an interactive assembler. A few ridiculous claims have been made for FORTH speed. The most ludicrous is the assertion that FORTH code often executes faster than the equivalent assembler program (!!!) an outrageous claim from no less than a FORTH Interest Group (fig) brochure. As for the example given, it is possible to speed it up by using constants instead of variables, and writing a FORTH word that stores a new value in a constant. That would make the phrase something like: A B + := C (The := word has to be IMMEDIATE and is best done in assembler, but : := ['] ! ; IMMEDIATE would probably work (haven't tried it), although you may need to get rid of the brackets.) D Gary Grady Duke University Computation Center, Durham, NC 27706 (919) 684-4146 USENET: {decvax,ihnp4,akgua,etc.}!mcnc!ecsvax!dgary
wmb@sun.uucp (Mitch Bradley) (07/13/84)
Gary Grady suggested using constants in place of variables to improve FORTH execution speed. The following syntax is suggested: A B + := C along with the implementation: : := ['] ! ; IMMEDIATE This implementation doesn't quite work; ['] is itself immediate, so this implementation of := actually just leaves the address of the word "!". One correct implementation is: : := ( value --name ) ( store into the constant whose name follows ) ' >body state @ if [compile] literal compile ! else ! then ; immediate This version works either in interpret mode or compile mode. The ">body" word is for Forth-83, in which "'" leaves the "compilation address" (cfa) of the word, instead of the "parameter field address" (pfa) of the word as in Forth-79 and FIG-Forth. ">body" should be omitted for Forth-79 or FIG-Forth systems. Historical perspective: An idea similar to this was suggested a couple of years ago in Forth Dimensions. Sorry, I don't have the reference handy. The name of the word was "TO" instead of ":=", so this concept has become known as "TO VARIABLES". They were used as: A B + TO C The implementation suggested in the article made such variables "smart" at execution time. The word "TO" set a global flag, and whenever a to-variable executed, it decided to fetch or store based on the value of the flag. This clearly had some bad features in terms of execution speed and the existence of the global state variable. Lately the idea has resurfaced in the form of so-called "QUAN"s. A QUAN is a variable that has three separate behaviors: 1) The default behavior is to fetch, that is to leave its value on the stack. 2) The secondary behavior is to store the value on the stack into the variable. 3) The tertiary behavior is to leave the address of the variable on the stack. Normally, QUAN variables behave as in 1). If the QUAN is preceded by the word "TO" (I think this is the correct word, but I may be wrong), behavior 2) is chosen, and if preceded by the word "ADDR", behavior 3 is chosen. The QUAN words themselves have 3 code fields, one for each of the behaviors, and the appropriate code field address is selected at compile time, thus eliminating the run-time speed penalty. The QUAN concept in various forms is getting a lot of attention. In particular, the last issue of the Journal of Forth Application and Research had two articles proposing a defining syntax for words with multiple code fields. Philosophically, such a word is an "object", in the sense that it defines a data structure and a set of operations which may be performed on that data. The concept is a useful one, and may usher in a whole new style of programming in Forth. If anyone is interested, drop me a line and I'll dig up the references and post them. Thanks to Gary Grady for bringing up the issue. Mitch Bradley decvax!decwrl!sun!wmb