[net.micro.amiga] C Philosophy

dillon@PAVEPAWS.BERKELEY.EDU (Matt Dillon) (06/16/86)

>George Robbins:
>
>	The Berkeley in you is showing.  If you have a machine that has
>a 16 bit processor, runs faster with 16 bit operands and generates
>smaller code, it is just plain lazy to say 'looks like 32 bits to me'.
>
>	As you pointed out, assuming that pointers and integers are
>the same length cause no end of portability problems.  The people who
>decided that an int on a VAX should be 32 bits did the micro-world a
>big disfavor, and the doubled it with a 'nothing smaller than a VAX
>is worth worrying about...' attitude.
>
>	Call a pointer a pointer, and an integer an integer (oops,
>I mean a short)...

	No, the practicality in me is showing.  I don't have a machine that
has a 16 bit processor (IBM's don't count; all of INTEL's processors are
screwed up anyway).  I consider the VAX and 68000 to be 32 bit machines, even
though they have 16-bit external data paths.  The registers are 32 bit.
With a good compiler, you don't really need to worry about the longer 
access time for long words over words.. it's trivial compared to
other possible improvments in code generation.  Additionaly, when 32 bit 
things are in 32 bit registers, the generated code is not any slower.  The
only real loose with 32 bit integers is with multiplication.

	Some people are paranoid about all of this, and NEVER use 'ints'...
They use either shorts or longs (which have definate minimum bit lengths).

	There are many cases where I have two int's and want to multiply them
together.  With a 16 bit compiler, I must force these int's to long's before
multiplying or my result will be truncated to 16 bits.... makes for messy
code.  One can say that I'm lazy in the fact that I do not want to deal with
or worry about having to cast my integers to longs (or vise versa).  This
whole deal about pointers is actually quite trivial compared to other reasons.
For instance, the 16 bit compiler people have to cast some passed values to 
long for function calls such as Seek(), or extern more than a reasonable
number of functions which return 'longs'.  32767 is simply not a large 
enough number for me to use as a default.

	there is a question of technology.   Do you really think
techonology is going to stick to 16 bit processors?  It's obvious to me, at
least, that it isn't.  My opinion is that today's 32 bit processors will 
become the 'standard' until the next big leap occurs some decades in the
future.  You can then ask 'what will happen to the 16 bit processors' or
'why do 8 bit processors still exist'.  The answer to that is simple.

	Take a look at your microwave.  Yup, you got it.  The small-control
-systems side of science is inheritting the 8/16 bit processor.  The handset
on your mobile telephone probably has a one chip 8 bit processor in it.
Your car's ignition system, your telephone, modem, 10 function clock-radio.
these are all items where the 8 bit processor fits the industry's needs to a
T.  There is no need for incredible speed, or major calculations, but there
is a need to conserve space and power.

	The reason I don't care to make my software (immediately) transportable
to these other processors is simply that my software wouldn't apply to these
other processors.  In fact, anything anybody writes for the latter would be
completely custom and non-portable anyway, would it not?

						-Matt

nick@hp-sdd.UUCP (Nick Flor) (06/17/86)

In article <8606161842.AA20107@pavepaws> dillon@PAVEPAWS.BERKELEY.EDU (Matt Dillon) writes:
>
>>George Robbins:
>>
>>	The Berkeley in you is showing.  If you have a machine that has
>>a 16 bit processor, runs faster with 16 bit operands and generates
>>smaller code, it is just plain lazy to say 'looks like 32 bits to me'.
>>
>>	As you pointed out, assuming that pointers and integers are
>>the same length cause no end of portability problems.  The people who
>>decided that an int on a VAX should be 32 bits did the micro-world a
>>big disfavor, and the doubled it with a 'nothing smaller than a VAX
>>is worth worrying about...' attitude.
>>
>>	Call a pointer a pointer, and an integer an integer (oops,
>>I mean a short)...
>
>	No, the practicality in me is showing.  I don't have a machine that
>has a 16 bit processor (IBM's don't count; all of INTEL's processors are
>screwed up anyway).  I consider the VAX and 68000 to be 32 bit machines, even
>though they have 16-bit external data paths.  The registers are 32 bit.
>With a good compiler, you don't really need to worry about the longer 

