And -- pow! My memory was gone.

Do you really need that? For most floating-point display code I do, nobody needs exponential format. And for "handy" numbers, one can do a simple, slow, probably totally standards-violating but short float max = 1.0; while (max < value) max *= 10; while (max > 1.0) { max /= 10; int n = 0; while (value >= max) { ++n; value -= max; } putchar('0' + n); } Make the while loop a little longer for fractional output.

Even if you need exponential format, the decimal point can be located without log10. int exp2, exp10; frexp(c, &exp2); exp10 = exp2 * 19728L / 65536; // 65536/19728 \approx log_2 10 frexp just dissects floating point representation. The result may be one off, which can be easily corrected (if, after moving the decimal point, the result is >= 10.0). pow(10.0, n) for integral n can be done with a loop instead of a log/exp pair.

At that point, I'd go hunting for a switch "link with non-IEEE-754 floating point libraries".

Stefan

Reply to
Stefan Reuther
Loading thread data ...

In comp.dsp Jason wrote: (snip)

(snip)

Since about when I learned C (before ANSI C), I have thought the lack of integer power functions a mistake in C. There should be functions for both integer to integer power, and double to integer power. Optimizing compilers would also optimize small integer powers. Oh well.

-- glen

Reply to
glen herrmannsfeldt

There seems to be about 3-4kB of stuff that's specifically associated with C++, starting with malloc (which I know _I'm_ not using) and going from there.

Cortex M3

Newlib.

gcc 4.5.2 -- is that too out of date? Maybe there's a beta version that I should be using?

This is a fresh build using the "summon-arm-toolchain" script that seems to be one's best bet for getting something that'll work on the Cortex M3.

I will look into the -ffast-math switch. Hopefully I can use it without rebuilding the libraries, but I can do that, too.

I _know_ there's more efficient ways! Like I said -- I started out with 'easy', and planned on working from there.

Obviously.

Ayup. And I'm not terribly inclined to rewrite the library, so will probably go with working around the problems.

Well yes. In this case, the 'different bucket' principal applies -- one's budget for profit-generating work has a few more zeros at the end than one's budget for playing around.

I vastly prefer the command-line tool approach. If I can't go to a command line and type 'make' to kick things off, then I haven't finished the job yet. Using an IDE to do your thinking for you is just an invitation to broken code in a month or two, and an endless life of never knowing if you've gotten all of the critical files archived.

Mostly I was sharing my amazement about how much of a chunk one (supposedly) itty bitty mathematical function took up, and how much more space the gnu embedded library for the ARM takes up than the alternative, commercial, tool. (With the library sprintf, the thing compiles to something like 78kB, which is a barrier to progress given that the processor in question only has 64kB of flash).

I do appreciate your suggestion about -ffastmath.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

I never use those. My impression of them is that they're written by zit-faced kids in India who aren't good enough to get jobs writing software for spammers. Even if they get you half way through a project, at some point before you're done they bite you.

I know that, but I also know that there was a software vendor library (it has to be either Keil or IAR -- I think IAR) that's much smaller.

Yup.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Come to think of it, I vaguely remember putting 'sprintf' in as a placeholder with the original tool chain, and being rather surprised when things actually linked.

Now I need to dig out the old Windows machine, and see what was on there...

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

What is "the Gnu embedded library for the ARM"?

I can think of probably a half-dozen different "libc" implimentations I've used with gcc. Which one are you using?

If you're using glibc and hoping for something not-huge, you're going to be pretty frustrated. uClibc and newlib are less huge and still pretty full-featured. There are others that are smaller-still, but they often tend to be specific to a particular architecture, and lack some features (e.g. they may not provide any of the calls that use the heap).

--
Grant Edwards               grant.b.edwards        Yow! BELA LUGOSI is my
                                  at               co-pilot ...
                              gmail.com
Reply to
Grant Edwards

It makes sense, though. GCC has a large number of target architectures, and therefore these libraries have been written in C to make them easier to port.

