Self-modifying code
Guy Harris
guy at gorodish.Sun.COM
Thu Jul 28 16:32:59 AEST 1988
> But I have a lot of doubts about this approach. To me it's like
> observing that an earth dam has 300 holes, and proposing to fix them
> one-by-one, each hole needing some different fix from the one before.
> The whole point of capabilities (at least as the 432 implemented
> them) was to provide a seamless programming environment, with exactly
> the same abstraction (that of an "object") presented to the
> programmer, no matter in which direction she looked (left or right
> through the code, or down to the hardware).
What if they look at the microcode, or directly at the hardware (if the
underlying machine isn't implemented using microcode)? In order for the
environment to be truly airtight, the microcode (or hardware) has to be
airtight.
It may be that producing a sufficiently airtight compiler that implements the
object-oriented model by producing the "right" code, including checks, is
either impossible or more costly than producing a microcode or hardware
implementation atop a compiler that doesn't have to be so airtight because the
microcode or hardware is. If people's experience points in this direction,
fine.
However, how is this different from, say, implementing the interpreter in some
"conventional" machine language, or in some language compiled into
"conventional" machine language? If it's not different, could the interpreter
then try compiling the code to be interpreted into that machine language,
preserving the run-time checks? Could this still be sufficiently airtight? If
so, would it be faster than, say, a microcode implementation of the same
interpreter with no compilation? How about a microcode implementation that
compiles either into some faster-to-interpret code, or directly into microcode?
> Actually, I didn't say it was the only way. In fact, all I've been
> trying to argue is that there are reasons to believe that there are
> things worth considering from that kind of research and that type of
> programming environment.
I'll certainly agree with that; however...
> Sometimes I feel like all we do is debate the race cars, when it's the
> production cars that represent all the money.
I won't agree with that, because
1) I don't think that's *all* people have been doing. While there's
been relatively little discussion of it in *this* forum, I get the
impression - perhaps erroneously - that people are thinking about
how to implement the desired kind of programming environment, even
if more in the "atop a 'conventional' machine language" form than in
the "machine language that does lots of it directly" form; e.g., the
SOAR people, people doing LISP implementations on "conventional"
machines, etc..
2) I don't think the analogy is appropriate. For one thing, most
computers are - for better or worse - "conventional", so a better
analogy would be "sometimes it feels like all we do is debate the
production cars, when we should be concentrating on 'safety' cars",
e.g. cars with significantly new features to increase safety.
The second analogy raises some interesting questions:
1) How much are people willing to spend to have safer cars? Are they
willing to pay X amount of extra money for airbags? (How much of a
slowdown are people willing to accept for some amount of additional
run-time checking?)
2) How much safer does a particular feature make you? (If 99% of
the errors a particular run-time check detects can be caught at
compile-time, how much safer are you if you catch the extra 1%?)
3) How many problems does a feature have that reduce its desirability -
or even its contribution to safety? For example, if there's a risk
of airbags detonating spontaneously, what is the risk of this
happening and how bad is it if it does? (What are the chances that
the implementation of the environment, and all its checking, has
a bug in it, and how badly are you screwed if it is?)
> Absolutely. I tried to quantify the cost of 432-style object
> orientation in my thesis. In a nutshell, I concluded that that style
> of machine be from 1 to 4 times slower than a conventional
> unprotected architecture made of equivalent implementation
> technology.
Just out of curiosity:
How would this figure change with newer implementation technologies for
"conventional" machines (e.g. more powerful optimizers, different
architectural style (for which you may read "the stuff that RISC implementors
talk about a lot"), etc.?
How would it change with newer implementations for protected architectures
(including some of the same newer technologies mentioned for "conventional"
machines, and also techniques such as compiling "protected architecture" code
into "conventional" code, or doing "quick" checks in hardware and trapping to
software checking code if they fail)? (For all I know, some of these may not
be "newer" techniques; if so, how did that change the relative performance?)
How easy is it to apply some of those techniques to instruction-set
architectures such as the 432's, as opposed to applying them to, say, RISC
architectures and using other techniques to implement a "protected" system atop
such a "conventional" architecture?
> You could do their transparent multiprocessing and buy that factor of
> 4 back, but if you got above 6 or 7 you'd saturate the bus
> (memory-to-memory architecture). Things get hard to sort out after
> that.
Yes, but could you buy an equivalent amount back with multiprocessing on
"conventional" architectures with the protection implemented elsewhere than in
the instruction set, even if the multiprocessing might be less transparent?
Could it be a greater amount if the "conventional" architecture were not so
memory-reference-intensive?
Could you change the "protected" system to make *it* less memory-intensive and
improve *its* multiprocessor performance? (At this point, one would no longer
expect eyebrows to raise at the appearance of a new register-oriented
machine.... :-))
> Is that performance hit worth it? Who knows? I'd say it's probably
> worth it a lot more often than most people currently think. An awful
> lot of code got written and debugged on machines that were a lot slower
> than the could-have-been 432. You have to allow for a natural
> tendency (which I think largely fuels this whole industry) to always
> want more and to refuse to ever go backwards in anything, speed,
> memory, disk, sw complexity...
Yes, but there may be an economic justification for that tendency; the issues
may not all be "technical" in the narrow sense. It may be hard, as you pointed
out, to show improvements in programmer productivity, code reliability, etc.
in a better programming environment, but if the advocates of such environments
want people to spend money on those sorts of improvements rather than straight
performance improvements, they should expect those who would pay the bills to
be more swayed by that kind of evidence.
(Another problem is that it may not even be cost-effective to adopt a
technology that's clearly "better", technically; I suspect a new motor fuel
would have to be quite a bit better before people were willing to write off the
existing investment in the production and distribution of existing fuels.
There are a lot of "conventional" machines out there.)
> Yeah, well, the Space Shuttle doesn't exactly have blazing hardware.
> But it's running some of the most sophisticated software I
> know of. And telephone switchers aren't mini-crays by any means.
Yeah, well, I don't know that either of those processors would necessarily have
the requisite horsepower for some of the embedded applications somebody might
want to put computers into in the future. That's why I said "as the jobs they
do get more sophisticated, the minimum performance required increases;" a 4x
performance hit relative to "conventional" computers may rule out a "protected"
processor for some application until you can either come up with a way of
solving the problem faster with existing hardware or make the hardware faster.
I'm certainly willing to believe that there are applications now that could use
a "protected" processor, but I'm not sure I'm willing to believe that there
aren't applications that, at present, couldn't use a "protected" processor if
it were 4x slower than a "conventional" one. In this case, a useful question
to ask might be "can I get the same level of protection with an adequate level
of performance if I don't put all the protection in the instruction set?"
(BTW, I infer from the paper "Engineering a RISC Compiler System", by some
people at MIPS, that their compiler can optimize register usage across
procedure boundaries even when the calling and called procedures were
separately compiled - they keep Ucode around for multiple compilation units, so
that information for both calling and called procedure is available to the
optimizer - so the claim made in "Fast Object-Oriented Procedure Calls:
Lessons from the Intel 432" that "Clearly, the same approach (interprocedural
register allocation) is inapplicable to separately compiled modules." is
false. It may be true in some cases - for example, if the modules are bound
together at run time - but it is hardly clear that it is always true. I
believe David Wall has worked on link-time register allocation as well.)
More information about the Comp.lang.c
mailing list