It is plainly stated in the C Reference manual the the type 'int' should 
reflect the most natural size for a particular machine.  The only thing 
you can depend on is that a 'short' is no longer than a 'long'.  The
people who called an int on the VAX 32-bits were only following what
Kern and Ritch stated on page 34.  

However, assuming pointers are the same size as ints, is bad programming
practice, pure and simple.  But hey, if Matt is the *only one* supporting
his programs, who gives a shit about good programming practice.  If it
speeds up his productivity more power to him.  ('sides, everyone knows
that the only good programmers to come out of the UC system come from
UCSD :-) :-) :-)

Nick

----------

"Atomic Energy, accept no substitutes!!!"

jdg@elmgate.UUCP (Jeff Gortatowsky) (06/20/86)

In article <8606161842.AA20107@pavepaws>, dillon@PAVEPAWS.BERKELEY.EDU (Matt Dillon) writes:
> 
> >George Robbins:
> >
> >	The Berkeley in you is showing.  If you have a machine that has
> >a 16 bit processor, runs faster with 16 bit operands and generates
> >smaller code, it is just plain lazy to say 'looks like 32 bits to me'.
> >
> >	As you pointed out, assuming that pointers and integers are
> >the same length cause no end of portability problems.  The people who
> >decided that an int on a VAX should be 32 bits did the micro-world a
> >big disfavor, and the doubled it with a 'nothing smaller than a VAX
> >is worth worrying about...' attitude.
> >
> >	Call a pointer a pointer, and an integer an integer (oops,
> >I mean a short)...
> 
> 	No, the practicality in me is showing.  I don't have a machine that
> has a 16 bit processor (IBM's don't count; all of INTEL's processors are
> screwed up anyway).  I consider the VAX and 68000 to be 32 bit machines, even
> though they have 16-bit external data paths.  The registers are 32 bit.
> With a good compiler, you don't really need to worry about the longer 
> access time for long words over words.. it's trivial compared to
> other possible improvments in code generation.  Additionaly, when 32 bit 
> things are in 32 bit registers, the generated code is not any slower.  The
> only real loose with 32 bit integers is with multiplication.

Wrong.  Sorry but this is not the case.  The 68000 inside your Amiga is
a 16 bit processor that just happens to have 32 bit registers and a 32
bit register-to-register data path.  I call your attention to Tables
starting on page 187 of the MC68000 Programmer's Reference Manual, 4th edition
(C) 1984 Motorola Inc.  These tables clearly show that almost all
instuctions pay a penalty for using a long.  Since I've seen the code
generated by the Lattice compiler (32bit ints), you ARE paying the price.
And it's is NOT insignificant!  Not in the context of a compiler that
produces mediocre code in the first place. You need to help it along all
you can. Are you using Greenhills on a SUN? Manx? Lattice?
Of course if your using assembler for many functions.....

> 
> 	Some people are paranoid about all of this, and NEVER use 'ints'...
> They use either shorts or longs (which have definate minimum bit lengths).

I'm not paranoid about ints at all.  I just beleive in using the right
data type for the job. No more, no less.   Further, using explict shorts
and longs tell OTHER programmers EXACTY what I intend the range of values
that variable might take on.  In most cases Shorts and Longs get the point
across clearly (MegaMax being an unfortunate exception).

> 
> 	There are many cases where I have two int's and want to multiply them
> together.  With a 16 bit compiler, I must force these int's to long's before
> multiplying or my result will be truncated to 16 bits.... makes for messy
> code.  One can say that I'm lazy in the fact that I do not want to deal with
> or worry about having to cast my integers to longs (or vise versa).  This
> whole deal about pointers is actually quite trivial compared to other reasons.
> For instance, the 16 bit compiler people have to cast some passed values to 
> long for function calls such as Seek(), or extern more than a reasonable
> number of functions which return 'longs'.  32767 is simply not a large 
> enough number for me to use as a default.

