EmbeddedRelated.com
Forums
Memfault State of IoT Report

And -- pow! My memory was gone.

Started by Tim Wescott February 21, 2011
On Feb 22, 4:17=A0am, Tim Wescott <t...@seemywebsite.com> wrote:
> > > 'pow' is over 1kB!! =A0And it pulls in something called __pow_754, which > is HUGE -- like, 5kB or something! =A0Eeek! =A0I mean -- the code worked, > but without much room in the end.
Just looked at my e^X, 2^x etc. FPU code which is part of DPS. For power (PPC), written in VPA, it is $1a0 (416 dec) bytes - double precision FP. Uses the FPU on the chip though (which has fmul, fadd, fsub, fdiv). On a CPU32 - done in 68k assembly - the code size is $232 (562 dec) bytes (no FPU to help, just the integer unit). I wonder if one is not using the HLL libraries and has to write his own ones, what good is the HLL for at all then... (other than staying with the trend, that is). Dimiter ------------------------------------------------------ Dimiter Popoff Transgalactic Instruments http://www.tgi-sci.com ------------------------------------------------------ http://www.flickr.com/photos/didi_tgi/sets/72157600228621276/
David Brown wrote:
> On 22/02/2011 13:19, Mel wrote:
>> One I used, I forget whether it was for AVR or ARM, used pow to do bit >> shifts. > > That sounds /very/ strange. Bit shifts are integer operations, while > pow is a floating point function - they should not be mixed unless your > source code says they must be mixed. I'm not going to claim that gcc > for the AVR and the ARM are bug-free, or that they always generates > optimal code. But this sounds so weird that I'd want to see details > before accepting it.
It was there, in a couple of functions dedicated to a built-in device. I could hunt it down again, I suppose. My impression was that one particular coder must have thought it was cool. Mel.
ChrisQ <meru@devnull.com> writes:

> Tim Wescott wrote: >> I'm shaking the box, trying to get the software to settle enough to >> fit into a 64kB memory space. This is made difficult by the fact >> that it's a human-interface rich environment with a bit of extra fat >> contributed by the fact that I'm writing in C++. >> >> This is for an application that worked just peachy-keen on a captive >> vendor's tool set, but which is too big using gnu tools. It's to be >> expected, I suppose. >> >> As soon as I saw all of the I/O junk in the map file I realized that >> maybe I shouldn't be using sprintf (even if it _did_ fit before). >> So I took it out, and rather than contort my code, I'm writing a >> replacement for just the formats that I'm using (yes, I know, bomb >> in the code). >> >> As I usually do, I started easy -- which, in my case, means locating >> the decimal point with log10, and moving it around using pow(10.0, >> n). >> >> 'pow' is over 1kB!! And it pulls in something called __pow_754, >> which is HUGE -- like, 5kB or something! Eeek! I mean -- the code >> worked, but without much room in the end. >> >> So I'm un-powing my sprintf, shaking my head at the vicissitudes of >> free software, and (since it's a hobby project) thinking about >> processors with more memory space. >> > > One of the reasons I never use standard c lib functions much is the > amount of crud they tend to pull in, and much of it seems to use signed > types where unsigned would be more appropriate. Memories of printf() > that pulls in over 100k, just to print a formatted string. Fine if it's > running on a desktop machine, but useless for most embedded work. Same > applies to the lib. Organising the data appropriately so you can do > scaled integer math does help, or designing your own simplified format and > limited range floating point functions to suit the application, where that > needs to be externalised. > > It's not too difficult to roll your own as needed and build libraries > over a few projects, with the added advantage that you always have full > visibility of all the code in the system...
Absolutely, this is exactly what I do. -nostartfiles -nostdlib then write whats missing yourself, For my embedded work this turns out to be a few trivial things like memset, strlen etc. A typical example is a colour VGA touchscreen UI with proportional fonts and "application" program, runs in ~32-50k of ARM/thumb code. (Depending on fonts and whether ARM or thumb mode). With gcc tools. Tim: Re sprintf. One useful thing was a public domain integer-only stripped down printf. I modified it to add extra formatting codes for fixed-point numbers. Let me know if you want a copy. I have d = tenths, c=hundredths, m=thousandths. So I get efficient handling of numbers with decimal points too. E.g. temperature stored in hundredths of a degree C might be: gdiPrintf(lcd, "Temperature %5.2c degrees C\n", status.temperature); With an output like Temperature 37.12 degrees C Actually my library accepts UTF8 and so does GCC in source code, So that could be: gdiPrintf(lcd, "Temperature %5.2c &deg;C\n", status.temperature); John -- John Devereux
Didi wrote:

> > I wonder if one is not using the HLL libraries and has to write his > own ones, what good is the HLL for at all then... (other than staying > with the trend, that is). > > Dimiter
For many reasons - primarily to have full visibility and confidence in the code you include in projects. Even where sources are available to lib code, it's often to no particular coding standard, can be badly laid out and often has a lack of commentary. Do you really want to include this in client projects without verification of all the corner cases ?. Other reasons include code efficiency and greater granularity in terms of what gets dragged in at link time. Looking at your web site, it seems like you write most of your own code anyway. Who would want to write all project code in (probably) non portable assembler now... Regards, Chris
On 2011-02-22, ChrisQ <meru@devnull.com> wrote:

