jpenne@ee.ualberta.ca (Jerry Penner) (03/30/91)
In article <13156@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: >Gee, Todd don't get so defensive! (:-)) [ stuff about timing critical code and the plethora of Mac/PC SW nuked ] >One thing really amazes me: people's insistence on writing Operating Systems >in HLLs like C. It is actually *easier* to write most of the OS in assembly >than it is to write it in C. It's just that modern day OS writers are >incompetent assembly language programmers so they force C to do the job for >them. They might be incompetent assembly language programmers but there is a bigger reason why OS writers do not want to use assembly language. Portability. It makes a lot more economic sense to write in a more portable language than in assembly. I think this is the most important reason OS writers use C. I agree that using assembly is probably easier to write an OS in, because you don't have to fight the HLLs tendencies to constrict you into doing something in a certain way. I disagree that most OS designers/writers are incompetent assembly programmers. They also probably have orders from mgmt to use C or some other HLL (like Modula 2 or 3). [ stuff about OS course deleted ] -- ------------- Jerry Penner alberta!bode!jpenne Edmonton, Alberta, Canada -- Go ahead, make my nanosecond! --
gwyn@smoke.brl.mil (Doug Gwyn) (03/30/91)
In article <1991Mar30.080418.16299@ee.ualberta.ca> jpenne@ee.ualberta.ca (Jerry Penner) writes: >Portability. It makes a lot more economic sense to write in a more >portable language than in assembly. I think this is the most >important reason OS writers use C. I think that's an argument for UNIX, but not in general. Texas Instruments, for example, wrote at least some of their OSes in an extended version of Pascal; Burroughs wrote theirs in ESPOL, which resembled Extended Algol; and DEC wrote VAX/VMS mainly in Bliss, which is very analogous to C although different in detail. In all these cases (UNIX also), an important consideration was that it is simply easier to do a good job using a structured high-level language. The fact that there was negligible impact on performance was of course crucial. >I agree that using assembly is probably easier to write an OS in, >because you don't have to fight the HLLs tendencies to constrict >you into doing something in a certain way. C was specifically designed to allow a high degree of exploitation of the system architecture from within a structured high-level language. There are a few things that normally HAVE to be done in assembly language, such as the glue between trap vectors and the C code that processes the interrupts, but these are relatively few and easily isolated.
rhyde@gibson.ucr.edu (randy hyde) (04/02/91)
If I was a hardware manufacturer writing an OS for an Apple II gs, the last thing I'd worry about is portability. Performance of my hardware is a much greater concern. That's why Apple has written their OSes in assembly in the past. Hopefully they will not succumb to the HLL trait. It's always amazing to me how much more money people are willing to spend on faster CPUs (8088->80286->80386->80486) but they're unwilling to spend more money on software to develop it in assembly rather than C. I'm not talking about one-of-a-kind programs here, I'm talking about high volume applications like word processors, spreadsheets, and the like. Guess the programmers never really have to *use* the software they write. OSes are the backbone of a machine. Furthermore, they are *pure overhead*. A high performance one will not speed up applications programs. A low performance one, however, can cripple applications. When I'm sitting at a machine running applications I could care less how portable the OS is. I want it to be fast!
gwyn@smoke.brl.mil (Doug Gwyn) (04/03/91)
In article <13202@ucrmath.ucr.edu> rhyde@gibson.ucr.edu (randy hyde) writes: >OSes are the backbone of a machine. Furthermore, they are *pure overhead*. Not so -- operating systems almost always provide support services, such as I/O management, for applications. If the OS didn't do it, the application would have to. There is great value in having a single consistent implementation of such services, even if task scheduling were not needed. Even MS-DOS systems have a "BIOS" that is designed to provide basic I/O services, not overhead. We have graphical performance monitors for a lot of our UNIX systems; these show what percentage of processor time is spent in various "modes". For example, "user" mode is pure processing without OS involvement, while "system" time is spent in the kernel, either on behalf of applications or in genuine overhead, and "idle" mode is time when the processor is not needed for anything. We find that a lightly-loaded system spends typically less than 1% of its processing in the kernel (due to always having a bunch of daemons handling network traffic, etc., not to mention having to run at least the monitoring process, it cannot be precisely 0%, which is the theoretical ideal). With numerous time-sharing tasks heavily competing for system resources, we nevertheless often attain "user" mode utilization over 90%, and on our multithreaded applications we have been able to attain around 99% "user" mode processing when the application is crunching numbers and not doing I/O concurrently. Thus, system overhead, at least on our UNIX systems, is close to negligible, even if one doesn't allow for the convenience of having the I/O, IPC etc. services that the OS provides. And the vast majority of the code executed by the UNIX kernel is written in C. Efficiency arguments about C versus assembler for the bulk of an OS kernel are thus spurious.
kadickey@phoenix.Princeton.EDU (Kent Andrew Dickey) (04/03/91)
In article <15682@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: [Lots deleted...] >With >numerous time-sharing tasks heavily competing for system resources, >we nevertheless often attain "user" mode utilization over 90%, and on >our multithreaded applications we have been able to attain around 99% >"user" mode processing when the application is crunching numbers and >not doing I/O concurrently. > >Thus, system overhead, at least on our UNIX systems, is close to >negligible, even if one doesn't allow for the convenience of having >the I/O, IPC etc. services that the OS provides. And the vast >majority of the code executed by the UNIX kernel is written in C. >Efficiency arguments about C versus assembler for the bulk of an OS >kernel are thus spurious. Doug misses an important point here in what those numbers mean. Unix uses timer interrupts to determine when to switch from one process to the next (so one doesn't monopolize the CPU time). After a program has been running for more than N clock ticks, that process is preempted and moved to the back of the queue (all of this is basically right, but there are a lot more subtleties to it all). Those numbers that Doug is quoting are calculated simply--when a timer interrupt occurs, the system merely figures out what state the machine was in when the interrupt came (either system or user) and increments a counter. However, there are times when interrupts are not enabled! Thus, the interrupt cannot occur at those times, and so the numbers calculated are not exactly right. In fact, during a context switch, these interrupts will not occur, so those numbers do not include times the system is taking to switch among processes (on most systems). Those numbers are really only meaningful in finding out whether the computer is spending a lot of time in the kernel calls (like read(2), write(2), pipe(2), etc.) and not in simple OS overhead. Granted, Doug's system may do the numbers absolutely correct (I don't know what he's running), but I wouldn't bank a lot on the validity of the numbers he's quoting. Unix has an incredible amount of overhead. Kent kadickey@phoenix.Princeton.EDU
jerry@polygen.uucp (Jerry Shekhel) (04/03/91)
jpenne@ee.ualberta.ca (Jerry Penner) writes: > >I agree that using assembly is >probably easier to write an OS in, because you don't have to fight the >HLLs tendencies to constrict you into doing something in a certain >way. > I doubt it. Modern OS's with their multitasking and inter-process communication capabilities are much more complex than most application programs. They have to manipulate process lists, maintain I/O request queues, use statistical methods and even heuristics to re-prioritize tasks, etc. And I'm not even talking about things like graphical window management and such. Don't tell me all these things are easier to code in assembly language than, say, C. Sure, operating systems used to be simple; all they did was talk to the hardware. For these, assembly language was acceptable. MS-DOS is such a system. But for modern OS's like UNIX, assembly language just gets in the way, and doesn't provide significant performance advantages. By the way, what tendencies do HLL's have that "constrict you into doing something in a certain way"? > > Jerry Penner alberta!bode!jpenne Edmonton, Alberta, Canada > -- +-------------------+----------------------+---------------------------------+ | JERRY J. SHEKHEL | POLYGEN CORPORATION | When I was young, I had to walk | | Drummers do it... | Waltham, MA USA | to school and back every day -- | | ... In rhythm! | (617) 890-2175 | 20 miles, uphill both ways. | +-------------------+----------------------+---------------------------------+ | ...! [ princeton mit-eddie bu sunne ] !polygen!jerry | | jerry@polygen.com | +----------------------------------------------------------------------------+
rhyde@koufax.ucr.edu (randy hyde) (04/04/91)
>>>
Thus, system overhead, at least on our UNIX systems, is close to negligible...
<<<
How did you come up with this? Have you actually rewritten the kernel in
assembly and compared the difference? Warm fuzzy feelings about it don't
count.
Now, perhaps, what you really mean to say is "Gee, we write all of our apps
in "C" and we write them in a sloppy fashion (i.e., slow). They eat up so
much CPU time that the overhead of the O/S pales in comparison."
I could buy that. However, it's not a good argument for writing OSes in
C. Some of us *do* write very high performance software in assembly and don't
need boat anchors like UNIX slowing us down!
BTW, I recently rewrote a MINIX-based SCSI device driver in assembly
(the original
code was in C). It actually took fewer lines of code (NS32532) and ran about
an order of magnitude faster. While this is not an entire O/S, I suspect the
process manager would fare much better in assembly. The memory manager
probably
would be better in assembly (warm fuzzy, I wouldn't bet anything on it). The
file manager probably wouldn't gain much in assembly over C assuming the device
drivers were written in assembly.
JWANKERL@UTCVM.BITNET ("Josef W. Wankerl") (04/05/91)
On Wed, 3 Apr 91 15:59:44 GMT Jerry Shekhel said: >I doubt it. Modern OS's with their multitasking and inter-process >communication capabilities are much more complex than most application >programs. They have to manipulate process lists, maintain I/O request >queues, use statistical methods and even heuristics to re-prioritize tasks, >etc. And I'm not even talking about things like graphical window management >and such. Don't tell me all these things are easier to code in assembly >language than, say, C. ACK!!!! "Easy" is a relative term. I could probably code something much faster in C, but I could do a much better job in assembly (on the IIGS, other architectures may vary.) Saying it's easier in C than assembly - well - the concepts are all the same, I can implement a linked list and queues and binary trees and all sorts of other nifty constructs with assembly, and I have lots more flexibility with my assembly constructs, too. ...and sometimes the easy way out isn't always the best way. >-- >+-------------------+----------------------+---------------------------------+ >| JERRY J. SHEKHEL | POLYGEN CORPORATION | When I was young, I had to walk | >| Drummers do it... | Waltham, MA USA | to school and back every day -- | >| ... In rhythm! | (617) 890-2175 | 20 miles, uphill both ways. | >+-------------------+----------------------+---------------------------------+ >| ...! [ princeton mit-eddie bu sunne ] !polygen!jerry | >| jerry@polygen.com | >+----------------------------------------------------------------------------+ -- ===> Josef W. Wankerl, Technical Editor for GS+ Magazine BITNET: JWANKERL@UTCVM.BITNET | America Online: JWankerl ProLine: jwankerl@pro-gsplus |-------------------------------- Internet: jwankerl@pro-gsplus.cts.com | "I am a Viking" -Y. Malmsteen
gwyn@smoke.brl.mil (Doug Gwyn) (04/05/91)
In article <7830@idunno.Princeton.EDU> kadickey@phoenix.Princeton.EDU (Kent Andrew Dickey) writes: >However, there are times when interrupts are not enabled! Wrong. The scheduler clock on our systems is serviced reliably. >Unix has an incredible amount of overhead. Also wrong in general, although perhaps true of some implementations if you overload them to the point that they start pagging or swapping unduly.
gwyn@smoke.brl.mil (Doug Gwyn) (04/05/91)
In article <13275@ucrmath.ucr.edu> rhyde@koufax.ucr.edu (randy hyde) writes: >>Thus, system overhead, at least on our UNIX systems, is close to negligible... >How did you come up with this? Have you actually rewritten the kernel in >assembly and compared the difference? NO, but the opposite conversion occurred and was reported in the literature which you apparently don't read. >... don't need boat anchors like UNIX slowing us down! I feel sorry for your students.
jcav@quads.uchicago.edu (john cavallino) (04/05/91)
One fact that hasn't yet been addressed in this discussion is the existence of new processor architectures (RISC especially) of such complexity that you REALLY DO NEED A COMPILER TO WRITE EFFICIENT SOFTWARE. I'm talking about things like multi-stage instruction pipelines which must be kept full to achieve good performance. What about branch prediction and register/pipeline interlock, which might involve actually changing the apparent order of instructions? Do you really want to have to keep track of stuff like that, when bunches of very smart people have already written compilers that will do it for you? Machine language isn't always the answer, and I suspect that will become more true in the future. -- John Cavallino | EMail: jcav@midway.uchicago.edu University of Chicago Hospitals | USMail: 5841 S. Maryland Ave, Box 145 Office of Facilities Management | Chicago, IL 60637 "Opinions, my boy. Just opinions" | Telephone: 312-702-6900
rhyde@ucrmath.ucr.edu (randy hyde) (04/05/91)
>>>> By the way, what tendencies do HLL's have that "constrict you into doing something in a certain way"? <<<< All languages (included different assembly languages) have a "programming paradigm". The differences between some languages is subtle (e.g., there are small, subtle, differences between languages like "C" and Pascal, there are considerable differences between languages like "C", Snobol4, ICON, LISP, Prolog, and SETL). Some languages are especially suited for certain apps. For example, Snobol4 and ICON are really great at pattern matching, but fair poorly in number crunching applications. APL is great for linear algebra and matrix arithmetic problems, but you never use it for database manipulation, COBOL isn't good for anything (okay, I couldn't resist that one!). Any application which requires bit pushing, assembly language wins hands down (a good example is a SCSI device driver I have been converting from C to 32532 assembly language). The program will generally shorter by a factor of two or more and about 10-100 times faster. Furthermore, in the hands of competent assembly and C programmers, the assembly language program will be easier to read and understand. This is not an absolute assessment, but it has been true most of the time, in my experience. Applications which push bytes around (e.g., text editors, graphic display drivers, memory managers, etc.) are generally easier to write or not much more difficult to write in assembly than in a language like C. Not all such applications, but a good number of them. Too many times I've started writing such a program in C only to swear at myself well into the project because so many components of the project would have been easier to implement in assembly. Why not write those components in assembly and call them from C? Alas, working in C forces you into a different programming paradigm. You have to think about the problem in a different fashion ("Constricting" is such a harsh term). This paradigm permeates throughout the code. Writing a few procedures or functions in assembly will not let you escape that paradigm. Assembly language programmers *think* about problems differently than C programmers. This is the true reason good assembly language programmers write much faster code than C programmers. If you write "C" code using MOVs (or LDAs), you're code isn't going to be much faster or much smaller than the output of the compiler. Indeed, optimizing compilers may beat the pants off of people acting as human compilers. I'm sure this is what the original poster was alluding to when s/he made the above comment. Of course, there are some applications where the choice of assembly language is not appropriate. Assuming a decent toolkit of library routines written in assembly language, I could not justify writing user interface code in assembly language. C, Pascal, or something at a high level (like 4th Dimension on the Macintosh) is more appropriate. And there would be very little performance benefit to sticking with asm. >>> I doubt it. Modern OS's with their multitasking and inter-process communication capabilities are much more complex than most application programs. They have to manipulate process lists, maintain I/O request queues, use statistical methods and even heuristics to re-prioritize tasks, etc. And I'm not even talking about things like graphical window management and such. Don't tell me all these things are easier to code in assembly language than, say, C. Sure, operating systems used to be simple; all they did was talk to the hardware. For these, assembly language was acceptable. MS-DOS is such a system. But for modern OS's like UNIX, assembly language just gets in the way, and doesn't provide significant performance advantages. <<<<< An OS, though, is a byte pusher. The process manager, communications managers, device managers, and user interface toolkits would all benefit from being written in assembly. The file manager is questionable. Manipulating process lists, I/O request queues, and reprioritzing tasks is no big deal in assembly language. I teach OS (CS 431) at Cal Poly Pomona. I make my students write their code in 8086 assembly language. These are people who are totally incompetent in assembly language. Yet they manage to accomplish these tasks quarter after quarter. Statistical methods and heuristics are definitely beyond these students, but they're not beyond me. They are just fancy names for some really simple processes. Certainly not too complex for a reasonable assembly language programmer. Keep in mind, that re-prioritizing tasks occurs at the level of the short and medium-term scheduler. These processes have to be very fast! Indeed, even in UNIX the dispatcher (i.e., short-term CPU scheduler) is typically written in assembly language. As for the Graphical User Interface- No way is this easier to write in assembly than in C. But there is an obvious performance benefit to having this written in assembly. X-Window is a good example of what happens when you try to write such code in C. It's wonderful that X is portable, but you need a H**L of a machine run in reasonably well. I'd hate to imagine a PC (<386), Mac, or *egads* an Apple IIgs where the windowing software was written in C. *** RAndy Hyde
rhyde@ucrmath.ucr.edu (randy hyde) (04/05/91)
>>>>
One fact that hasn't yet been addressed in this discussion is the existence
of new processor architectures (RISC especially) of such complexity that you
REALLY DO NEED A COMPILER TO WRITE EFFICIENT SOFTWARE. I'm talking about
things like multi-stage instruction pipelines which must be kept full to
achieve good performance. What about branch prediction and
register/pipeline interlock, which might involve actually changing the
apparent order of instructions? Do you really want to have to keep track
of stuff like that, when bunches of very smart people have already written
compilers that will do it for you? Machine language isn't always the answer,
and I suspect that will become more true in the future.
<<<<
I let some people sucker me into believing this. I swear I'm gonna teach
myself SPARC assembly before I make any cracks one way or another on this
topic. However, please allow me to make one quick comment: Why on earth
can't we write an *optimizing assembler* which rearranges instructions
to keep the queues full, and warns you if you're not using the registers
as efficiently as you possibly could? This would address the statement
that one really needs a compiler to write efficient code on a RISC.
Remember, it isn't just the instruction mix which makes human-written
assembly language programs better than machine-written assembly language
programs, it's the intelligence of the auther and the way s/he thinks
about the solution to the problem.
As an aside (which I'm sure will start another flaming thread), I suspect that
RISC's days are numbered. Most of the advantages of RISC are being implement-
ed into CISC, and what CICS will never be able to handle, LIWCs will blow
both RISC and CISC away on. I suspect that VCISC computers, once someone
comes up with a better system bus structure (e.g., optical) will prove
that RISC is a dead end.
*** Randy Hyde
rhyde@ucrmath.ucr.edu (randy hyde) (04/05/91)
>>>> NO, but the opposite conversion occurred and was reported in the literature which you apparently don't read. >... don't need boat anchors like UNIX slowing us down! I feel sorry for your students. <<< Not only have I read that literatur (from the early '70's I might point out, my how things have changed since then!), I assign it as reading. Don't feel sorry for my students. They come out of that class with a major prejuidice against assembly removed. By the time they're seniors they've written a *lot* of C and Ada code, yet very little assembly. They are excited by the end of the quarter. A good number of them exclaim happily that "Gee, I really learned assembly language this quarter, it's nowhere near as bad as I thought it was." To bad *YOU* never had this experience. One other comment about the literature you are obviously refering too: keep in mind that the "C" which UNIX was originally re-written in was an over-glorified assembler for the PDP-11. C's syntax (e.g., ++i) was designed to take advantage of the PDP-11's instruction set and hardware. When you look at how C has grown (e.g., ANSI C and C++) and you look at the various architectures it's running on (65c816, 8086, SPARC, R3000, etc.), I believe you'll discover that compiling UNIX in C won't universally produce the same results the original programmers found on the PDP-11. *** Randy Hyde
gwyn@smoke.brl.mil (Doug Gwyn) (04/06/91)
In article <13345@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: >X-Window is a good example of what happens when you try to write such code >in C. It's wonderful that X is portable, but you need a H**L of a machine >run in reasonably well. I'd hate to imagine a PC (<386), Mac, or *egads* >an Apple IIgs where the windowing software was written in C. Again I have to challenge this, using real-world evidence. The bitmap graphics interface (including multitasked windows) I'm using while typing this has nearly all of its firmware and applications written in C, and it uses a processor and clock comparable with low-end Macintosh models. Its interactive performance far exceeds that of X11 terminals, and also exceeds that of the Macintosh Finder and of Microsoft Windows on a 33MHz IBM PC/AT clone. If it had had to have been programmed in assembler, I doubt very much that it would ever have been developed. X11 indeed suffers from several problems, but none of them are due to use of C.
gwyn@smoke.brl.mil (Doug Gwyn) (04/06/91)
In article <13348@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: >One other comment about the literature you are obviously refering too: >keep in mind that the "C" which UNIX was originally re-written in was >an over-glorified assembler for the PDP-11. C's syntax (e.g., ++i) was >designed to take advantage of the PDP-11's instruction set and hardware. While C is a good match for the PDP-11, it is as equally good match for the VAX and MC68000 instruction sets. Most modern CPUs were designed, unlike the afore-mentioned, with the idea that the majority of programs for them would be coded in HLLs, and thus if their designers did a decent job they should also be good matches for HLLs, certainly including C, which is the most popular of all HLLs these days. As I mentioned in private correspondence with you and also, as I recall, some time ago in this newsgroup, the 65816 instruction set does not do a very good job of supporting HLLs, so there are cases where assembly code is preferred in Apple II applications (such as display animation loops). But that does not support the argument that assembly coding should be preferred in most cases.
jh4o+@andrew.cmu.edu (Jeffrey T. Hutzelman) (04/06/91)
gwyn@smoke.brl.mil (Doug Gwyn) writes: > In article <13345@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: > >X-Window is a good example of what happens when you try to write such code > >in C. It's wonderful that X is portable, but you need a H**L of a machine > >run in reasonably well. I'd hate to imagine a PC (<386), Mac, or *egads* > >an Apple IIgs where the windowing software was written in C. > > Again I have to challenge this, using real-world evidence. The bitmap > graphics interface (including multitasked windows) I'm using while > typing this has nearly all of its firmware and applications written in > C, and it uses a processor and clock comparable with low-end Macintosh > models. Its interactive performance far exceeds that of X11 terminals, > and also exceeds that of the Macintosh Finder and of Microsoft Windows > on a 33MHz IBM PC/AT clone. If it had had to have been programmed in > assembler, I doubt very much that it would ever have been developed. > > X11 indeed suffers from several problems, but none of them are due to > use of C. Me too. The machine I'm sitting at (a DECstation 3100) uses a RISC architecture that no one in his right mind would want to program in assembly for. The C compiler generates much more efficient code than any human programmer I know, and I know plenty of decent human programmers. -------------------- Jeffrey Hutzelman America Online: JeffreyH11 Internet: jh4o+@andrew.cmu.edu BITNET: JHUTZ@DRYCAS >> Apple // Forever!!! <<
rhyde@ucrmath.ucr.edu (randy hyde) (04/06/91)
>>>>
Me too. The machine I'm sitting at (a DECstation 3100) uses a RISC
architecture that no one in his right mind would want to program in
assembly for. The C compiler generates much more efficient code than
any human programmer I know, and I know plenty of decent human
programmers.
<<<<
The MIPS R2000 and R3000 archetectures are not that bad. Would decent
tools appear (e.g., an asm data flow analyzer) it would be perfectly
possible to program it any assembly language with no problem (other than
a steep learning curve).
Of course, as machines get faster and faster, the point really becomes one
of economics. If C programs run between 1/2 and 1/10th the speed of
assembly language programs and you can buy a machine that is two to ten
times faster, you can easily opt for the faster machine and do all your work
in C. My original post did not claim that *everyone* should write *all*
their applications in assembly. I simply stated that I spend lots of extra
money on high-end machines so that they will execute their applications
*fast*, not so those application authors can write their programs in C
rather than assembly.
Some people around here think that I'm totally against the use of HLLs.
Nothing could be farther from the truth. Indeed, I consider languages like
C and Pascal low(er) level languages. HLLs encompass things like Prolog,
ICON, 4GLs, SETL, and the like. Why don't we write applications in these
languages? For many applications I can write a program in SETL ten times
faster than you can write it in C. Why don't we write all (applicable)
software in SETL? There are two reasons: SETL is dreadfully slow (although
I'll counter that by saying "buy a faster machine"); SETL isn't
appropriate for all applications. However, you can make both of these
statements about *any* programming language *except* assembly. For assembly,
only one of the statements might be true (dreadfully slow isn't the correct
answer).
pnakada@oracle.com (Paul Nakada) (04/06/91)
In article jh4o+@andrew.cmu.edu (Jeffrey T. Hutzelman) writes: >gwyn@smoke.brl.mil (Doug Gwyn) writes: >>In article <13345@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: >>>X-Window is a good example of what happens when you try to write such code >>>in C. It's wonderful that X is portable, but you need a H**L of a machine >>>run in reasonably well. I'd hate to imagine a PC (<386), Mac, or *egads* >>>an Apple IIgs where the windowing software was written in C. >> >>Again I have to challenge this, using real-world evidence. The bitmap >>graphics interface (including multitasked windows) I'm using while >>typing this has nearly all of its firmware and applications written in >>C, and it uses a processor and clock comparable with low-end Macintosh >>models. Its interactive performance far exceeds that of X11 terminals, >>and also exceeds that of the Macintosh Finder and of Microsoft Windows >>on a 33MHz IBM PC/AT clone. If it had had to have been programmed in >>assembler, I doubt very much that it would ever have been developed. >> >>X11 indeed suffers from several problems, but none of them are due to >>use of C. > >Me too. The machine I'm sitting at (a DECstation 3100) uses a RISC >architecture that no one in his right mind would want to program in >assembly for. The C compiler generates much more efficient code than >any human programmer I know, and I know plenty of decent human >programmers. >-------------------- I think the important thing to realize is not that the compiler generates more efficient code, but that these days, CPU's are designed with compilers in mind. Efficient, with respect to compiler generated code, does not necessarily mean tight, small, and tricky code, but it refers to code that takes the greatest advantages of processor strengths and limits the effects of processor weaknesses. Granted, this is nothing that someone couldn't do directly in assembly, but why do it, when the compiler will do it for you? -Paul Nakada -- Paul Nakada | Oracle Corporation | pnakada@oracle.com
gwyn@smoke.brl.mil (Doug Gwyn) (04/07/91)
In article <13390@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: >ICON, 4GLs, SETL, and the like. Why don't we write applications in these >languages? You omitted one of the most important reasons in the real world: Most such languages are not sufficiently widely available. That is also true in spaces of any specific assembly language. Few programs that I write run on only the system they were intially implemented for; most of them end up being heavily used on a large number of quite different computer systems, ranging from Apple IIs to Cray-2s. SETL or iAPX366 assembler would have been an utter waste of time.
jerry@polygen.uucp (Jerry Shekhel) (04/09/91)
In article <13345@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: > >All languages (included different assembly languages) have a "programming >paradigm". The differences between some languages is subtle (e.g., there >are small, subtle, differences between languages like "C" and Pascal, there >are considerable differences between languages like "C", Snobol4, ICON, LISP, >Prolog, and SETL). Some languages are especially suited for certain apps. > I see your point; I guess I was just thinking of C. I still don't see how anything could be easier to code in assembly language than in C. Maybe that's why they say that C is not a real high-level language. > >Any application which requires bit pushing, assembly language wins hands >down (a good example is a SCSI device driver I have been converting from C >to 32532 assembly language). The program will generally shorter by a factor >of two or more and about 10-100 times faster. Furthermore, in the hands of >competent assembly and C programmers, the assembly language program will >be easier to read and understand. This is not an absolute assessment, but >it has been true most of the time, in my experience. > I must disagree with this, again, keeping C in mind. Any decent compiler will optimize register usage, and C expressions like "a <<= 5" or "a &= ~0x1234" will normally compile down to a single instruction. So I really don't see your "bit-pushing" argument here, and certainly not the performance increase factors you quote. Of course, you may have been thinking of FORTRAN or LISP... -- +-------------------+----------------------+---------------------------------+ | JERRY J. SHEKHEL | POLYGEN CORPORATION | When I was young, I had to walk | | Drummers do it... | Waltham, MA USA | to school and back every day -- | | ... In rhythm! | (617) 890-2175 | 20 miles, uphill both ways. | +-------------------+----------------------+---------------------------------+ | ...! [ princeton mit-eddie bu sunne ] !polygen!jerry | | jerry@polygen.com | +----------------------------------------------------------------------------+
jerry@polygen.uucp (Jerry Shekhel) (04/09/91)
In article <13347@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: > >As an aside (which I'm sure will start another flaming thread), I suspect that >RISC's days are numbered. Most of the advantages of RISC are being implement- >ed into CISC, and what CICS will never be able to handle, LIWCs will blow >both RISC and CISC away on. I suspect that VCISC computers, once someone >comes up with a better system bus structure (e.g., optical) will prove >that RISC is a dead end. > I disagree with this, too. The problem (or blessing) is that people don't want to write in assembly language, and the hardware which executes all those complex (CISC) machine instructions is a waste of on-chip real-estate. Typical C compilers only utilize a tiny fraction of the instructions available on a CISC processor, so what's the point? The upshot of RISC is that these chips are smaller, they require less power, they are more easily scaled down, and less hardware is necessary for decoding the instructions, all of these factors leading to much greater performance. The typical RISC microprocessor contains under 100,000 transistor components. Compare that to the 1 million+ in the 486! The only disadvantage I see with RISC is that executable programs compiled for RISC are approximately 30% larger than equivalent programs compiled for CISC. > >*** Randy Hyde > -- +-------------------+----------------------+---------------------------------+ | JERRY J. SHEKHEL | POLYGEN CORPORATION | When I was young, I had to walk | | Drummers do it... | Waltham, MA USA | to school and back every day -- | | ... In rhythm! | (617) 890-2175 | 20 miles, uphill both ways. | +-------------------+----------------------+---------------------------------+ | ...! [ princeton mit-eddie bu sunne ] !polygen!jerry | | jerry@polygen.com | +----------------------------------------------------------------------------+
jerry@polygen.uucp (Jerry Shekhel) (04/10/91)
In article <13345@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: > >As for the Graphical User Interface- No way is this easier to write in >assembly than in C. But there is an obvious performance benefit to having >this written in assembly. X-Window is a good example of what happens when >you try to write such code in C. It's wonderful that X is portable, but >you need a H**L of a machine run in reasonably well. > If you think that X-Window's slowness is due to it having been written in C, you are sadly mistaken. The reason it's slow is that it has to convert each call to a network packet, and send it over the network (or socket). The server on the other end, then receives the packet, converts it back to a request, and finally does the requested processing. When this whole process has to be repeated for EVERY SINGLE call, no wonder it's slow. The fact that the software is written in C has zero performance implications here. -- +-------------------+----------------------+---------------------------------+ | JERRY J. SHEKHEL | POLYGEN CORPORATION | When I was young, I had to walk | | Drummers do it... | Waltham, MA USA | to school and back every day -- | | ... In rhythm! | (617) 890-2175 | 20 miles, uphill both ways. | +-------------------+----------------------+---------------------------------+ | ...! [ princeton mit-eddie bu sunne ] !polygen!jerry | | jerry@polygen.com | +----------------------------------------------------------------------------+
rhyde@gibson.ucr.edu (randy hyde) (04/11/91)
Obviously, if you need portability, you would *never* consider using assembly language. Gee, even machines with the same processor (Mac, Amiga, ST) don't allow you to easily port assembly language programs. If you must sacrifice your software on the altar of portability, you will not be able to use assembly language. Those of us who *use* software, as opposed to *write* software could really care less about portability. If I own an IBM PC, I could really care less if Lotus 1-2-3 runs on a Mac, under UNIX, or on an Apple II gs, I only care that it runs on a PC. Sure, there are some people out there who work on different platforms and may need the cross-platform portability, but they are a very small minority. The rest of us could care less (I work on several platforms and I could care less, for example). I'd rather see each program optimized for the particular platform than turned into generic mush which runs on everything.
rhyde@gibson.ucr.edu (randy hyde) (04/11/91)
>> I disagree with this (bit pushing is easier in assembly than in C)
Okay, here's a challenge, code a CRC-16 algorithm in C. I can promise you
that I can do it in few lines of assembly language (on *any* machine) and the
result will be easier to understand to anyone who has a basic understanding of
the instruction set. If you want further proof, let me know and I will post
the two versions of the algorithm. Of course, this is but one example, but I
can come up with a fair number of similar examples.
rhyde@gibson.ucr.edu (randy hyde) (04/11/91)
RE: CISC vs. RISC
Yeah, RISCs are smaller, so what? Yes, todays RISC chips use 100K xstrs, CISCs
use millions. So what? You can buy a 486 chip for less money than most RISC
chips. Where is the savings? CISC manufacturers are not standing still, they
are using those extra transistors to eliminate microcode in the frequently
executed instructions (on a 386 or 486, for example, the LOOP instruction is
actually *slower* than the corresponding DEC CX, JNE instructions because the
DEC and JNE instructions are implemented via random logic and the LOOP
instruction is microcoded; in a future version of the 80x86 family we'll
probably see *all* of the instructions implemented in random logic. It
just takes time to do this).
>>> All of these factors lead to increased performance.
Then why are CISC processors like the 80486 and 68040 comparing
favorably or even out-performing their RISC competitors at equivalent
clock speeds. As for the "They can run at faster clock speeds
arguement", CISC is only about a year behind in brute force clock
speeds, in terms of system throughput rates, high end CISC compares
favorably against high-end RISC today.
RISC has had the obvious benefit of making CISC producers stand up and
take notice. They've stopped using microcode so much and they're
switching to the use of random logic for instruction decoding (*exactly*
the hardware equivalent of the assembly language vs. C arguement).
rhyde@ucrmath.ucr.edu (randy hyde) (04/11/91)
>>>
If you think that X-Window's slowness is due to it having been written in C,
you are sadly mistaken. The reason it's slow is that it has to convert each
call to a network packet, and send it over the network (or socket).
<<<
First of all, mostly high level commands get sent over the network. The
communications performance is bad, but not as bad as you imply. On a system
which doesn't use a network (client and server are all on the same machine)
sockets surely slow you down. Why? That part of the operating system is
written in C! :-)
Seriously, though, scrolling and redrawing are server operations, even these
operations take a fast machine to work reasonably well. On a SPARC this
works okay, on a Sun-3, well you can go take a coffee break. I'd hate to see
it on an Apple IIgs, even with a TWGS.
whitewolf@gnh-starport.cts.com (Tae Song) (04/13/91)
|I disagree with this, too. The problem (or blessing) is that people don't |want to write in assembly language, and the hardware which executes all those |complex (CISC) machine instructions is a waste of on-chip real-estate. |Typical C compilers only utilize a tiny fraction of the instructions available |on a CISC processor, so what's the point? The upshot of RISC is that these |chips are smaller, they require less power, they are more easily scaled down, |and less hardware is necessary for decoding the instructions, all of these |factors leading to much greater performance. The typical RISC microprocessor |contains under 100,000 transistor components. Compare that to the 1 million+ |in the 486! The only disadvantage I see with RISC is that executable programs |compiled for RISC are approximately 30% larger than equivalent programs |compiled for CISC. The reason the i486 has 1,000,000 transistors is because it has everything built-in... 8K cache, MMU, FPU, as will as the CPU itself and logic to handle the interactions within the chip. RISC itself is now even becoming a misnomer, because some RISC chips have more instruction that CISC chips, it's now Simple Instruction Set Chip (SISC)... The point is becoming moot as well, both CISC and RISC are merging and the most inportant think is to keep the instruction time to near 1 cycle or less. The '040 has an average cycle time of 1.3 and the instructions that do more (complex instruct.) take longer and the simpler ones shorter. whitewolf@gnh-starport!info-apple
bh1e+@andrew.cmu.edu (Brendan Gallagher Hoar) (04/13/91)
So I was reading Tae's message on RISC and CISC chips and just remembered a slightly humorous little thing I found out yesterday. Thursday I got my new toy in the mail, a Digitech GSP 21 Pro which is a DSP, etc sound processor specifically designed to be used with electric guitars. Anyway, supposedly the company did a lot of development on the thing using VLSI, etc. They call the engine a HISC processor. I'm thinking to myself, obviously, "What does the H stand for???". Well, yesterday while going thru the manual I came upon a list of acronym definitions. Whats DSP, whats VLSI, etc. HISC Happenin' Instruction Set Computer. Ahem. Only from guitar geeks...sheesh. Brendan G. Hoar bh1e+@andrew.cmu.edu Apartment 1 Carnegie Mellon, Inc. 357 Melwood Ave. Pittsburgh, PA 15213 (412) 621-8278
gwyn@smoke.brl.mil (Doug Gwyn) (04/16/91)
In article <13494@ucrmath.ucr.edu> rhyde@gibson.ucr.edu (randy hyde) writes: >>> I disagree with this (bit pushing is easier in assembly than in C) >Okay, here's a challenge, code a CRC-16 algorithm in C. I can promise you >that I can do it in few lines of assembly language (on *any* machine) and the >result will be easier to understand to anyone who has a basic understanding of >the instruction set. Here is an extract from actual code (being executed for EVERY character being sent to or from the terminal I'm typing this on), not written by me (or it would have been more readable). It is a fair comparison, because it uses the same algorithm with the same interface constraints (e.g., must be callable from C). C version: typedef unsigned char uchar; typedef unsigned short ushort; #define lobyte(X) ((X)&0xff) #define hibyte(X) (((X)>>8)&0xff) static ushort crc16t_32[2][16] = { 0, 0140301, 0140601, 0500, 0141401, 01700, 01200, 0141101, 0143001, 03300, 003600, 0143501, 02400, 0142701, 0142201, 02100, 0, 0146001, 0154001, 012000, 0170001, 036000, 024000, 0162001, 0120001, 066000, 074000, 0132001, 050000, 0116001, 0104001, 042000 }; int crc(buffer, nbytes) register uchar *buffer; int nbytes; { register ushort tcrc = 0; register int temp; register int i; if ( (i = nbytes) > 0 ) do { temp = tcrc ^ *buffer++; tcrc = crc16t_32[0][temp & 017] ^ crc16t_32[1][(temp>>4) & 017] ^ (tcrc>>8); } while ( --i > 0 ); if ( lobyte(tcrc) != *buffer ) i++; *buffer++ = lobyte(tcrc); if ( hibyte(tcrc) != *buffer ) i++; *buffer++ = hibyte(tcrc); return i; } MC68000 assembler version: data crc16t_3: word 0,0140301,0140601,0500 word 0141401,01700,01200,0141101 word 0143001,03300,003600,0143501 word 02400,0142701,0142201,02100 word 0,0146001,0154001,012000,0170001 word 036000,024000,0162001,0120001 word 066000,074000,0132001,050000 word 0116001,0104001,042000 text global crc crc: link %fp,&crcF movm.l &crcM,crcS(%fp) mov.l 8(%fp),%a2 mov.l &0,%d2 mov.w 12(%fp),%d4 ble crc%140 crc%170: mov.b (%a2)+,%d3 eor.b %d2,%d3 mov.l &15,%d0 and.b %d3,%d0 add.l %d0,%d0 mov.l &crc16t_3,%a1 mov.w 0(%a1,%d0.l),%d0 lsr.b &3,%d3 and.w &30,%d3 mov.l &crc16t_3+32,%a0 mov.w 0(%a0,%d3.w),%d1 eor.w %d0,%d1 lsr.w &8,%d2 eor.w %d1,%d2 sub.w &1,%d4 bgt crc%170 crc%140: cmp.b %d2,(%a2) beq crc%180 add.w &1,%d4 crc%180: mov.b %d2,(%a2)+ lsr.w &8,%d2 cmp.b %d2,(%a2) beq crc%190 add.w &1,%d4 crc%190: mov.b %d2,(%a2)+ mov.w %d4,%d0 movm.l crcS(%fp),&crcM unlk %fp rts set crcS,-16 set crcF,-22 set crcM,02034 Frankly, I don't think either version is very intuitive, but both are intended to execute quickly. I would have to wonder about anybody who would claim that there is anything inherently more readable about the MC68000 version. And no fair rewriting it to use a different algorithm or to fit different constraints! I could certainly substantially improve the readability of the C version too under those circumstances.
rhyde@maris.ucr.edu (randy hyde) (04/17/91)
Well, I will post my CRC algorithms a little later (I don't have them here at school, you'll have to wait until I get home). I will attack one premise of yours (or, perhaps, support it). You state the following: "It is a fair comparison, because it uses the same algorithm with the same interface constraints (e.g., must be callable from C)." If these are the constraints you place on assembly language programming then I must support *your* position 100%. It would not be worthwhile writing *anything* (well, just about anything) in assembly language. I don't know if you were the original poster (my memory fades fast on these rwar topics), some- one around here stated that you should always stick to the abstract model of computation that a language has to offer. Anytime you attempt to force one model of computation on a language not suited for it, the end result is in-` efficiency. If you are going to act as a "human compiler" for C, your assembly language code is not going to be as good as someone who "thinks" in assembly language. I do not have time, right now, to analyze your algorithm. As soon as I figure it out I'll post another version of it. We'll see if I can do any better (perhaps, perhaps not). *** Randy Hyde
davewh@microsoft.UUCP (04/17/91)
My two cents:
I found that even though I had plugged on an Apple // for years, my
BEST source of serious knowledge on how a computer works came from 2
classes at MIT: one in which we built a predesigned computer (very
simple little thing, 800KHz clock, 64k RAM. CPU was built out of
little parts); the other one a compiler class.
The first class gave me a very good understanding of how the hardware
works in computers: why this instruction takes n cycles and so on.
The other gave me a good idea on how the compiler translates my C
into assembler. I had had plenty of assembler experience before these
classes, but the real insight doesn't come from programming in
assembler or programming in some HLL - but rather in knowing how the
compiler translates one into the other. Once you know how a compiler
works, it's much easier to locate obscure bugs in some HLL code. One
also can employ many tricks and know to avoid certain things. ie:
struct foo * NewFoo(void)
{
struct foo TheNewFoo;
TheNewFoo.member1 = value1;
TheNewFoo.member2 = value2;
return &TheNewFoo;
}
Do you know why this will FAIL? Do you know the RIGHT way to do it?
Sure, it compiles. It'll even run. I wouldn't write any code like
this though because it's dangerous. The quick and obvious fix is to
take out the '*' and the '&'. I still wouldn't do it that way
though... Anyone know why?
People here are arguing that Assembler should be a required course,
while others say it should only be touched upon or ignored. I
disagree with everyone: first, take a simple HLL course (like C).
Then a compiler class (we didn't have to write a C compiler, but the
language we did invent gave us a good idea of the complexity of
compilers and how they generally work). Then a more esoteric
language, like LISP. By then, students will have generic algorithm
experience and have a good idea on how to construct a program. Next
they get experience in how the compiler does the translation (and
what it gets translated into). They learn the pitfalls of doing
things the wrong way in some HLL. They learn WHY they have to use
'scanf("%d",&intvar)'. Then they learn the language of choice for CS
majors. The one where the compiler is much more friendly than a C
compiler but the students still know the pitfalls (why the thing has
to freeze up every now and then and garbage collect, etc).
The "you build it" computer class teaches people how the OS interacts
with the program. How the hardware handles memory cacheing, virtual
memory, context switching. Students learn why the computer will crash
if too many processes are running. Just what 'load" is. They learn
and appreciate what sort of work is going on. Why they should access
a 2-d array of numbers in row major order and not column major order
(one way causes the virtual memory system to spend all it's time
swapping - I sped a program up by a factor of 10 by simply changing
the order of the loops!). They appreciate the work involved in using
floating point numbers over integers. I could go on and on...
Ok, what do you all think?
Dave Whitney Microsoft Corp, Work Group Apps dcw@goldilocks.lcs.mit.edu or
I wrote Z-Link and BinSCII - send me bug reports. {...}!uunet!microsoft!davewh
I only work here. All opinions herein aren't Bill's, they're mine.
"We're samplin' - Yeah we're doin' it. We take good music an' we ruin it."
-- "Rap Isn't Music"
davewh@microsoft.UUCP (04/18/91)
Raymond Lang <uunet!rex.cs.tulane.edu!lang> asks me (and I answer):
: >struct foo * NewFoo(void)
: >{
: > struct foo TheNewFoo;
:
: > TheNewFoo.member1 = value1;
: > TheNewFoo.member2 = value2;
:
: > return &TheNewFoo;
: >}
:
: >Do you know why this will FAIL? Do you know the RIGHT way to do it?
:
: I'm new at this. What's the problem?
OK, C compilers are pretty simple and predicatable. In fact, Pascal
compilers are very similar. At any rate, they all "create" local
variables on the stack. When a procedure call is made, the calling
function pushes its parameters on the stack and then calls the
function. The function then pushes dummy stuff onto the stack to
allocate enough space for its local variables.
So, upon entry to NewFoo, the top of stack contains the return
address for the function call (no parameters). NewFoo then pushes
enough space onto the stack to hold one foo struct.
Members are now set. Look what's returned: the address of TheNewFoo,
a pointer to some location on the stack (more accurately, a pointer
to some memory currently being used by the stack - memory that will
be used again by the stack). The calling function gets this pointer
back and does what it pleases. What happens when another function is
called? Well, the stack is overwritten (more accurately, the memory
where the stack is is changed). But that pointer I have is supposed
to point to some valid data! The pointer is still OK, but the data
has been corrupted because the next function call has changed the
contents of the memory where the stack is (and where my struct is)!
OK, you say. Don't pass back a pointer. C can pass whole structs
around. So, I change my function to pass back a struct instead of a
pointer to a struct. Well, that'll work. No problem there. The only
reason I wouldn't do it that way is because what if the struct is
HUGE? Passing structs around is terribly inefficient. Lots and lots
of bytes have to copied. You also get into very hairy stuff if the
struct contains pointers. How do you "copy" the struct? Do you copy
the pointers only or do you allocate new memory and copy what the
pointers point to? It depends.
My solution is this:
struct foo * NewFoo(void)
{
struct foo *TheNewFoo = malloc(sizeof(struct foo));
TheNewFoo->member1 = value1;
TheNewFoo->member2 = value2;
return TheNewFoo;
}
Subtle difference here. In this case, I've called the memory manager
and asked it for some memory. Assuming the memory manager works
correctly (which, by the way, on Sun OS 4.1, it does not - it
allocates n-1 bytes for you; the last byte of the memory you ask for
isn't there!), this is a safe thing to do. No other function in the
computer will deliberately interfere with this chunk of memory. It's
*not* on the stack, it's in the heap - a seperate section of memory
that the runtime system manages. Should the stack grow so large that
it runs into the heap, the program will crash - the runtime system
will cause it to crash with a stack overflow error. (This assumes
that you're running on a system that can handle an "infinite" stack.
Mac's and IIgs's have a much smaller limit and you may overflow that
stack long before it runs into the heap.)
Since I've manually allocated new memory, I can pass that pointer
around with confidence. All I need to do is remember to ask the
memory manager to free up that memory when I'm done with it. On unix
systems (and other multitasking environments), you can get away with
not freeing the memory because usually, when a program exits, all of
the space it asked for is freed automatically. This may or may not be
the case with the Mac or IIgs (I don't know). Not freeing your memory
could cause a memory leak and eventually your machine would fill up
with garbage and you'd run out of memory.
LESSON: don't return local struct variables. Manually allocate new
memory and return a pointer to it.
: > Then they learn the language of choice for CS
: >majors. The one where the compiler is much more friendly than a C
: >compiler but the students still know the pitfalls (why the thing has
: >to freeze up every now and then and garbage collect, etc).
:
: What language is that?
Most (not all) would agree, LISP. LISP handles a lot of this memory
management crap for you. Allocations in the heap are done behind your
back. On the downside, freeing is not automatic and there's no way to
do it manually. Therefore, the machine runs out of memory. BUT,
because the system knows that it's very likely that you haven't
REALLY run out of memory, it does what's called a garbage collect. It
examines its list of pointers to objects and the allocated memory. It
does some shuffling around and pushing back and forth and discovers
allocated memory that has absolutely no pointer pointing to it. OOPS.
Free it. After scanning like this, memory is compacted so new
allocations can be made easily.
Symbolics LISP machines may be set up to do quick and dirty garbage
collection while your program is running. This gives you a slight
reduction in performance while giving you more time before a
heavy-duty garbage collect needs to be done. The heavy duty garbage
collect stops the system completely while it shuffles. This can take
a couple of hours (I've seen a machine tied up for 4 hours just
garbage collecting). You can make the machine NOT EVER do garbage
collection, but that isn't wise. The machine just goes right down the
toilet. You get panic messages saying "There's only 180K left!"
"There's only 100k left!" "There's only 60k left!" "There's only 10k
left!" GRONK! Machine crashes.
LESSON: no lanuage is perfect for everything. It depends on what you
want to do and how much operating responsibility you want to take on
for yourself.
Dave Whitney Microsoft Corp, Work Group Apps dcw@goldilocks.lcs.mit.edu or
I wrote Z-Link and BinSCII - send me bug reports. {...}!uunet!microsoft!davewh
I only work here. All opinions herein aren't Bill's, they're mine.
"We're samplin' - Yeah we're doin' it. We take good music an' we ruin it."
-- "Rap Isn't Music"
gwyn@smoke.brl.mil (Doug Gwyn) (04/21/91)
In article <9104181707.AA29942@beaver.cs.washington.edu> davewh@microsoft.UUCP writes: >{ > struct foo TheNewFoo; > return &TheNewFoo; >} >Do you know why this will FAIL? Sure, but it is not necessary to understand code generation to avoid that pitfall. The relevant knowledge concerns the concept of the lifetime of an instance of an automatic variable, which can be dealt with on a purely abstract (HLL) level. A more detailed understanding of one possible method of implementation might help one better appreciate why the language has such a restriction; however, if you simply are careful to obey the language rules you will avoid such problems. I agree with the general sentiment that a well-rounded background in practical aspects of computing can be helpful in making better use of computers. I haven't been arguing against exposure to machine architecture or assembly language. What I have been arguing against is that assembly language should be the language of choice for any significant fraction of computing application implementations.
jerry@polygen.uucp (Jerry Shekhel) (04/22/91)
In article <13516@ucrmath.ucr.edu> rhyde@ucrmath.ucr.edu (randy hyde) writes: > >...[About the X Window System]... > >Seriously, though, scrolling and redrawing are server operations, even these >operations take a fast machine to work reasonably well. On a SPARC this >works okay, on a Sun-3, well you can go take a coffee break. I'd hate to see >it on an Apple IIgs, even with a TWGS. > I use a Sun-3, and the performance of the vanilla MIT X Window Server went up by a factor of about 5 between Release 3 and Release 4. The improvement is unbelievable. And yes, it's still written in C, so go figure. -- +-------------------+----------------------+---------------------------------+ | JERRY J. SHEKHEL | POLYGEN CORPORATION | When I was young, I had to walk | | Drummers do it... | Waltham, MA USA | to school and back every day -- | | ... In rhythm! | (617) 890-2175 | 20 miles, uphill both ways. | +-------------------+----------------------+---------------------------------+ | ...! [ princeton mit-eddie bu sunne ] !polygen!jerry | | jerry@polygen.com | +----------------------------------------------------------------------------+
rhyde@musial.ucr.edu (randy hyde) (04/24/91)
>> It went up by a factor of 4-5...Still written in C...So go figure...
There's nothing to figure, better programming is better programming regardless
of the language. If you've got a better algorithm, it's going to run faster
(assuming that's what's better about the algorithm). As my CRC posts prove,
it's quite possible to have a C program run faster than an assembly program
if the C program uses a better algorithm. Given the same algorithm, though,
the assembly code will always run faster still (generally by 50% to 1000%).
Would you like X to run 8-10 times faster rather than 4-5? Write it in
assembly.
Personally, I feel X is too unstable to do this just yet (still too many new
versions in the works), buit ultimately, a X-terminal vendor may want to recode
X in assembly so (1) That vendor has a performance advantage over
competitors, or
(2) that vendor can use slower parts (i.e., cheaper) to acheive the same
performance as competitors for less money.
If you're happy with the performance as it is (I suspect you're not, you *did*
upgrade to the faster version, right?), stick with it. But would you turn down
code which runs 2x faster?
curts@usenet.umr.edu (Curt Schroeder) (04/25/91)
In article <9104181707.AA29942@beaver.cs.washington.edu> davewh@microsoft.UUCP writes: [lots of great stuff that I agree with deleted] >Ok, what do you all think? > >Dave Whitney Microsoft Corp, Work Group Apps dcw@goldilocks.lcs.mit.edu or I have been following this discussion for some time now. Some of the comments that have been made I agree with, some have made me angry. Dave is the first one I can truly say I agree with. Why? Because other than changing the order of a few things around, he has essentially described the curiculum that I have had! I would like to note that the curiculum here drifted away from the low- level stuff about one year behind me during my undergrad. But, the curiculum is starting to swing back to a stronger low-level understanding of computing (I would like to think that I had something to do with this, because I have supported this approach all along, but I doubt one student's voice had that much to do with it ;) ). The key to the whole discussion though is "Use the right tool for the job!" Curt Curt Schroeder | U of Missouri - Rolla | curts@ee.umr.edu | ---------------------------------------| curts@cs.umr.edu | "Oops? What do you mean, oops? I | s076895@umrvma.bitnet | distinctly heard an oops!" - Opus | -- Apple II Forever -- |
reanor@speedy.cs.pitt.edu (Jeffrey Getzin) (04/26/91)
In article <9104041653.AB15986@apple.com> JWANKERL@UTCVM.BITNET ("Josef W. Wankerl") writes: > >ACK!!!! "Easy" is a relative term. I could probably code something >much faster in C, but I could do a much better job in assembly (on the >IIGS, other architectures may vary.) Saying it's easier in C than >assembly - well - the concepts are all the same, I can implement a >linked list and queues and binary trees and all sorts of other nifty >constructs with assembly, and I have lots more flexibility with my >assembly constructs, too. ...and sometimes the easy way out isn't >always the best way. > >-- >===> Josef W. Wankerl, Technical Editor for GS+ Magazine > BITNET: JWANKERL@UTCVM.BITNET | America Online: JWankerl > ProLine: jwankerl@pro-gsplus |-------------------------------- >Internet: jwankerl@pro-gsplus.cts.com | "I am a Viking" -Y. Malmsteen I think you people have been arguing with only tiny computers (such as the Apple II's) in mind. On these machines, the limitation is in the compiler and not in the language. On a larger machine, I don't see how it's even REMOTELY possible to out-do a compiled high-level language. Compilers can do automatically what is inconceivably hard, boring, or distasteful to a programmer. For example, I recently read an article, "Program Optimization for Instruction Caches" (McFarling/Stanford University) in which compiled programs are optimized to minimize the miss rate on an instruction cache by rearranging the basic blocks. I don't know about you net-ers, but I personally would not want to do this to assembler language programs by hand. Personally, I don't know if even I COULD, and I feel that I am a more than an adequate programmer. The same argument goes for such things as register allocation (minimize memory access), redundant load/store elimination (again minimizing memory access), constant propogation (reducing number of computations performed), invariant code motion (reducing number of instructions executed), etc. All of these optimizations are very easy conceptually, but are simply beyond the boredom-thresholds of most programmers. -- --- Jeffrey Getzin saintdor@vms.cis.pitt.edu
rhyde@dimaggio.ucr.edu (randy hyde) (04/27/91)
> The key to the whole discussion though, is use the right tool for the job.
AMEN.
The problem is, most people don't know what the right tool is at some
particular time (on both sides of the argument, I might point out).
toddpw@nntp-server.caltech.edu (Todd P. Whitesel) (05/01/91)
I don't have a specific point to prove, just a comment: reanor@speedy.cs.pitt.edu (Jeffrey Getzin) writes: > All of these optimizations are very easy conceptually, but are simply >beyond the boredom-thresholds of most programmers. Maybe this is because they don't know how to write efficient code in the first place. Good assembly prorammers often write pre-optimized code where it counts, and usually the optimizations are impractical for the compiler but garner that extra size/speed edge that justified using assembly in the first place. Todd Whitesel toddpw @ tybalt.caltech.edu
rhyde@ucrmath.ucr.edu (randy hyde) (05/02/91)
re: I wouldn't want to write assembly code on a big machine.... register optimizations... cache hits... etc... Actually, anyone with about a year's experience can handle most of this with no problem. I've written assembly code on 80386, 680x0, and 32532 machines (which IMHO, are big), and I'm learning SPARC right now. It's not that big a deal to do those things you're so frightened of. I can tell you what's worse-- writing a serial driver on the 6502 using the game port on the Apple II. I've written a couple of those in my time. At one time I had all the instruction cycle timings for the 6502 instr. set memorized (it's been a while since I can remember them, though!). I consider this a greater feat than learning about cache hits and delay slots, and stuff like that. As for compilers doing better than people at code generation, I must reiterate an earlier post-- (1) This applies only if you continue thinking in C while programming in assembly. If you do not switch to the assembly language programming paradigm (which, admittedly, takes a couple of years to learn), you don't stand a chance against modern optimizing compilers (which most available today are *not*). (2) The same data flow analysis tools which optimize compilers can be applied to assembly language. You could write a tool to tell you that you could be using the register better, or that moving a few instrs. around will speed things up. This needn't be limited to HLLs. Admittedly, such tools do not exist yet, but I'm working on such items (alas, not for the 65816, DFA tools wouldn't be much help for optimization [though I have developed a DFA tools for helping show program correctness of assembly language programs on the GS]). *** Randy Hyde
psonnek@pro-mansion.cts.com (Patrick Sonnek) (05/03/91)
In-Reply-To: message from reanor@speedy.cs.pitt.edu >I think you people have been arguing with only tiny computers (such as >the Apple II's) in mind. On these machines, the limitation is in the >compiler and not in the language. > >On a larger machine, I don't see how it's even REMOTELY possible to out-do >a compiled high-level language. Compilers can do automatically what is >inconceivably hard, boring, or distasteful to a programmer. For example, >I recently read an article, "Program Optimization for Instruction Caches" >(McFarling/Stanford University) in which compiled programs are optimized >to minimize the miss rate on an instruction cache by rearranging the basic >blocks. I don't know about you net-ers, but I personally would not want >to do this to assembler language programs by hand. Personally, I don't know >if even I COULD, and I feel that I am a more than an adequate programmer. > >The same argument goes for such things as register allocation (minimize >memory access), redundant load/store elimination (again minimizing memory >access), constant propogation (reducing number of computations performed), >invariant code motion (reducing number of instructions executed), etc. All >of these optimizations are very easy conceptually, but are simply beyond the >boredom-thresholds of most programmers. Have you ever heard of macros? Most good assemblers, even Apples Pro-Dos Assembler tools supports macros. Alot of assmblers for mainframes come with a whole truck load of memory and register management macros. (As well as I/O, program initialisation, system inqiry.) Granted, the Apple does this entirely with Calls to the MLI, but those are almost as easy to use as macros. About the Redundant load/stores, I've noticed many compilers do the exact opposite, the resulting code is full of unnessesary loads/stores. in assembler you would code direct memory access, which is many times faster, providing that what it is your accessing is within your immediate memory page. ---- ProLine: psonnek@pro-mansion Sysop Pro-mansion: 507/726-6181 Internet: psonnek@pro-mansion.cts.com MCImail: psonnek UUCP: crash!pro-mansion!psonnek ARPA: crash!pro-mansion!psonnek@nosc.mil BITNET: psonnek%pro-mansion.cts.com@nosc.mil <<Real programmers don't program in HLL's.>> <<HLL's are for wimpy application coders!!>>
gwyn@smoke.brl.mil (Doug Gwyn) (05/04/91)
In article <8993@crash.cts.com> psonnek@pro-mansion.cts.com (Patrick Sonnek) writes: >Have you ever heard of macros? None of the resource allocation issues that reanor@speedy.cs.pitt.edu mentioned can be solved by using macros.
msucats@att1.Mankato.MSUS.EDU (msucats) (05/04/91)
In article <8993@crash.cts.com> psonnek@pro-mansion.cts.com (Patrick Sonnek) writes: >> [ HLLs are faster because they do optimizations that assembly >> programmers wouldn't do due to boredom ] > Have you ever heard of macros? Most good assemblers, even Apples > Pro-Dos Assembler tools supports macros. Alot of assmblers for > mainframes come with a whole truck load of memory and register > management macros. (As well as I/O, program initialisation, system > inqiry.) Granted, the Apple does this entirely with Calls to the > MLI, but those are almost as easy to use as macros. About the Once you start using macros, you're back in HLL hell. Macros hide their internal details from the programmer; this is their advantage. However, this is also their disadvantage, since the programmer's ignorance means that macros may do useless things, such as... > Redundant load/stores, Bingo. > I've noticed many compilers do the exact opposite, the resulting > code is full of unnessesary loads/stores. Get A Real Compiler. (I suppose that's hard on the 6502. I wonder if gcc could be retargetted...naw.) Seriously, this means that you need a better optimizer for your compiler, or your compiler needs to be recoded from the bottom up. > in assembler you would code direct memory access, which is many > times faster, providing that what it is your accessing is within > your immediate memory page. Huh? Immediate memory page? Page Zero? > ProLine: psonnek@pro-mansion Sysop Pro-mansion: 507/726-6181 ^^^^^^^ The reason ProLine is a work of art is that it exists at all. Of course, such artistry is not necessary on 8086 machines of similar price...where HLL's can get the job done just as quickly. :-) > Internet: psonnek@pro-mansion.cts.com MCImail: psonnek > UUCP: crash!pro-mansion!psonnek ARPA: crash!pro-mansion!psonnek@nosc.mil > BITNET: psonnek%pro-mansion.cts.com@nosc.mil ^^^^^^^^ Doesn't look like a BITNET address to me. > <<Real programmers don't program in HLL's.>> Yes. We program in C. ;-) > <<HLL's are for wimpy application coders!!>> Could you parenthesize that? Do you mean coders who write wimpy applications, application coders who are wimpy, or coders who are wimpy and write applications? Or are you trying to imply that people who write applications are wimpy coders? Jay Carlson msucats@att1.mankato.msus.edu
rhyde@ucrmath.ucr.edu (randy hyde) (05/06/91)
>>>>
Get A Real Compiler. (I suppose that's hard on the 6502. I wonder if
gcc could be retargetted...naw.) Seriously, this means that you need
a better optimizer for your compiler, or your compiler needs to be
recoded from the bottom up.
<<<<
I don't know what GCC is like on 68Ks and Sparcs, but I do know it produces
redundant loads on the 32532 version. I recently hand-compiled a GCC SCSI
driver for my PC532 using the grossest, simple-minded code I code (to avoid
possible timing problems). My code was less than 1/4 the size and about
three times faster than the GCC variety. Mainly because of those Da*n redundant
loads. GCC does some neat optimizations, but it really drops the ball in
other areas.
BTW, for anyone who is gonna start flaming me, SCSI drivers are a perfect
example of code that really *should* be written in assembly.
*** Randy Hyde