From: ctm@ardi.com (Clifford T. Matthews)
Subject: Re: The need for an assembler
Organization: ARDI
Date: Thu, 3 Sep 92 06:19:25 GMT

Dear Folks,

>>[entire personal attack and other offensive stuff deleted]

    The personal attack consisted of calling attention to cjl's ignorance that
he has repeatedly shown when discussing HLLs, compilers and compiler
construction technique.  I'd find that offensive too, which is why I prefer to
send e-mail, which, in fact I did.  The only reason I ever posted was cjl's
insistence to misrepresent what he has been told.

>>Matthews claims that his code duplicates the assembler algorithm.  It doesn't,
>>rather it mimics it using longword arithmetic to circumvent the problem of
>>being ignorant of the potential for algorithmic failure.

No.  It doesn't use longword arithmetic, it never did.

	Again, with cjl's permission, I'm happy to post our correspondence,
and you can read about the fixed range test and make up your own mind.  It
is clear that cjl doesn't know C, so much of his talk about C is flat out
wrong.  The same is true about his knowledge of compilers.  The code that
I sent him did not use longwords; it has exactly the same restriction that
the algorithm that he codes in assembler does; it requires twos complement
arithmetic and that the difference between the upper bound and lower bound
be less than or equal to "maxint" (i.e. (2^(n-1))-1 since we require twos-
complement arithmetic).

>>On many machines the
>>use of extra precision is either unavailable or a potentially severe tradeoff
>>of either space or speed.  In any case, there is always a problem since this
>>is a "pyramid structure" argument because how can you implement the last
>>generation of the algortihm for a given precision arithmetic when you just
>>ran out of bits?

Since the C code doesn't require any different precision than what the
assembler code requires, this argument doesn't make any sense.

>>The fact that gcc implements the DP trick indicates that it is true that a
>>compiler can use second-rate tricks, it in no way validates any claims of
>>superiority to hand assembly.

Funny, the code that I wrote doesn't rely on GCC at all; it will work with
any C implementation that uses twos complement arithmetic.  But since cjl
doesn't know C, (or at least how unsigned and signed arithmetic works in C),
he doesn't realize this.  This is not the first time that his argument is just
plain flat out wrong due to his ignorance of the issues.

>>It would be interesting to find a version of
>>GCC that can generate MS-DOS-compatible code for execution on 8086/88 and/or
>>80286 where this algorithm can't be done.

Again, it doesn't have anything to do with GCC, of course it would work on
an 8086.  Almost all digital computers use twos complement arithmetic.  Yes,
it is that simple.

>>Curiously enough the minimum gcc
>>implementation is for 80386.  (That's why there are GNU-ish projects; they
>>need Microsoft or Borland's "inferior" compilers to get implemented.)

There he goes again.  GNU does not need Microsoft or Borland's compilers to
get implemented, because GCC is available as a cross compiler.  Ritchie's
original recursive descent C compiler might be a sufficient bootstrap. S.C.
Johnson's PCC or PCC-2 are sufficient bootstraps.  I'm not sure what is curious
about the minimum gcc implementation being for a 386.  I've quite openly
stated that GCC isn't available on PDP-8's either, but perhaps that's another
curiousity.

>>The ultimate point of all of this is that, as others have pointed out, C
>>is not the panacea that Matthews and others believe it is.  His misguided
>>belief in the algorithm he stumbled across in no way affects the technical
>>merits of any of my arguments against the expediency of hll usage, especially
>>C.  High-level language was developed with the understanding of a tradeoff
>>of performance vs. development ease.  Matthews wants to handwave that into
>>the notion that the tradeoff is nonexistent.  And we never got into the
>>more substantive issues of interrupt handling w/foreground handling in
>>real-time or the *efficient* use of co-routines, etc.

I've never said it's a panacea.  I've specifically mentioned that our current
product has ~4000 lines of assembler in it (as well as ~400 lines of YACC,
~5000 lines of Objective C, and ~62000 lines of C).  I've also mentioned
that our product is a weird application; a Macintosh emulator is not your
average application; it's an operating system unto itself (we should have
it running on bare bones machines, with no OS underneath it, within a year).
The issue is that I know C very well and assembler very well, and am familiar
with the current state of compilers.  I will restate again, for everyone to
read, Modern C compilers produce code that is more efficient than assembler
that I hand write, because a computer is very good at tedious things, and
optimizing assembly is a tedious task.  cjl has stated that assembler
programmers optimize as they write, but a few people have pointed out
experiences that contradict that.

I could go on to talk about "substantive" issues of interrupt handling,
co-routines, etc., but again, it would be a one-sided discussion, since
cjl doesn't know C well enough to talk about it, much less how modern
compilers work.

As for my handwaving:  Primarily my letters have addressed
cjl's discussion of range checking an integer with one compare.  That is
what my last post was primarily about, that's what this one's about.  Why
should I talk about any other issue, while cjl so stubbornly refuses to admit
the correctness of the code that was sent to him via e-mail?  I'm not going
to waste my time trying to nail jello to the wall.

>>This is not an attack on the work of Richard Stallman and other fine
>>programmers, who use both assembler and hll where they see fit.