> One of the reasons I never use standard c lib functions much is the > amount of crud they tend to pull in, and much of it seems to use signed > types where unsigned would be more appropriate. Memories of printf() > that pulls in over 100k, just to print a formatted string.
When doing embedded stuff, I almost never use *printf routines from libc. There are some very nicely done, small-footprint replacements floating around out there that can be configured to support only the features you need. -- Grant Edwards grant.b.edwards Yow! When this load is at DONE I think I'll wash it gmail.com AGAIN ...
On Feb 22, 5:07=A0pm, ChrisQ <m...@devnull.com> wrote:
> ... > Looking at your web site, it seems like you write most of your own code > anyway. Who would want to write all project code in (probably) non > portable assembler now... > > Regards, > > Chris
Make that "most" "all" (all tools included) and you'll still be correct :-). But the assembly language is portable allright, the code which had been written for CPU32 (68k assembly) got beautifully ported to power (PPC) some 10 years ago. Porting this down (to a smaller core, say, like ARM) will be less beautiful but still doable. Yet I pray I do not have to... Hopefully all that QorIQ vaporware materializes in the not so distant future, that is :D . Anyway, I do not claim what I do is typically done by many other people, I suppose this must be said. Dimiter ------------------------------------------------------ Dimiter Popoff Transgalactic Instruments http://www.tgi-sci.com ------------------------------------------------------ http://www.flickr.com/photos/didi_tgi/sets/72157600228621276/
On 22/02/2011 15:14, Mel wrote:
> David Brown wrote: >> On 22/02/2011 13:19, Mel wrote: > >>> One I used, I forget whether it was for AVR or ARM, used pow to do bit >>> shifts. >> >> That sounds /very/ strange. Bit shifts are integer operations, while >> pow is a floating point function - they should not be mixed unless your >> source code says they must be mixed. I'm not going to claim that gcc >> for the AVR and the ARM are bug-free, or that they always generates >> optimal code. But this sounds so weird that I'd want to see details >> before accepting it. > > It was there, in a couple of functions dedicated to a built-in device. I > could hunt it down again, I suppose. My impression was that one particular > coder must have thought it was cool. >
Are you talking about some sort of application code or example code? I thought you were talking about the compiler itself generating pow() calls to implement something like (1 << n). For code written by someone with little understanding of embedded programming, I can well imagine someone writing pow(2, n) instead of (1 << n). And I have seen such poor programming in example code, especially from hardware manufacturers - it is not something related to gcc or open source programming. It's just what you get when a PHB tells a Visual Basic programmer to write embedded C code.
On 22/02/2011 15:06, Didi wrote:
> On Feb 22, 4:17 am, Tim Wescott<t...@seemywebsite.com> wrote: >> >> >> 'pow' is over 1kB!! And it pulls in something called __pow_754, which >> is HUGE -- like, 5kB or something! Eeek! I mean -- the code worked, >> but without much room in the end. > > Just looked at my e^X, 2^x etc. FPU code which is part of DPS. > For power (PPC), written in VPA, it is $1a0 (416 dec) bytes - double > precision > FP. Uses the FPU on the chip though (which has fmul, fadd, fsub, > fdiv). > > On a CPU32 - done in 68k assembly - the code size is $232 (562 dec) > bytes > (no FPU to help, just the integer unit). > > I wonder if one is not using the HLL libraries and has to write his > own ones, what good is the HLL for at all then... (other than staying > with the trend, that is). >
For embedded programming, you use /some/ HLL libraries - but not others. For example, it is common to use the libm libraries directly if you need them - but you do so only if you need it, and you do so appropriately. So if you are using an 8-bit AVR, it is very rare that you would use floats rather than integers - and even rarer that you would use doubles rather than floats. But if you /do/ need to use them, then you do so using the libraries. Other libraries are less useful in embedded systems - there is little in stdio.h that makes sense in most cases, and the *printf family is always very expensive in size and time. Many libraries for embedded toolchains come with a variety of *printf functions to give a better compromise between functionality and size. In the end, however, it comes down to a balance between the size and speed of the embedded system, and the cost and speed of the development. Sometimes it makes sense to use inefficient libraries that are easily available, rather than finding or writing something better. But you should only do so when you know what you are doing - this thread started with someone who appears to have thrown code at the toolchain without understanding the compiler or the library.
David Brown wrote:
> Are you talking about some sort of application code or example code? I > thought you were talking about the compiler itself generating pow() > calls to implement something like (1 << n). For code written by someone > with little understanding of embedded programming, I can well imagine > someone writing pow(2, n) instead of (1 << n). And I have seen such > poor programming in example code, especially from hardware manufacturers > - it is not something related to gcc or open source programming. It's > just what you get when a PHB tells a Visual Basic programmer to write > embedded C code.
I meant to mean library code. Mel.
Mel wrote:
> David Brown wrote: >>But generally speaking, beware libraries - whether C or C++ - they are >>often the cause of extra code space (and wasted run time). > > One I used, I forget whether it was for AVR or ARM, used pow to do bit > shifts.
I remember that from end-1980's MS BASIC which didn't have a shift operator. This was also the only compiler I've seen which produces the result 3 for INT(SQR(4**2)). Stefan

Memfault State of IoT Report