Commercial tools are usually aimed towards a single target, which makes it a lot easier to hand optimize the math libs in assembly.

Reply to
Arlet Ottens

1st: Be sure to set -fno-exceptions -fno-rtti ! 2nd: Check the map-file who pulls in malloc. If you use sprintf, there you are. 3rd: Get the sprintf() out of the newlib sources and make a local copy where you remove the un-needed stuff.

Using the latest build might not always lead to the best results. Did you try e.g. CodeSourcery ?

That'll won't improve the code size. This switch only tells GCC to be a bit less strict w.r.t. IEEE754

--
42Bastian
Do not email to bastian42@yahoo.com, it's a spam-only account :-)
Use @monlynx.de instead !
Reply to
42Bastian Schick

Table ! Table ! Table !

Are you using float or double ?

What is the range for ?

Ok. Do the math: 1KB => table for pow(10,0) .. pow(10,255)

--
42Bastian
Do not email to bastian42@yahoo.com, it's a spam-only account :-)
Use @monlynx.de instead !
Reply to
42Bastian Schick

Or just multiply by 10 in a loop.

Reply to
Arlet Ottens

Sorry. Newlib. I've always ever just started from bare metal or used vendor-provided libraries. The free software landscape is an interesting one (and this is one of the reasons I'm using it for a hobby project -- so I'll be familiar with the pitfalls if I use it professionally).

If I could figure out how to keep C++ without using the heap, I'd be a happy camper. I'm not even sure if malloc &c. are getting _called_, or just pulled in because C++ uses "new", which uses -- well, you get the idea. For embedded I pretty much avoid dynamic deallocation like the plague*; while this is against the C++ desktop paradigm, it lets you use a very useful subset of the language without a whole 'heap' of trouble.

  • Meaning I'll "new" things at system startup but only if they're going to live until power-down. This gives one great flexibility in making portable libraries while still not fragmenting the heap through new-delete-new-delete-new sequences.
--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Check!

I should know this -- how do I do that? I can see it in the symbol table, but I don't know how, from the object file, I can see what ended up pulling in malloc.

That's what I'm doing, to find out that lazily using 'pow' calls in a whole bunch-o-memory.

I was having trouble with CodeSourcery several months ago, and on-line comments were pointing toward building the latest.

Hey! It does too -- it holds things down by ten or twenty whole bytes!!

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Even hand optimizing in C for a specific processor, or doing mostly C with assembly just in the spots where it really matters, can do considerable good for both size and run time.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Given that in this particular case the code is servicing a maintenance/debug interface that never, ever has to go fast, that's pretty much what I'm doing now.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

In comp.dsp 42Bastian Schick wrote: (snip)

Or a table of powers of 1e10 (over the range necessary), and powers of 10 from 0 to 9. Then one multiply. (Useful for decimal conversions.)

Or, two tables based on a power of two division probably makes even more sense. Powers of 10 from 0 to 15, powers of 1e16 from -32 to 31 or so. Not so may bytes at all.

-- glen

Reply to
glen herrmannsfeldt

For practical values of 'n' (less than 10), it probably runs faster than pow() anyway.

Reply to
Arlet Ottens

This is what crossed my mind, Tim, in your case. I've written custom log functions which execute more quickly than an FP div and take up rather little space on an 8051, for example. I don't even blink about such things; just set down and get 'er done and then run some tests against it in simulation to make sure it works over the range of inputs.

For specialized cases like this, I'd write specialized code. There are a few handy books to have about, which I suspect you may already have. I'll mention a few that may bear directly on the topic. I think PJ Plauger has written a book on the c library that is worth having around (nicely exposes all of those sprintf details, for example.) I also enjoy having Analog Device's numerical approximation books they developed for the ADSP-21xx family (the black, hard-bound book in particular would be good here.) They used to give them away for free (as well as sell them to those who didn't bother to ask for a free copy and took the still easier way out and wrote checks.) Although there are some errors in it, another nice book with a different kind of segue is "Math Toolkit for Real-Time Programming," by Jack W. Crenshaw. And everyone MUST have an edition or two of "Numerical Recipes."

