jlg@lambda.UUCP (Jim Giles) (02/06/90)
From article <PCG.90Feb5163252@rupert.cs.aber.ac.uk>, by pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi): > [... 'register' is only a 'noalias' substitute - I said ...] > > Well, there is also actually a strong *hint* that the variable will > be heavily *dynamically* used across statement boundaries, in the > current scope. The compiler can use this hint very effectively. Such a hint is only useful to an exceptionally dumb compiler. Most modern compilers do better data flow analysis than human programmers are willing to do. Studies have shown that compilers can consistently do a _very_ good job of register allocation without such hints. In fact, most C compilers simply ignore the 'register' attribute except to verify that the variable is never used with an 'address-of' (&) operator. In the overwhelming majority of programming environments, the only way to beat the compiler's code is to switch to assembly. The use of 'register' or other such tricks is insignificant (sometimes even damaging). > [...] > A careful programmer will never declare a variable for a scope larger > than that in which it is used, [...] I disagree. A careful programmer will neither write extremely monolithic code, nor write code which is fragmented into lots of little scopes. If I have a 50 line function which uses XYZ in only the middle third, I'm not likekly to make a new scope just for XYZ. I _may_ split out the middle third _if_ it seems to be a distinct and nearly independent segment (but, then I would ask myself whether the code should actually all be in the same function at all). > [...] will never reuse a variable with the same > name for two different roles. Now, I agree with that. However, I make one caveat: in most languages including C, the idiom for the use of index variables in loops is single letter variables. Such variables are often used in separate loops (with non-overlapping scopes of course) without any sign of confusion that I've ever noticed. Of course, you _could_ argue that the variable _isn't_ being used in separate roles - it's always an index variable. It is interesting that you consider using the same name for two different things to be very evil and yet you consider having two names for a single object (aliasing) to be acceptable. For most people, the degree of evil is the other way 'round. > [...] > Of course this is because I am eccentric enough to think > that the performance characterization of a program is > part of its design and pragmatics should be as obvious > as semantics. One should only degrade the readibility of code with performance enhancing transformations when absolutely necessary: that is, when the performance of the code would otherwise be unsatisfactory. This usually applies only to a very small part of the code for any given project. Most of the code is under another sort of optimization pressure altogether: the pressure to work correctly, to get written quickly, to be maintainable, to be easy to enhance when new demands are made on the program, etc.. Even the code that needs to work _FAST_ should first be written as clearly as possible and only _then_ optimized. > [... Other languages don't usually _need_ 'register' ...] > Let me differ. Fortran has had equivalence and common forever, > and even if dirty tricks are prohibited in theory, most compilers > cannot assume users are well behaved [...] There is a difference between aliasing and storage association. Common blocks can cause storage association between different objects - but _NOT_ within the same scope. The only type of aliasing possible with common is passing common variables through the argument list. But this is illegal! And most compilers _DO_ assume that such aliasing has not occurred. As for equivalence: that is a _LOCAL_ declaration. The compiler can clearly see what variables are aliased and what variables aren't. There is no need for a 'register' attribute to declare this information, the compiler is already explicitly aware of it. Fortran 90, on the other hand, has introduced pointers which can point to other (non-dynamic) objects. In this language, something analogous to the 'register' attribute is needed. The method chosen by the committee was symmetric to the C solution: Fortran 90 has the POINTEE attribute, which tells the compiler that an object _may_ be aliased. This means that the default attribute of most Fortran 90 objects is effectively 'register'. > [...] Pascal has 'var' parameters, Yes, but Pascal is not separately compilable. The compiler can do a complete interprocedural dataflow analysis to find out _unambiguously_ what arguments might be aliased with what global variables. > [...] and, more murkly, variant > records without discriminant. C _also_ has variant records without discriminants! They're called unions. The kinds of problems caused by such things are usually type-coercion problems and have nothing to do with 'register' attributes or aliasing in the hidden sense. After all, the declaration of such a union is clearly visable in any scope that can reference any field in it - so the compiler can already determine that overlapping fields _might_ be aliased (just like Fortran's EQUIVALENCE in fact). > [...] > the absence of presence of 'noalias' (and 'volatile') does change the > semantics of a program, while for 'register' this is not true; [...] This is false. The 'register' attribute should have no effect on the _semantics_ of a correct program. If you don't use the address-of (&) operator on a variable, the presence or absence of 'register' on that variable should have NO effect on the semantics of the code. If it does, I suspect that you have a broken compiler! > [...] 'register' > also gives a *positive* hint on usage frequency. Yes, one that is practically useless on a good compiler. In fact, if the compiler makes an effort to put your 'register' vars into registers, it may actually _inhibit_ optimal register utilization. The fact of the matter is, usage frequency is one of the things I expect the language environment to tell ME, not the other way around. The compiler and the run-time profiler are where that information comes from - not from my gut feeling. Now, if the profiler could feedback information into the compiler for a subsequent compile, THAT might be a useful feature. > [...] > With 'register' safety (no aliasing) is a side effect, but a > clever one, under more than one aspect. Actually, no aliasing is about the _only_ useful feature of the 'register' attribute. And it is one that is basically unneeded in other languages. Even so, it's not all that useful - unless you like to explicitly copy-in copy-out all your global variables that you wish to use. And it doesn't help with array manipulation at all (which are still pointers and are assumed aliased to everything that's not 'register'). > [...] > What ruins the alias show for most languages is either separate compilation > or parameter passing, even where pointers are not present. It's not either-or. The problem arises only with _both_ parameter passing and separate compilation. Without separate compilation, the compiler can look at the whole call tree to detect any possible aliasing. Without call by reference there is no problem (and this is the only parameter passing mechanism which causes the problem). Even so, a run-time test for aliasing would be cheap and easy to implement, but the current lack of interest indicates to me that there really isn't much of a problem. Compilers _DO_ optimize as if such aliasing has not taken place and they _DON'T_ usually test for aliasing - yet the frequency of such errors is very small. > [...] And even if > this not true, the compiler still has to guess which of the safe variables > are actually worth caching. But, this is something that the compiler is usually _very_ good at. Better than most people have time to be. (And, if you _do_ have time, you're better off going to assembly where your register declarations aren't hints but _orders!) > [...] > Naturally this is a moot point on many of today's architectures, > where register optimization is entirely unnecessary, as there usually > far more registers available than variables [...] Additional registers aren't a panacea. For one thing, as the number of registers increase, the register allocation schemes have gone 'cosmopolitan'. There is an increasing effort to keep data in registers across procedure calls. The less efficiently codes use the registers, the less efficiently the code runs - even if there are a massive number of registers. For another thing, register utilization is not the only thing inhibited by aliasing! All those multi-register machines you're talking about are also likely to be pipelined. Pipelining is inhibited by possible aliasing as bad (or worse) than register utilization. And there's NO source level control (in C or anywhere else) over code ordering optimizations on the pipelining level. The best thing is for the language to be designed in such a way that aliasing is difficult and rare and is only forced upon the user when it is actually part of the functionality he needs. J. Giles
mjs@hpfcso.HP.COM (Marc Sabatella) (02/07/90)
>> Well, there is also actually a strong *hint* that the variable will >> be heavily *dynamically* used across statement boundaries, in the >> current scope. The compiler can use this hint very effectively. > >Such a hint is only useful to an exceptionally dumb compiler. Most >modern compilers do better data flow analysis than human programmers >are willing to do. Studies have shown that compilers can consistently >do a _very_ good job of register allocation without such hints. In fact, >most C compilers simply ignore the 'register' attribute except to verify >that the variable is never used with an 'address-of' (&) operator. Throw in profiling, and you've got a deal. But very few compilers actually take profiling data into account, and if you've written a routine which takes a parameter 'n' that gives the iteration count for the loop, no amount of static data flow analysis (even interprocedural, in many cases) is going to tell you the dynamics of that loop. Now say you have another loop, with a fixed count of "10". Which should the optimizer think is going to be more heavily executed? A careful programmer can hint to the optimizer with 'register' which variables he thinks are more important, which may be all the hint the compiler needs. And often it doesn't take a lot of work to do this, so you are not "better off using assembly langauge". There is also portability to consider. Now I agree that often, the 'register' attribute is misued by programmers. So I would suggest a compiler pragma which says something to the effect of "take my register declarations seriously", and ignorigin them (as usual) by default. >Yes, but Pascal is not separately compilable. The compiler can do a complete >interprocedural dataflow analysis to find out _unambiguously_ what arguments >might be aliased with what global variables. (scoff...)
preston@titan.rice.edu (Preston Briggs) (02/07/90)
In article <8960010@hpfcso.HP.COM> mjs@hpfcso.HP.COM (Marc Sabatella) writes: (in response to a posting by J. Giles) >>Yes, but Pascal is not separately compilable. The compiler can do a complete >>interprocedural dataflow analysis to find out _unambiguously_ what arguments >>might be aliased with what global variables. >(scoff...) You doubt? People *have* built interprocedural flow analysers for Pascal compilers. People have even done it for Fortran, complete with separate compilation. Even commercial people (as opposed to research). Other people even use such compilers. Preston Briggs preston@titan.rice.edu
mjs@hpfcso.HP.COM (Marc Sabatella) (02/07/90)
>People *have* built interprocedural flow analysers for Pascal compilers. >People have even done it for Fortran, complete with separate compilation. >Even commercial people (as opposed to research). >Other people even use such compilers. Saying that there exist such compilers (and we all know many implementations of Pascal *do* support separate compilation) is not the same as saying it is "not a problem for Pascal".
jlg@lambda.UUCP (Jim Giles) (02/08/90)
From article <8960010@hpfcso.HP.COM>, by mjs@hpfcso.HP.COM (Marc Sabatella): > [...] and if you've written a routine which takes > a parameter 'n' that gives the iteration count for the loop, no amount of > static data flow analysis (even interprocedural, in many cases) is going to > tell you the dynamics of that loop. Agreed. So, in lieu of complete information, you optimize the code as if 'n' were large. If 'n' really _is_ large, you have a winning solution. If 'n' is not large, you don't suffer much - the code isn't executed much in this case. Of course, the more that is known about 'n' the better you can optimize the loop. If 'n' is known to be small, you might _completely_ unroll the loop or perform some other modification. But, a better hint to the compiler in this case is _not_ to use 'register' attributes. Instead, the language sould provide some mechanism for making (checkable) assertions. For example: Assert(n>0 and n<=15) The generated code can then test the assertion at run-time and the compiler can generate the rest of the code efficiently based on the assertion. Of course, you might want a compiler option to turn off the run-time checking of assertions. Furthermore, this is _much_ more refined and clean than the methods recommended by Peter Grandi for documenting the assumptions of the programmer. Every time a language standard comes up for review, some recommendation like the above 'Assert' feature is brought up (it happened for both C and Fortran in the last few years). I don't know what arguments have resulted in leaving such features out. The state-of-the-art of compilers is gradually reaching the point where such assertions can be used very well indeed. Oh well.... > [...] Now say you have another loop, with a > fixed count of "10". Which should the optimizer think is going to be more > heavily executed? I don't see your point. If the loops are disjoint, the registers used by the first are free by the start of the second. If the loops are nested, the inner-most loop should be optimized regardless of any 'register' declarations. Since these are the only two possibilities, I don't see how the lack of information about 'n' can negatively effect the loop with constant trip-count at all. J. Giles
meissner@osf.org (Michael Meissner) (02/10/90)
In article <8960010@hpfcso.HP.COM> mjs@hpfcso.HP.COM (Marc Sabatella) writes: | >> Well, there is also actually a strong *hint* that the variable will | >> be heavily *dynamically* used across statement boundaries, in the | >> current scope. The compiler can use this hint very effectively. | > | >Such a hint is only useful to an exceptionally dumb compiler. Most | >modern compilers do better data flow analysis than human programmers | >are willing to do. Studies have shown that compilers can consistently | >do a _very_ good job of register allocation without such hints. In fact, | >most C compilers simply ignore the 'register' attribute except to verify | >that the variable is never used with an 'address-of' (&) operator. | | Throw in profiling, and you've got a deal. But very few compilers actually | take profiling data into account, and if you've written a routine which takes | a parameter 'n' that gives the iteration count for the loop, no amount of | static data flow analysis (even interprocedural, in many cases) is going to | tell you the dynamics of that loop. Now say you have another loop, with a | fixed count of "10". Which should the optimizer think is going to be more | heavily executed? A careful programmer can hint to the optimizer with | 'register' which variables he thinks are more important, which may be all the | hint the compiler needs. And often it doesn't take a lot of work to do this, | so you are not "better off using assembly langauge". There is also | portability to consider. The MIPS compilers seem to have the ability to use profiling data when doing full blow optimization. Here are some sections from the online manual (from a Dec Pmin system): Cc(1) man page section: -O3 Perform all optimizations, including global register allocation. This option must pre- cede all source file arguments. With this option, a ucode object file is created for each C source file and left in a .u file. The newly created ucode object files, the ucode object files specified on the command line, the runtime startup routine, and all the runtime libraries are ucode linked. Optimization is performed on the resulting ucode linked file and then it is linked as normal producing an a.out file. A resulting .o file is not left from the ucode linked result. In fact -c cannot be specified with -O3. -feedback file Use with the -cord option to specify the feedback file. This file is produced by prof(1) with its -feedback option from an execution of the program produced by pixie(1). -cord Run the procedure-rearranger on the resulting file after linking. The rearrangement is performed to reduce the cache conflicts of the program's text. The output is left in the file specified by the -o output option or a.out by default. At least one -feedback file must be specified. Prof(1) man page section: -feedback filename Produces a file with information that the compiler system can use to decide what parts of the program will benefit most from global optimization and what parts will benefit most from in-line pro- cedure substitution (requires basic-block count- ing). See cc(1). -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA Catproof is an oxymoron, Childproof is nearly so
pcg@aber-cs.UUCP (Piercarlo Grandi) (02/10/90)
In article <14226@lambda.UUCP> jlg@lambda.UUCP (Jim Giles) writes:
[ an argumetn based on the assumption that commonly available
compilers are very good at discoverin which variables
are frequently used, and similar interesting things ]
UNFORTUNATELY, this assumption is unproven. Commonly available
compilers are not able to do this. What happens is that
virtually every compiler out there optimizes based on *static*
frequency of usage, and even this is irrelevant on many modern
machines that have more registers than most programs can use.
Compilers that can do a good job should either use heuristics,
or profile feedback, and are exceedingly rare. In both cases
the compiler becomes more complex (becomes it has to analyze
control and data flows as a preliminary -- it is this that makes
the compiler more complex, not the optimization per se). I think
that the programmer, *by design* (aided by heuristics and
profiling, yes) should know what is going on, and tell the
compiler instead.
In any case, whether compilers can or could do this analysis is
a different issue from whether the programmer *should* document
the performance assumptions made in a piece of program, and
whether the compiler should ignore this.
I reckon the programmer should, because I reckon that programs
ought to be as precise descriptions as possible, both as to
semantics and as to pragmatics.
The issue is then whether the reader of a program be it either
human or program should not be required to second guess the
author.
Once this is demonstrated undesirable, the issue of whether
compilers should do this, taking into account the extra
complexity and ensuing unreliability of getting a much more
sophisticated compiler, and the effectiveness of doing so.
Any technology should be examined as to it cost, not just as to
its benefit. Are aggressive optimizers so effective that the
added cost in compiler complexity and reliability, in encouraging
more sloppily written programs, in resource usage, is worth it?
A completely seaprate issue is instead that of having a
'programmer assistant' that aids the programmer with writing
source code, e.g. in doing program transformations; as to this
I am in favour, as long as this is not made part of a code
generator.
--
Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
cks@white.toronto.edu (Chris Siebenmann) (02/13/90)
pcg@cs.aber.ac.uk (Piercarlo Grandi) writes: | Compilers that can do a good job should either use heuristics, or | profile feedback, and are exceedingly rare. In both cases the | compiler becomes more complex (becomes it has to analyze control and | data flows as a preliminary -- it is this that makes the compiler | more complex, not the optimization per se). Profiling feedback compilers are becoming more and more common and at least one set are fairly widely used: the MIPSco compilers. As people start reading various technical reports about the gains possible and become more aware of the usefulness of this sort of thing. | I think that the programmer, *by design* (aided by heuristics and | profiling, yes) should know what is going on, and tell the compiler | instead. I agree that programmers should have some way of manually telling the compiler about usage frequency. However, given that we're already assuming a profiler at work, and the usual quality of commercial programmers, I think it's foolish not to let the compiler/linker read the profiling results directly. When something is simple and mechanical, why not let the computer do the drudge work? I wonder how many programmers even bother running a profiler on their programs? I suspect not many. -- "I shall clasp my hands together and bow to the corners of the world." Number Ten Ox, "Bridge of Birds" cks@white.toronto.edu ...!{utgpu,utzoo,watmath}!utcsri!white!cks
pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) (02/14/90)
In article <1990Feb12.172948.17784@jarvis.csri.toronto.edu> cks@white.toronto.edu (Chris Siebenmann) writes:
Profiling feedback compilers are becoming more and more common and at
least one set are fairly widely used: the MIPSco compilers.
Sure the MIPSco people would love their compilers to be widely used...
Sure DEC is contributing powerfully... :-) :-).
I agree that programmers should have some way of manually telling the
compiler about usage frequency.
Definitely yes! Even if the compiler uses heuristics or profiling,
the programmer may still know better in certain cases.
However, given that we're already assuming a profiler at work, and
the usual quality of commercial programmers, I think it's foolish
not to let the compiler/linker read the profiling results directly.
When something is simple and mechanical, why not let the computer
do the drudge work?
I tend to agree in principle. In practice, things are less clear
cut. To make use of profling and heuristic information, the
compiler has to run complex analysis and optimizing modules. This
is *bad*. The beauty of things like 'register' is that they are
absolutely safe and effective, without any analysis whatsoever.
I wonder how many programmers even bother running a profiler on their
programs? I suspect not many.
Very few. Actally, in most cases, profiling requires recompilation,
and this is often not very attractive, and in any case very few
programmers would understand the profile.
I think that rather than sticking complex, often unreliable and
ineffective optimizers in the bowels of code generators, the
following topics should be explored:
1) ways to make languages safer without requiring complex analysis;
2) ways to describe the semantics and pragmatics of a program, both
to human and programmatic readers;
3) ways to make it easier to profile for time, e.g. for a coarse first
run use statistical PC sampling, without recompilation, and then
using flow graph based tecniques;
4) ways to make it possible to profile for space, e.g. for a coarse first
run use statistical page reference sampling, without recompilation, then
using flow graph based techniques, e.g. in malloc() or equivalents;
5) programmer's assistants that do a thorough analysis of the source code;
6) programmer's assistants that help make transformations of the source code;
7) training better programmers (oh well, let's dream...).
I am aware of some work in the literature about these points
(Alpeh, Euclid, lint, ....), but it is pitifully small compared
to the vast effort expended on what by comparison is an unsafe,
inefficient shortcut, "optimizers", not to mention recent
standard efforts that have worsened problems (volatile!).
If you look at things cynically, "optimizers" are a shortcut most
effective only on benchmarks, and these sell machines...
--
Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
jlg@lambda.UUCP (Jim Giles) (02/14/90)
From article <PCG.90Feb13161349@rupert.cs.aber.ac.uk>, by pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi): > [...] > to the vast effort expended on what by comparison is an unsafe, > inefficient shortcut, "optimizers", [...] You keep saying that. However, you have yet to prove (or even make a good case) that optimizers are either unsafe or inefficient. To be sure, I have no absolute objection to 'hints' that help the compiler do a better job. BUT - the compiler should be expected to do a reasonably good job in the absence of such 'hints'. Furthermore, a compiler with a good optimizer should be expected to do _better_ than a simple compiler even on the 'hint' filled code! After all, the _PURPOSE_ of a compiler is to translate from source code to semantically equivalent machine code. Unfortunately, there are an infinite number of semantically equivalent translations!!! Optimization is a word for several compiler techniques of selecting one of these translations which is - at least - reasonably efficient. In fact, in order to use the _programmer's_ time most effectively, the compiler writer should get the compiler to produce the most efficient code he can. (By the way, I DO have an objection to the 'uglifying hints' that C makes available. It seems to me that conveying such information to the compiler shouldn't require destroying the natural flow of the source code.) J. Giles
steve@cs.su.oz (Stephen Russell) (02/15/90)
In article <PCG.90Feb13161349@rupert.cs.aber.ac.uk> pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) writes: >I tend to agree in principle. In practice, things are less clear >cut. [...] The beauty of things like 'register' is that they are >absolutely safe and effective, without any analysis whatsoever. >I think that rather than sticking complex, often unreliable and >ineffective optimizers in the bowels of code generators, ... Complex, probably, though this depends on the target architecture and the ambition of the compiler writers. Simple optimisers can be very effective (eg, Powell's Modula-2 compiler's register allocation strategy). Unreliable, sometimes. Ineffective, depends. There have been some very effective optimisers around (eg, Bliss, DEC M2, MIPSCo). A typical optimiser does much more than just register allocation. It may even be essential when there is a mismatch between the source and target architectures. The match for C and the PDP-11 was very good, but this doesn't guarantee that C will match all other architectures as well. Without a good optimiser, improving the match may require lots of hand rewriting when code is ported. A well-written code generator will do most of this rewriting automatically, and perform optimisations that cannot be expressed (or only in an ugly manner) in the source language. >... the following topics should be explored: [list of topics deleted, except for ...] >5) programmer's assistants that do a thorough analysis of the source code; >6) programmer's assistants that help make transformations of the source code; What would you call an effective "programmer's assistant" that does a thorough analysis of code (the level is mostly irrelevant) and makes optimising (you don't want _worse_ code, right?) transformations? I'd call it an optimiser. >I am aware of some work in the literature about these points >(Alpeh, Euclid, lint, ....), but it is pitifully small compared >to the vast effort expended on what by comparison is an unsafe, >inefficient shortcut, "optimizers" I don't see how arguing in favour of safer HLL's is an argument against aggressive code generators. In fact, I would have thought that further movement away from programming the bare metal increases the need for better optimisers to bridge the gap, particularly when RISC architectures are also increasing the gap.
cks@white.toronto.edu (Chris Siebenmann) (02/20/90)
pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) writes: [I wrote] | Profiling feedback compilers are becoming more and more common and at | least one set are fairly widely used: the MIPSco compilers. | | Sure the MIPSco people would love their compilers to be widely used... | Sure DEC is contributing powerfully... :-) :-). Well, MIPSco-based machines seem to be the dominant thing to buy here. I hope vendors will be paying attention to the quality of the MIPSco compilers and implementing similar features. Maybe one of the 88K vendors will even stick this into gcc and feed the changes back to the FSF. | When something is simple and mechanical, why not let the computer | do the drudge work? | | I tend to agree in principle. In practice, things are less clear | cut. To make use of profling and heuristic information, the | compiler has to run complex analysis and optimizing modules. This | is *bad*. The beauty of things like 'register' is that they are | absolutely safe and effective, without any analysis whatsoever. If the compiler makes use of usage hints at all, I suspect that getting it to take them from a profile file instead of from the source code is fairly easy. A sophisticated compiler will want to anyways, because its using more fine-grained granularity than a function anyways. One danger of having only programmer-level hints is that quite a few programmers will add wrong hints, or change their programs such that hints become incorrect. The only way to make sure that the hints are correct is to make their gathering and use automatic or nearly so. -- "I shall clasp my hands together and bow to the corners of the world." Number Ten Ox, "Bridge of Birds" cks@white.toronto.edu ...!{utgpu,utzoo,watmath}!utcsri!white!cks
dhinds@portia.Stanford.EDU (David Hinds) (02/20/90)
In article <1990Feb19.155810.29127@jarvis.csri.toronto.edu>, cks@white.toronto.edu (Chris Siebenmann) writes: > > | When something is simple and mechanical, why not let the computer > | do the drudge work? > | > | I tend to agree in principle. In practice, things are less clear > | cut. To make use of profling and heuristic information, the > | compiler has to run complex analysis and optimizing modules. This > | is *bad*. The beauty of things like 'register' is that they are > | absolutely safe and effective, without any analysis whatsoever. > > One danger of having only programmer-level hints is that quite a few > programmers will add wrong hints, or change their programs such that > hints become incorrect. The only way to make sure that the hints are > correct is to make their gathering and use automatic or nearly so. Not to mention that programmers are not omniscient, and a good programmer's best hints aren't enough. FORTRAN may not be a fashionable language among computer scientists, but twenty years of improvement has yielded highly optimizing mainframe compilers that generally can't be beat by hand-coded assembly language. And on unusual architectures, it is often a nightmare for a programmer to figure out an efficient use of the machine's resources. For example, on a Cray, FORTRAN is presently the only way to make efficient use of the machine's resources. Cray Unix may be "hot" now, but C brings the machines to their knees. -David Hinds dhinds@popserver.stanford.edu
sommar@enea.se (Erland Sommarskog) (02/25/90)
Piercarlo Grandi (pcg@cs.aber.ac.uk) writes: >Any technology should be examined as to it cost, not just as to >its benefit. Are aggressive optimizers so effective that the >added cost in compiler complexity and reliability, in encouraging >more sloppily written programs, in resource usage, is worth it? It is maybe totally irrelevant, but I cannot fail to notice that Piercarlo Grandi is posting from an academic site. In real life, it is in many cases not a question on whether to write as fast code as possible, but to write code as fast as possible. There are delivery deadlines to keep. And very seldom can you advocate from an economic point of view to polish every part of a big program. Let a good optimizer take care of the main bulk, and then put the efforts where the bottlenecks are. (*) Also, you shouldn't spend the time on the wrong issues. With the application I currently work, optimization of the Pascal code probably has little significance since this is a database application where the I/O is the critical part. >The issue is then whether the reader of a program be it either >human or program should not be required to second guess the >author. If you write a program to help the compiler to produce good code, you very often run the risk of having another human reader to second-guess (whatever that means) what you originally meant. (*) And when you look at those bottlenecks, what you have to do is often not to help the compiler, but improve the algorithm. I had a program which the profiler told me I spend a good deal of the time inserting elements in linked lists. So what did I do? Did I rewrite the linked-list package? No, I changed the way of working with the lists to keep them down in size. (They were sorted.) When I was ready with it the insertion routine was below 1% of the executed time. -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se