Then use longs in the first place and be done with it!  Again choose the
right data type for the job at hand.  You saved a couple of micro seconds
by not having to cast these 16 bit ints to longs and loss SECONDS (or much
much more) thoughout the rest of the program by forcing the poor CPU to
deal with an extra bus cycles on every data fetch.  Penny wise, pound
foolish.

> 	The reason I don't care to make my software (immediately) transportable
> to these other processors is simply that my software wouldn't apply to these
> other processors.  In fact, anything anybody writes for the latter would be
> completely custom and non-portable anyway, would it not?
> 
> 						-Matt

Very true. Unless you stick to tried and true K&R/UNIX(tm) stdio functions
your not going to easily port your code.  Even these functions give bazaar
results from compiler to compiler.

Of course there IS no better way to speed code along than to use the right
algorithm in the first place.  That's where the REAL time will be gained or
lost.   But to ignore the target machines CPU limitations will still cost
you in the final result.  It depends on your feelings of 'when is fast,
fast enough?' .  Me, I'm never satisfied.  Not till I know that given my
own 'brain' limitations, and the compiler's code generating limitations
(after all, I don't want to code it all in assembler), I've done the best I
can.  And that to *ME* means using 16 bit shorts were 16 bit shorts are all
that's needed.  At least until someone comes up with a reasonably priced
68020 board/machine with 32 bit memory.

-- 
Jeff Gortatowsky       {allegra,seismo}!rochester!kodak!elmgate!jdg
Eastman Kodak Company  
<Kodak won't be responsible for the above comments, only those below>

dillon@PAVEPAWS.BERKELEY.EDU (Matt Dillon) (06/21/86)

(I absolutely refuse to include huge amounts of old messages.  this is flame
in a way, but I think it's better classified as 'opinion wars')


this is in responce to Jeff Gortatowsky 's message:

>Jeff Gortatowsky       {allegra,seismo}!rochester!kodak!elmgate!jdg
>
>Wrong.  Sorry but this is not the case.  The 68000 inside your Amiga is
>a 16 bit processor that just happens to have 32 bit registers and a 32
>bit register-to-register data path.  I call your attention to Tables
>starting on page 187 of the MC68000 Programmer's Reference Manual, 4th edition
>(C) 1984 Motorola Inc.  These tables clearly show that almost all
>instuctions pay a penalty for using a long.  ....

Not Wrong, Sorry.  My opinion.  Refering to the same page on the manual,
I would like to point out that register addressing modes take no longer
using 32 bits than 16 bits.  If you take into account that most speed-daemon
hacker-programmers use register declarations for variables in tight loops,
your only looking at an extra fetch every once in a while rather than every
other instruction.  most of the standard optimization techniques outway
any trivial amount of time saved by that extra fetch, all we really need is
a good compiler.  Of course the 16-bit compiler is going to be generally
faster, but if you look closely, it really isn't *all* that much faster.
Try doing timing runs on some of your sources (e.g. programs you have
written which were NOT explicity created for the purpose of speed testing).
Manx 32 against Manx 16 is probably as good as you'll get, though Manx
was really written to be a 16 bit compiler.

I've seen the code generated by the lattice compiler too... it's all Lattice's
fault.  Though they do seem to do some sub-expression elimination, but they 
definately do not have a peephole optimizer on the tail end.

>Then use longs in the first place and be done with it!  Again choose the
>right data type for the job at hand.  You saved a couple of micro seconds
>by not having to cast these 16 bit ints to longs and loss SECONDS (or much
>much more) thoughout the rest of the program by forcing the poor CPU to
>deal with an extra bus cycles on every data fetch.  Penny wise, pound
>foolish.

	tut tut, don't exaggerate.  Using longs in the first place 
requires you to extern your functions (16 bit compiler) in the first place 
also, so you can still wind up with a lot of junk.  I'm not saying declaring
everything 'long in the first place' is bad on a 16 bit compiler, just that
what you've said doesn't really reduce the amount of extra crap you have 
to declare at the beginning.  You still have to specify 'L' after all 
your integer constants.

>Of course there IS no better way to speed code along than to use the right
>algorithm in the first place.  That's where the REAL time will be gained or
>lost.   But to ignore the target machines CPU limitations will still cost
>you in the final result.  It depends on your feelings of 'when is fast,
>fast enough?' .  Me, I'm never satisfied.  Not till I know that given my
>own 'brain' limitations, and the compiler's code generating limitations
>(after all, I don't want to code it all in assembler), I've done the best I
>can.  And that to *ME* means using 16 bit shorts were 16 bit shorts are all
>that's needed.  At least until someone comes up with a reasonably priced
>68020 board/machine with 32 bit memory.

Agreed, to a point.  You are suggesting that the 68000 has limitations when
using 32 bit int's... that is completely incorrect in my view.  You should
consider the fact that all addresses must be handled as 32 bits and not
16 (no crap about .W addressing modes, please.)  Indrection through 32 bit
addresses, indexing through 32 bit registers... all these things point
to the fact that the 68000 handles 32-bit integers just as easily as
16-bit integers.

Assembly is fine.... for the 68000.  However, I personally find assembly
rather difficult to debug (almost as bad as basic), and drawn out.  It's
definately the way to go on a small computer for immensley
important routines, but I try to stay away from it.  Also, for you
speed daemons out there, I would like to point at that shaving 10 uS
from a tight loop with a library call in the middle is generally useless.

On algorithms, I agree wholeheartedly.  The program which writes to the
screen a character at a time is going to be an order of magnitude slower
than the program which writes to the screen in large(er) chunks, no matter
what.


					-Matt

jsgray@watdragon.UUCP (Jan Gray) (06/22/86)

In article <8606210754.AA01488@pavepaws> dillon@PAVEPAWS.BERKELEY.EDU (Matt Dillon) writes:
>>Jeff Gortatowsky       {allegra,seismo}!rochester!kodak!elmgate!jdg
>>
>>Wrong.  Sorry but this is not the case.  The 68000 inside your Amiga is
>>a 16 bit processor that just happens to have 32 bit registers and a 32
>>bit register-to-register data path.  I call your attention to Tables
>>starting on page 187 of the MC68000 Programmer's Reference Manual, 4th edition
>>(C) 1984 Motorola Inc.  These tables clearly show that almost all
>>instuctions pay a penalty for using a long.  ....
>
>Not Wrong, Sorry.  My opinion.  Refering to the same page on the manual,
>I would like to point out that register addressing modes take no longer
>using 32 bits than 16 bits.

Wrong.  Perhaps the *addressing* takes the same time; however the operations
don't.  The 68000 has internal 16 bit ALUs;
	ADD.W	D0,D1	takes 4 cycles
	ADD.L	D0,D1	takes 8 cycles.

C code which assumes 32 bit ints will run significantly slower on a 68000.
The 68020 is another story!

"You'd just watch yourself.  We're wanted men.  I have the death sentence
 on 12 systems!"

Jan Gray    jsgray@watdragon    University of Waterloo    519-885-1211 x3870

jdg@elmgate.UUCP (Jeff Gortatowsky) (06/24/86)

In article <8606210754.AA01488@pavepaws>, dillon@PAVEPAWS.BERKELEY.EDU (Matt Dillon) writes:
> Not Wrong, Sorry.  My opinion.  Refering to the same page on the manual,
> I would like to point out that register addressing modes take no longer
> using 32 bits than 16 bits.  If you take into account that most speed-daemon
> hacker-programmers use register declarations for variables in tight loops,
> your only looking at an extra fetch every once in a while rather than every
> other instruction.
> 

Ok,ok, OPINION..whatever..
You (really the compiler) still have to get that data into the register.
And thats still going to take extra time.  Yes, if your code is spending
most of it's time executing Amiga functions by all means use 32 bits (no
choice really).  But when I'm writing the glue that brings it all together
I look for ANY place 16 bits can be used.  I think you over estimate the
68000 a bit.  It means smaller, faster, tighter code (not THE best, but at
least better), even in REAL programs.   Move instructions are still doing
most of the work and that means extra bus cycles for a long (the sign
extension of 16 bits in the MOVEM instruction is a REAL loser).

> 
> 	tut tut, don't exaggerate.  Using longs in the first place 
> requires you to extern your functions (16 bit compiler) in the first place 
> also, so you can still wind up with a lot of junk.  I'm not saying declaring
> 
Yup. That's is exactly what I do.  Proper declarations and casts where ever
they are needed.  LOTS more typing for me, but more readable later on as
well a (opinion) faster.  Make the compiler do what *I* say, not what it
*THINKS* I meant.  Mind you I'm NOT casting 16 bit ints to longs. For that
I use longs in the first place. But I talked about that before.  This means 
lotsa '(struct xxxx *)' casts ecetra, but weeks or months from now I won't 
be wondering what that function call returns.  So maybe that another benny 
of 16 bit ints.  Makes me *THINK* hard about what that function returns, etc.

> Agreed, to a point.  You are suggesting that the 68000 has limitations when
> using 32 bit int's... that is completely incorrect in my view.  You should
> consider the fact that all addresses must be handled as 32 bits and not
> 16 (no crap about .W addressing modes, please.)  

First off, I've never use absolute short addressing so wouldn't presume to
give you any cr*p about it.  In *MY* view it's "your already paying the
price loading addresses so avoid doing so in data when possible". If extra
bus cycles for 32 bits isn't a limitation (no matter how big or small), I
don't know what is.

> Assembly is fine.... for the 68000.  However, I personally find assembly
> rather difficult to debug (almost as bad as basic), and drawn out.  It's
> definately the way to go on a small computer for immensley
> important routines, but I try to stay away from it.  Also, for you
> speed daemons out there, I would like to point at that shaving 10 uS
> from a tight loop with a library call in the middle is generally useless.
> 
Huh?  You can single step C code?  Where'd you get your source level
debugger?  BTW I have written exactly two assembly routines for the Amiga,
so it's not like I'm religous or anything.  On the other point, again we
agree to disagree.  First off if you havn't shaved that 10us off and can,
it's not a tight loop.  Ten microseconds per iteration? Or just 10us
period. Big difference. However we were discussing the merits of 32 bit
ints not algorithms.  Presumably neither one of us would put that call in,
if it was to be tight.

One last comment. I *DO* believe in getting it right first, then if
needed, making it faster.  It's just that many times I find the two go
hand-in-hand by using the right data type for the job, no more, no less.

Oh well.. On to the next subject, aye?
-- 
Jeff Gortatowsky       {allegra,seismo}!rochester!kodak!elmgate!jdg
Eastman Kodak Company  
<Kodak won't be responsible for the above comments, only those below>

aaron@uwmacc.UUCP (Aaron Avery) (06/25/86)

In article <1146@watdragon.UUCP> jsgray@watdragon.UUCP (Jan Gray) writes:
>Wrong.  Perhaps the *addressing* takes the same time; however the operations
>don't.  The 68000 has internal 16 bit ALUs;
>	ADD.W	D0,D1	takes 4 cycles
>	ADD.L	D0,D1	takes 8 cycles.
>
>C code which assumes 32 bit ints will run significantly slower on a 68000.
>The 68020 is another story!
>

So is the 68010, by the way. The 8 cycles for the ADD.L D0,D1 above
is due to a 2 cycle penalty for data register direct mode on a long
incurred by the 68000. The 68010 takes 6 cycles for the same operation
and similar ones for which the 68000 takes 8. This could account for
a greater increase due to putting a 68010 in your Amiga than just
the multiply and divide operations. I'd bet side-by-side comparisons of
the 68000 and 68010 in the Amiga would be greatly affected by whether
you were using Lattice with 32 bit ints, or Aztec with 16, but I guess
this would only be if you used a lot of register vars. I was previously 
unaware of any internal penalty for 32 bit operations on the 68000, so I 
thank you for this discussion, as it has been enlightening. 

Aaron Avery ({seismo,topaz,allegra,caip,ihnp4}!uwvax!uwmacc!aaron)
            (aaron%maccunix@rsch.wisc.edu)
            (aaron@unix.macc.wisc.edu)