Jon

P.S. Not really related to the above issue but which come to mind right now because they helped me a lot:

  • E Oran Brigham's "The Fast Fourier Transform" (I use the
1974 first edition) -- the one book for FFTs that in my estimation stands above all others I've experienced.

  • Ronald Graham, Donald Knuth, and Oren Patashnik, "Concrete Mathematics" -- a unique place for this book. Nothing else quite like it and a must-have, I think.

  • Nicholas John Loy's "An Engineer's Guide to FIR Digital Filters" -- a very intuitive approach to understanding FIR filters and applications of them.
Reply to
Jon Kirwan

So what? Consider yourself lucky it's not even bigger than that.

Seriously, though, setting aside the *printf() and *scanf() families themselves, pow() is easily the most complicated function in the entire Standard C Library, even with hardware FPU support. Without it, it can easily be twice as large as that if you want to really cover all the corner cases (IEEE754 special data formats, getting it right even at the boundaries of precision or range, ...).

Oh, come on guys, you can do better than that, even under code size pressure. Has everybody already forgot about iterated squaring and multiplying? In a nutshell:

while exponent left if exponent uneven: multiply base into result right-shift exponent by one replace base by its square

Hardly any more complex than iterated multiply, but O(log(exponent)) instead of O(exponent).

Or do yourself a favour and use hexadecimal floating point format instead. _Much_ easier on the binary ALU, standardized format, and still (marginally) human-readable.

Reply to
Hans-Bernhard Bröker

Cross-reference outputs from the linker step can be very useful in tracing why library code has been linked in. But one of the unfortunate aspects of C++ libraries with all their templates is the horrendous mangled names that make this task difficult.

OK - useful to know.

OK. Newlib can be big - it has a lot of features, but it's not the smallest library around.

No, gcc 4.5 is the current version. So no problem there.

There are /many/ ways to get hold of a gcc toolchain, especially for a popular target like the ARM. For most people, it is best to get a pre-packaged setup. There are free builds, and commercial builds, with different pros and cons. For example, Rowley sell a package with their own library, which may suit you better. Personally, I like CodeSourcery

- they are the people who do most of the work on the ARM port of gcc, and you can get packages ranging from free to fairly expensive depending on the support packages, additional libraries, integration with Eclipse, etc. The paid-for packages are /much/ cheaper than Kiel or IAR - they are well within the reach of most hobbyists.

You shouldn't need to rebuild the libraries. However, I can't give a categoric answer off-hand. But -ffast-math can make a big difference to floating point code. Obviously you'll also want to use at least -Os optimisation for your code too. And if you want the smallest and fastest code, look into the LTO flags for doing full program optimisation (though it makes debugging a lot harder).

Maybe we are looking at this from different angles - using log10 when displaying a floating point number sounds like a /hard/ way to do it!

Of course, you get to learn a lot more when playing around (my boss always worries if I say a prospective project sounds "interesting", or "a chance to learn").

I agree with that. Most tools at least let you use a command line, but I've used some commercial tools that will only run from within their IDE, which is invariably a terrible editor.

Also remember to avoid doubles unless you really need them - they are a lot slower than floats, and need larger library code.

I'll try and have a look tomorrow at a project I have on the M3 using CodeSourcery's tools - I /think/ it uses snprintf (it's not my code, so I don't know it all).

Reply to
David Brown

Well...

I misnomered* that. The use case for the system as a whole is to be a control systems training platform for embedded software guys. It's just closing a loop at 100Hz or a kHz. The whole thing could be done in integer or other fixed point math, with very light loading on the processor. But I want people to be able to focus on the control systems part of things, not picking through all the fussy little details that it would make sense to pick through for a true production machine.

So all the math is done in floating point, and presented that way to the outside world. In order to do that, I use a processor that has an excess of resources -- except flash. That'll be fixed when I stop using eval boards and actually put processors down on my own board.

  • Dang -- 'misnomered' is actually in my spell checker!
--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.