Erik Christiansen schrieb:
On 07.10.12 10:25, Georg-Johann Lay wrote:
Are such calls "allowed" in avr-libc provided
- The special interface is documented in libgcc sources and mentions
that avr-libc makes use of the special interface
- The functions with their special interface are documented, e.g. in
the GCC wiki
Well, that's how I would do it in a project of mine, FWIW.
The question is for code that is not yet part of avr-libc, namely the
upcoming fixed-point support; it's not about optimizing code that's
already there.
Sean said that CORDIC shows bad rounding for asin, for example.
I played around with a home-brew asin approach that has no rounding
issues. The performance of the implementation can be improved if
knowledge of libgcc is used.
Holy cow, the approach is fine, I figure, just from the perspectives of
consistent code behaviour and reuse. Add performance improvements and
your case is irresistible, I reckon.
Actually I don't know if the performance compared to CORDIC is
reasonable because I have no CORDIC benchmark results.
My intuition says that CORDIC will beat code size, for speed I have no
clue, and precision and monotony is the great pro for my approach.
I once tried CORDIC with sin and cos and I observed that there is quite
some noise on the result, namely up to 7 LSB for 15 fractional bits,
i.e. 3 bits of the result are lost. And that's for a function that's
well behaved (monotone, C(oo), any derivative limited by 1, ...)
The only performance results I have so far is for 0.16 q-format square
roots which is needed for asin:
speed in Ticks: 240 (with MUL) 340 (no MUL)
size in Bytes: 80 (with MUL) 60 (no MUL)
Speed is the maximum over all 2^16 inputs.
Maybe someone can tell if these results are reasonable?
This square root comes in a "floor" and a "round to nearest" flavor.
Maximum absolute errors are (again over all inputs):
sqrt floor: -1 LSB < err <= 0 LSB
sqrt round: -1/2 LSB < err < 1/2 LSB
For the fixed-point asin the first results indicate that the computation
will need around 700 - 800 ticks (asinf needs ~2500) which is 50 ticks
per bit so CORDIC is likely faster.
For a s.15 implementation of CORDIC sin / cos I found 560 ticks (with
MUL) and 280 bytes flash.
My approach for asin consumes 560 bytes flash (dunno if it is reasonable
to compare that with CORDIC sin to estimate CORDIC asin).
I've only tried basic CORDIC to produce sin and cos. I didn't know that
asin was feasible with the method.
AFAIK that approach uses
asin(x) = atan2(x, sqrt(1-x*x))
so that it's clear you accumulate rounding errors and is must behave bad
close to the singularity at x=1.
Johann
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list