Huh?  I don't know what you're talking about w.r.t. Richard Stallman using
assembler where he sees fit.  He's clearly qualified to do so, and he probably
has somewhere (he's probably sung "Happy Birthday" too, but I can't think of
a particular instance), but there's no assembler that I know of in gcc, I
don't recall seeing any in emacs either (he may provide some assembly versions
of alloca for emacs, but he definitely provides a C implementation).  It sounds
like this is just another ill-founded assumption.  Again, look at the source
to GCC (it's about 250,000 lines of C, another 50,000 lines of machine specific
.h files and another 50,000 lines of machine specific ".md" files (".md" being
machine description, using a lisp-like syntax)).

>>The parameters
>>of their requirements guide them as necessary.  Their position isn't as far
>>afield from mine as Matthews et al would indicate.  I just refuse to ascribe
>>larger-than-life properties to compilers.

My questions are simple:  Has cjl looked at the optimizations that GCC does
at the RTL level?  Has cjl looked at the optimizations that are done at
the backend?  If not, how can cjl tell what's larger-than-life?  Specifically
what have I said that makes the compiler larger-than-life?  That it can
generate better assembly than I (and most programmers, including cjl) can?

The reasons that I've publically discussed cjl's ignorance are:  1) his
comments w.r.t. compilers may sound like they're accurate if you aren't
familiar with compiler technology, but they're six foot day-glow flashing
signs of ignorance to anyone who does know how compilers work (as Jim Frost
and others have pointed out).  2) His challenge about range checking with one
compare was answered (politely, by e-mail) and he continues to misunderstand
that a proper solution to that one question was shown.

For the record, I realize that given a small task, and plenty of time to spend,
it is possible in some cases to write assembly that's better than what a good
compiler produces, and in fact, for loops with several million iterations, it
may be a worthwhile endeavor (after the code has been written and tested).
Again, *I use assembly in my professional work*.  I cut my teeth on "PDP-8"s,
"PDP-11"s, and the good ol' UNH "Dec-10"s.  I'm exceeding familiar with the
code gcc produces, because I spend much of my time debugging at the assembler
level.

To cjl (my answerers are in parens):

Where do you get your information about compilers?
    (I use C extensively, my C.S. masters emphasis was compiler construction)

Is there any chance that it's outdated?
    (My education is outdated; I got my M.S. in '85, my knowledge of gcc is
     fairly up to date, although I deal mostly with GCC 1.xx instead of 2.xx)

Have you read "the dragon book?"
    (The first edition, yes, much of it, as well as several other books on
     compiler construction; the second edition sits on my shelf uncracked)

Have you examined GCC (remember folks, the source to gcc is available for
free.  If you'd like to make up your own mind, check it out)?
    (Yes, we've modified GCC locally to make it understand "Macintosh"
     calling conventions, and other things)

How many years of C experience do you have?
    (Eleven)

If there's such a large discrepancy between how useful C and assembler is,
why aren't you trying to leverage your superior knowledge into millions of
dollars?
    (To some extent I am; the original Macintosh ROMs were written in assembly,
     and that has been a major drawback of them from day one.  Our code is
     written in C, and our code is probably worth millions of dollars, largely
     because it's written in C, but that falls into the portability category
     more than the speed category, however, our C implementation of seedfill
     is faster than Apple's assembly implementation, and many people were
     very impressed by their version.  Granted hand-crafted assembler might
     be able to speed it up a bit more, but I wouldn't have the time to do that
     and all the other cool stuff we've done in C.  If you have a NeXT, check
     out our product; if you have something else, wait for us to finish
     our synthetic CPU (written in C, uses dynamic recompilation) so we can
     bring Executor to other platforms.)

To everyone:  If you really think that you get that much of a speed boost
hand-coding in assembly, try this.  Find out if your local Univeristy runs
a programming contest (many of them do, to determine who to send to the
ACM regional programming cotest).  Find someone of your own caliber who
programs in C (e.g., if you consider yourself a real good assembly programmer,
find a real good C programmer, if you're mediocre, find a mediocre C
programmer).  Enter the contest, with you programming in assembler and your
alter-ego programming in C.  At the end of the contest, compare number of
problems successfully solved, *and the runtime that each takes.*  If you can't
find a programming contest, I can probably get you the questions for this
years UNM contest (coming in September or October).  Of course this isn't
a very controlled experiment, but it's something you can do in your spare
time.  In most cases I believe you can even give extra points for having a
correct program run faster than the counterparts correct program, and give
the assembler programmer several multiples more time to work in (e.g. the UNM
contest normally runs in 6 hours, but you could give the assembler programmer
24 hours, etc.).  The assembler programmer still has a fighting chance because
the contest problems are much more simple than problems in real life.

If you're a student, and you think that your Professors are misrepresenting
the benefits of programming in a high level language, talk to them about it;
grill them for examples; take a course in compiler construction; ask for good
references to articles in the literature.  If you are self-taught, try to find
a Professor who's willing to talk to you without forcing you to take a class
(unless of course, you have the time and desire to take a class).  Usenet does
not provide a fraction of the bandwidth to discuss the real issues in depth,
but the fact that fewer and fewer are programming in assembly is not a sign
that we're failing to make progress, quite the opposite.

	--Cliff

BTW, for people who repeatedly say that assembly can't be beaten when code size
is important, in many cases interpretive code is smaller yet.
Newsgroups: alt.folklore.computers