Byte Craft is one of the vendors who regularly make the claim of the C
compilers generating
code as tight as as assembly code. Your point is well taken. There are
big C programs out there
that can be coded with very little assembly but on a level playing field
between competent C
and assembly implementations the generated code by good compilers is
very very close less
than 1 % different. Compilers do better than assembly language
programmers in performing
accounting and data management tasks (variable allocation, variable
re-use and instruction
selection) . In our tests looking at this type of benchmark the
compilers win through attention
to detail (compilers use the whole instruction set) and variable
allocation.
Walter Banks
Byte Craft Limited.
Robert Wood wrote:
> Also, I still don't believe, even though many
compiler vendors claim
> otherwise, that C is *anything like* as efficient as assembly
> language. It
> never ceases to amaze me how big C programs get and conversely how
> small they
> are when I write them in assembly.
Assembler Vs C-Compiler
Started by ●July 10, 2003
Reply by ●July 14, 20032003-07-14
Reply by ●July 14, 20032003-07-14
Tam wrote:
> It would be interesting to know how
> many firms/people actually have NDA's with their vendors.
>
> I will put up a Poll to find out.....
We have NDA's with any of our customers that this is an issue. We assume
that all
customer code is company confidential unless we have in writing
otherwise.
w..
Reply by ●July 14, 20032003-07-14
On Mon, 14 Jul 2003 14:36:19 -0400, Walter Banks wrote: >Robert Wood wrote: > >> Also, I still don't believe, even though many compiler vendors claim >> otherwise, that C is *anything like* as efficient as assembly >> language. It >> never ceases to amaze me how big C programs get and conversely how >> small they >> are when I write them in assembly. >Byte Craft is one of the vendors who regularly make the claim of >the C compilers generating code as tight as as assembly code. It's quite common for those claims to be made. It's not just you. >Your point is well taken. There are big C programs out there >that can be coded with very little assembly but on a level playing >field between competent C and assembly implementations the >generated code by good compilers is very very close less >than 1 % different. >Compilers do better than assembly language programmers in performing >accounting and data management tasks (variable allocation, variable >re-use and instruction selection). In our tests looking at this type >of benchmark the compilers win through attention to detail (compilers >use the whole instruction set) and variable allocation. > >Walter Banks I've seen some absolutely excellent compilers in my day. One of them was the Pascal compiler for the Apollo DN 3000, for example. I remember one function I tried hand-coding and I couldn't find a single word to squeeze out, hand-writing it. I was able to beat it in other places, but it was generally *very* good. But on embedded systems, this claim of "within 1%" I actually have been checking every chance I get, over the last 15 years or so. And in every single case where I had a chance to carefully consider the issues and try my hand at it, it's not been born out by the empirical results. Interestingly, I just had an opportunity to verify this concept about two years ago on an entire application! I'd originally written it in assembly for one of the smaller PIC, an OTP part. Later, in a board revision we decided to both specify a larger part (flash-based) and to port the application into C, as a first step before adding other functionality. This presented an excellent chance to see what's what. Now, in this case, we decided to use the Microchip PIC18 C compiler for the newer chip, a PIC18F252. (I'm not going to get into a protracted comparison of Microchip's ability or lack thereof in putting out a decent compiler for a difficult chip.) The assembly had NOT been written with the idea of trying to compete with C, of course, since we didn't have any idea we'd ever be attempting C later on at that time. It was written to be understandable and to get the right job done in the given space. The first job was to port the exact application into C, within our ability to do so accurately. Now, I have to first say that I've been using C, regularly, since 1978, when I first started with it for the Unix v6 kernel. And I've been using C for embedded applications since 1985. So I think I am relatively competent at C and I'm pretty good at keeping it both understandable as well as well crafted for reasonably small size. I'm well aware of the details *how* C compilers generate their code, having had some small experience trying my own hand at it, but I'm not the expert you or others are who do this every day in their work. But I'm not entirely ignorant, either. In other words, I'm not the worst C coder out there and neither am I the best, but I'm generally competent. When the exact-port was completed and tested, I then compared the resulting memory footprints. The original assembly code occupied approximately 2k word of 14-bit instructions (it was on the PIC16C73B.) The final C code, after I stripped out the forced inclusion of the darned unused FP library [geez was that large], occupied almost 7k word of 16-bit instructions. Now, there were a lot of reasons why this was so, in digging into the details. Some of them were that C simply didn't offer a syntax to directly mirror some of the semantics I used in the assembly code. For example, I used an array of subroutines which were 4-word-aligned so that a simple, calculated CALL sufficed. And, naturally, these routines could NOT have fit in 4-word areas if they used C function semantics, in any case. Other cases were where the C compiler failed to choose much more efficient idioms for the syntax it did face. I've haven't been handled an entire application on a platter like this to test, before. Most of my conclusions are drawn from my general experiences, together with the many, many times I've faced going in the other direction (re-coding in assembly, a C routine which we'd hoped to speed up that way.) In every such case, I've been able to easily outwit the C compiler, even when forced to stay within the semantics of the particular C compiler (such as scratch registers, parameter passing, stack frame, and epilogue/cleanup.) Sometimes, only a little. Most of the time, even in the more elementary cases (of perhaps 5 or 7 lines of C code and only integers involved and no external function calls), it's been more like 20%-100%. Anyway, I've yet to find an embedded compiler where I can't do better than 1% in writing the assembly code, even on relatively inconsequential routines. And without having to work at it much, either. Here's one to try, I've used before because it's a very common teaching algorithm, in generally portable and can use the natural word size, and doesn't get into floating point complications or even issues of signed comparisons. Just your basic algorithm with =, !=, <, +/- operation, and unsigned integers. It doesn't get much more basic and still be useful: unsigned int gcd (unsigned int a, unsigned int b) { if (a == 0 && b == 0) b= 1; else if (b == 0) b= a; else if (a != 0) while (a != b) if (a < b) b -= a; else a -= b; return b; } Then compare the output with what you can come up with, doing hand assembly. Frankly, I'm curious about the MSP430 case, where I honestly believe the C compiler has a darned good chance to do almost as well as an assembly coder. (I'll try my hand at the assembly.) I guess the sum of my experience tells me that the 1% figure is something I just plain ignore as not being meaningful, whether applied to an isolated set of functions which must live in the context of a C compiler environment and follow those rules or an entire application where I'm free to set up rules of my own in the assembly case. C does mean many other things to me. But not 1%. Jon
Reply by ●July 14, 20032003-07-14
> That story about Atmel is not fiction. I'm not sure all of what
> parts were affected but I know for a fact that the
FPGA
> configuration memories we were buying from Atmel a few years ago
> were put on "hold" because they had promised Siemens something
like
> 100% of their fab capacity. Luckily we had enough on hand to get by
> but I am sure there are plenty of customers that got screwed on that
> deal.
Got burnt by Motorola a few years ago with exactly the same issues.
Getting 6805's suddenly went out to months and months lead time. I know
around our area it turned a LOT of people off Motorola big time and it
coincidently was at the time that PIC's took off.... Unfortunately I
don't think any of the manufacturers are immune to this...
--
This email is confidential and intended solely for the use of the individual to
whom it is addressed. Any views or opinions presented are solely those of the
author and do not necessarily represent those of Nautronix Ltd.
If you are not the intended recipient, you have received this email in error and
use, dissemination, forwarding, printing, or copying of this email is strictly
prohibited. If you have received this email in error please contact the sender.
Although our computer systems use active virus protection software, and we take
various measures to reduce the risk of viruses being transmitted in e-mail
messages and attachments sent from this company, we cannot guarantee that such
e-mail messages and attachments are free from viruses on receipt. It is a
condition of our using e-mail to correspond with you, that any and all liability
on our part arising directly or indirectly out of any virus is excluded.
Please ensure that you run virus checking software on all e-mail messages and
attachments before reading them.
Reply by ●July 14, 20032003-07-14
On Tue, 15 Jul 2003 09:50:12 +0800, Tim wrote:
>> That story about Atmel is not fiction.
I'm not sure all of what
>> parts were affected but I know for a fact that the FPGA
>> configuration memories we were buying from Atmel a few years ago
>> were put on "hold" because they had promised Siemens
something like
>> 100% of their fab capacity. Luckily we had enough on hand to get by
>> but I am sure there are plenty of customers that got screwed on that
>> deal.
>
>Got burnt by Motorola a few years ago with exactly the same issues.
>Getting 6805's suddenly went out to months and months lead time. I know
>around our area it turned a LOT of people off Motorola big time and it
>coincidently was at the time that PIC's took off.... Unfortunately I
>don't think any of the manufacturers are immune to this...
Yeah, I've been burned by Mot, as well. More than 12 month lead
times, in fact. I like playing with them, frankly. And I still
use some of their parts in devices I haven't yet gotten around
to designing them out of. But I'm trying not to use them in
anything new.
Jon
Reply by ●July 15, 20032003-07-15
This is a little bit like the chicken and egg. personally I think the
books were written because the PIC was popular. No point expending lots
of effort, time and money on somethign that doesn't have a market yet.
Just my thoughts from the ground floor, as one who was intimately
involved with Microchip in its transitional period from niche to noticed.
Al
Bruce Cannon wrote:
> After low-cost tools I think the biggest influence
driving the use of the
> PIC has to be the literally scores of tutorial books on programming it
> (mostly in assembly by the way).
>
> --Bruce
>
>
>
>>The PIC was the
>>first micro that came out with such low priced tools (MPLAB is free, and
>>is still far better than most commercial IDE's), that were so well
>>integrated, yet were affordable to hobbyists, and even kids with a
>>little spare pocket money. As they moved into the work force what else
>>would they use? The STAMP also helped, it made using micros much easier
>>for many who might have shied away from assembler or C, as being too
>>hard. Once bitten by the bug many felt compelled to move up the chain,
>>and stuck with the same micro. The PIC16F84 was probably the worst of
>>the PICs, the PIC16C73, even with crash and burn, was a far better
>>option, yet the F84 won out, again this gives another pointer, for the
>>POIC's popularity, a dirt cheap micro that didn't need a UV
eraser, and
>>was in circuit programmable.
>
>
>
>
> .
>
>
>
> ">http://docs.yahoo.com/info/terms/
>
>
>
Reply by ●July 15, 20032003-07-15
Andreas this group doesn't allow attachments. It should be small
enough
to include inline.
Al
Andreas Schwarz wrote:
> Jonathan Kirwan <jkirwan@jkir...> wrote:
>
>
>>When the exact-port was completed and tested, I then compared
>>the resulting memory footprints. The original assembly code
>>occupied approximately 2k word of 14-bit instructions (it was on
>>the PIC16C73B.) The final C code, after I stripped out the
>>forced inclusion of the darned unused FP library [geez was that
>>large], occupied almost 7k word of 16-bit instructions.
>
>
> Ouch...
>
>
>>Here's one to try, I've used before because it's a very
common
>>teaching algorithm, in generally portable and can use the
>>natural word size, and doesn't get into floating point
>>complications or even issues of signed comparisons. Just your
>>basic algorithm with =, !=, <, +/- operation, and unsigned
>>integers. It doesn't get much more basic and still be useful:
>>
>>
>> unsigned int gcd (unsigned int a, unsigned int b)
>> {
>> if (a == 0 && b == 0)
>> b= 1;
>> else if (b == 0)
>> b= a;
>> else if (a != 0)
>> while (a != b)
>> if (a < b)
>> b -= a;
>> else
>> a -= b;
>>
>> return b;
>> }
>>
>>
>>Then compare the output with what you can come up with, doing
>>hand assembly. Frankly, I'm curious about the MSP430 case,
>>where I honestly believe the C compiler has a darned good chance
>>to do almost as well as an assembly coder.
>
>
> I tried it with MSPGCC:
> andreas@d700 tmp $ msp430-gcc -Os -g -c test.c -o test.o
> andreas@d700 tmp $ msp430-size test.o
> text data bss dec hex filename
> 46 0 0 46 2e test.o
> andreas@d700 tmp $ msp430-objdump -d --source test.o > test.lst
>
> The listing file is attached.
>
> I'm very much interested in what other compilers make out of this
code.
>
>
>
>
>
>
> .
>
>
>
> ">http://docs.yahoo.com/info/terms/
>
>
>
Reply by ●July 15, 20032003-07-15
Hi,
> unsigned int gcd (unsigned int a, unsigned int
b)
> {
> if (a == 0 && b == 0)
> b= 1;
> else if (b == 0)
> b= a;
> else if (a != 0)
> while (a != b)
> if (a < b)
> b -= a;
> else
> a -= b;
>
> return b;
> }
Well, CrossWorks produces something you'd expect:
CODE SECTION CODE
1100 ___begin_CODE
unsigned int gcd (unsigned int a, unsigned int b)
1100 .ALIGN BYTE[2]
1100 _gcd
1100 @18
if (a == 0 && b == 0)
1100 0f93 CMP.W #0, R15
1102 0420 JNZ @19
1104 0e93 CMP.W #0, R14
1106 0220 JNZ @19
b= 1;
1108 1e43 MOV.W #1, R14
110a 0e3c JMP @20
110c @19
else if (b == 0)
110c 0e93 CMP.W #0, R14
110e 0220 JNZ @21
b= a;
1110 0e4f MOV.W R15, R14
1112 0a3c JMP @22
1114 @21
else if (a != 0)
1114 0f93 CMP.W #0, R15
1116 0824 JZ @23
1118 053c JMP @24
111a @25
if (a < b)
111a 0f9e CMP.W R14, R15
111c 022c JC @26
b -= a;
111e 0e8f SUB.W R15, R14
1120 013c JMP @27
1122 @26
a -= b;
1122 0f8e SUB.W R14, R15
1124 @27
1124 @24
while (a != b)
1124 0e9f CMP.W R15, R14
1126 f923 JNZ @25
1128 @28
1128 @23
1128 @22
1128 @20
return b;
1128 0f4e MOV.W R14, R15
112a @29
112a @30
112a 3041 RET
112c @31
void main(void)
112c .ALIGN BYTE[2]
112c _main
112c @32
gcd(10, 15);
112c 3f400a00 MOV.W #10, R15
1130 3e400f00 MOV.W #15, R14
1134 b0120011 CALL #_gcd
1138 @33
1138 @34
1138 3041 RET
113a @35
-- Paul.
Reply by ●July 15, 20032003-07-15
Anreas, Can you possibly post the assembler source code of GCD? Graham. --- In msp430@msp4..., Andreas Schwarz <andreas-s@w...> wrote: > Jonathan Kirwan <jkirwan@e...> wrote: > > > When the exact-port was completed and tested, I then compared > > the resulting memory footprints. The original assembly code > > occupied approximately 2k word of 14-bit instructions (it was on > > the PIC16C73B.) The final C code, after I stripped out the > > forced inclusion of the darned unused FP library [geez was that > > large], occupied almost 7k word of 16-bit instructions. > > Ouch... > > > Here's one to try, I've used before because it's a very common > > teaching algorithm, in generally portable and can use the > > natural word size, and doesn't get into floating point > > complications or even issues of signed comparisons. Just your > > basic algorithm with =, !=, <, +/- operation, and unsigned > > integers. It doesn't get much more basic and still be useful: > > > > > > unsigned int gcd (unsigned int a, unsigned int b) > > { > > if (a == 0 && b == 0) > > b= 1; > > else if (b == 0) > > b= a; > > else if (a != 0) > > while (a != b) > > if (a < b) > > b -= a; > > else > > a -= b; > > > > return b; > > } > > > > > > Then compare the output with what you can come up with, doing > > hand assembly. Frankly, I'm curious about the MSP430 case, > > where I honestly believe the C compiler has a darned good chance > > to do almost as well as an assembly coder. > > I tried it with MSPGCC: > andreas@d700 tmp $ msp430-gcc -Os -g -c test.c -o test.o > andreas@d700 tmp $ msp430-size test.o > text data bss dec hex filename > 46 0 0 46 2e test.o > andreas@d700 tmp $ msp430-objdump -d --source test.o > test.lst > > The listing file is attached. > > I'm very much interested in what other compilers make out of this code. > > >
Reply by ●July 15, 20032003-07-15
Jonathan Kirwan <jkirwan@jkir...> wrote: > When the exact-port was completed and tested, I then compared > the resulting memory footprints. The original assembly code > occupied approximately 2k word of 14-bit instructions (it was on > the PIC16C73B.) The final C code, after I stripped out the > forced inclusion of the darned unused FP library [geez was that > large], occupied almost 7k word of 16-bit instructions. Ouch... > Here's one to try, I've used before because it's a very common > teaching algorithm, in generally portable and can use the > natural word size, and doesn't get into floating point > complications or even issues of signed comparisons. Just your > basic algorithm with =, !=, <, +/- operation, and unsigned > integers. It doesn't get much more basic and still be useful: > > > unsigned int gcd (unsigned int a, unsigned int b) > { > if (a == 0 && b == 0) > b= 1; > else if (b == 0) > b= a; > else if (a != 0) > while (a != b) > if (a < b) > b -= a; > else > a -= b; > > return b; > } > > > Then compare the output with what you can come up with, doing > hand assembly. Frankly, I'm curious about the MSP430 case, > where I honestly believe the C compiler has a darned good chance > to do almost as well as an assembly coder. I tried it with MSPGCC: andreas@d700 tmp $ msp430-gcc -Os -g -c test.c -o test.o andreas@d700 tmp $ msp430-size test.o text data bss dec hex filename 46 0 0 46 2e test.o andreas@d700 tmp $ msp430-objdump -d --source test.o > test.lst The listing file is attached. I'm very much interested in what other compilers make out of this code.