How are math.h library functions like sqrt, asinf, tanf implemented in CoIDE - Page 1
Forum section: electronics / general

author: kody
author_rank: Contributor
timestamp: December 28, 2014, 03:08:51 am
content: How are math.h library functions like sqrt, asinf, tanf implemented for the CoIDE compiler?Need further information regarding the internal implementation(like taylor series?) to calculate the number of cycles taken for a certain program which implements these functions takes in FPU enabled Cortex M4 based MCU's.

author: dannyf
author_rank: Super Contributor
timestamp: December 28, 2014, 03:10:03 am
content: CoIDE is just an IDE. The actual implementation is done by the compiler(s) you hook to CoIDE, just like any other IDE.

author: Mechatrommer
author_rank: Super Contributor
timestamp: December 28, 2014, 04:14:35 am
content: Quote from: dannyf on December 28, 2014, 03:10:03 amthe implementation is done by the library that came with the compiler, compiler is just that, to compile them. to know exactly whats going on, one need to dig the library, if one is lucky, they may find it in the form of plain source code, if one is unlucky, they may find it in the form of obj or precompiled stuffs.

author: kody
author_rank: Contributor
timestamp: December 28, 2014, 07:35:20 am
content: I have used the arm-gcc compiler. I have tried to search online for a good description of these functions in source code. But to no avail. Could you please provide any further sources?Math.h is the library

author: westfw
author_rank: Super Contributor
timestamp: December 28, 2014, 10:04:31 am
content: I believe that by default, the gcc compilers use a set of generic software floating point code as part of libgcc (https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html), and higher level math functions as part of gcc libc (http://www.gnu.org/software/libc/) All nice and portable, but not particularly fast or small.Technically, these are separate from the compiler, and in fact are one of the things that a value-added compiler vendor might provide as "improved" versions. For example, avr-gcc has its own complete set of floating point routines. However, coide expects you to download the ARM compiler from launchpad.net, which claims to be using newlib or newlib-nano, so you can find code there, ie:https://github.com/32bitmicro/newlib-nano-1.0/tree/master/newlib/libm/mathIt takes a brave (or desperate) vendor or engineer to implement new floating point math code...Different libs for chips with HW floating point, of course. And cmsis-dsp has some specially optimized functions (apparently not direct replacements for libm functions, though.) CooCox does seem to have a bunch of peripheral libraries that replace the usual vendor libraries, but I don't see alternate floating point functions.

author: 0xdeadbeef
author_rank: Super Contributor
timestamp: December 28, 2014, 10:35:00 am
content: Quote from: kody on December 28, 2014, 03:08:51 amAt least for sqrt, usually a variant of newton's method is used to calculate the invert square root.See:http://en.wikipedia.org/wiki/Fast_inverse_square_rootWell, this is at least true for SW implementations, but I would assume that HW implementations use the same approach.

author: nctnico
author_rank: Super Contributor
timestamp: December 28, 2014, 11:25:32 am
content: Quote from: kody on December 28, 2014, 07:35:20 amNo. Math.h is a so called header file describing the functions. The actual library is libm. You have to look for the sources of libm. This can be tricky because the implementation depends on whether the processor you are using has a floating point processor or not.

author: kody
author_rank: Contributor
timestamp: December 28, 2014, 05:32:21 pm
content: The processor I used is a STM32F4 it has FPU. But, we can have the option of enabling it or not.So, by observing the documentation for these functions in libm code give some idea to calculate the number of cycles it took to calculate that particular function?For example- for sinf function with fpu enabled - can we calculate the number of clock cycles consumed for it?

author: kody
author_rank: Contributor
timestamp: December 28, 2014, 05:41:57 pm
content: Thanks @westfw! that was primarily what I would be concerned with.Quote from: westfw on December 28, 2014, 10:04:31 am

author: zapta
author_rank: Super Contributor
timestamp: December 28, 2014, 05:42:32 pm
content: Quote from: kody on December 28, 2014, 05:32:21 pmCan't you just run a benchmark and extract the numbers from it?

author: 0xdeadbeef
author_rank: Super Contributor
timestamp: December 28, 2014, 06:17:57 pm
content: Well, a quick search brings us to the manual:http://www.st.com/st-web-ui/static/active/jp/resource/technical/document/application_note/DM00047230.pdfFrom what I see there, it's single precision FPU with add/sub/mul/div and sqrt plus some MAC instructions, but no trigonometric functions.Quoting the manual, the cycles needed are:Code:? Absolute value (1 cycle)? Negate of a float or of multiple floats (1 cycle)? Addition (1 cycle)? Subtraction (1 cycle)? Multiply, multiply accumulate/subtract, multiply accumulate/subtract then negate (3 cycles)? Divide (14 cycles)? Square root (14 cycles)Obviously, if they are part of a math library, this might need some additional cycles. E.g. if the check the value for a square root to be positive etc.Anyway, the above functions are relatively "cheap" cycle wise. The trigonometric functions are then probably implemented using taylor series and accordingly expensive.

author: dannyf
author_rank: Super Contributor
timestamp: December 28, 2014, 06:25:05 pm
content: QuoteYeah: most simulators will provide exact cycle counts for you; and you can use timers too - systick comes in handy for things like this.

author: kody
author_rank: Contributor
timestamp: December 29, 2014, 10:36:15 pm
content: Hi dannyf,When you say most simulators, can you please give some examples. Like open-source simulator software.ThanksQuote from: dannyf on December 28, 2014, 06:25:05 pm

author: kody
author_rank: Contributor
timestamp: December 29, 2014, 10:37:57 pm
content: Can we run the benchmarks from the CoIDE compiler?Quote from: zapta on December 28, 2014, 05:42:32 pm

author: kody
author_rank: Contributor
timestamp: December 29, 2014, 10:42:54 pm
content: Thanks for the link 0deadbeeef. I too have it. The problem is, since I do not know how exactly the asinf and tanf functions are implemented. I can only keep guessing with these numbers.Quote from: 0xdeadbeef on December 28, 2014, 06:17:57 pm

author: T3sl4co1l
author_rank: Super Contributor
timestamp: December 29, 2014, 11:09:26 pm
content: If you need to know implementation... inspect the implementation!Find the library and disassemble the routines, or at worst, write a "simplest example program" incorporating the interested function, and disassemble that (the machine code output is then necessarily part of the project, and any IDE worth its salt will provide a disassembled view of that output).If you can't read ARM assembler... better get a book/guide and a pot of coffee...Tim

author: 0xdeadbeef
author_rank: Super Contributor
timestamp: December 29, 2014, 11:30:38 pm
content: Quote from: kody on December 29, 2014, 10:42:54 pmIt clear that these function will lead alotof cycles. Indeed, if they're implemented with an accuracy threshold, the number of loops needed for approximation depends on the actual value.Not the correct repository, but to get an impression:http://svnweb.cern.ch/world/wsvn/vdt/trunk/include/tan.hThere is a fast tangens implementation there called fast_tanfm which avoids the iterations and is mostly linear.In this fast implementation are about 15 multiplications and one division, plus a lot of additions and integer operations. I'd assume this will cost at least 100 cycles in sum. Probably more.If the non-fast version with iterations is used, the runtime behavior will me much more unpredictable and thus should not be used in a realtime environment.

author: dannyf
author_rank: Super Contributor
timestamp: December 30, 2014, 12:46:57 am
content: QuoteYes, if you have a hardware debugger like st-link or jlink, + the actual hardware.

author: theoldwizard1
author_rank: Regular Contributor
timestamp: December 30, 2014, 01:02:53 am
content: Quote from: kody on December 28, 2014, 03:08:51 amComplex math function are typically implemented usingTaylor Series. Slow, but accurate.

author: zapta
author_rank: Super Contributor
timestamp: December 30, 2014, 01:09:56 am
content: Quote from: theoldwizard1 on December 30, 2014, 01:02:53 amOP, you can use an implemented that trades accuracy for speed, for example a table driven piece wise interpolation.

author: kody
author_rank: Contributor
timestamp: December 30, 2014, 11:46:43 pm
content: @dannyf - is it not possible if we only have the compiler? I mean, without the actual hardware/microcontroller.Quote from: dannyf on December 30, 2014, 12:46:57 am

author: tggzzz
author_rank: Super Contributor
timestamp: December 31, 2014, 01:03:09 am
content: Quote from: theoldwizard1 on December 30, 2014, 01:02:53 amOr, where multiplications are expensive, CORDIC is used for some functions.http://en.wikipedia.org/wiki/CORDIC

author: westfw
author_rank: Super Contributor
timestamp: December 31, 2014, 04:17:54 am
content: QuoteThis is likely to be difficult, especially if you're using the the gnu libraries. The sort of code that is good for portability is frequently not very good for readability (although, the disassembled object code might be better than the source...)Keil has a free evaluation version (up to 32k code size), with simulator, that could probably be used to measure this without having actual hardware. OTOH, Keil may have their own libraries. (On the third hand, Keil is now owned by ARM, so they may be distributing the same libraries.) I guess that at least in theory, you could load up binaries produced by other compilers into the Keil simulator...

author: dannyf
author_rank: Super Contributor
timestamp: December 31, 2014, 02:11:45 pm
content: QuoteYes. By looking at the delisting and counting up the instruction cycles.QuoteA far better approach is to get the actual hardware.

author: Mechatrommer
author_rank: Super Contributor
timestamp: January 01, 2015, 01:56:35 am
content: Quote from: dannyf on December 31, 2014, 02:11:45 pmagree but not compulsary. setting the target hardware during compile time may produce whats wanted. if the target supports fptan then you'll see it in the dissasembler.

author: jpelczar
author_rank: Contributor
timestamp: January 02, 2015, 09:20:44 am
content: You may also look at FreeBSD math library:https://svnweb.freebsd.org/base/head/lib/msun/src/https://svnweb.freebsd.org/base/head/lib/msun/src/s_sin.c?revision=218509&view=markuphttps://svnweb.freebsd.org/base/head/lib/msun/src/k_sin.c?revision=218509&view=markup

author: westfw
author_rank: Super Contributor
timestamp: January 02, 2015, 10:00:47 am
content: QuoteIt looks to me like the newlib nano libraries and the freebsd libraries are essentially the same old Sun code.

author: kody
author_rank: Contributor
timestamp: January 03, 2015, 02:01:20 am
content: Thanks for the links @jpelczar. Do you think the implementation would be same through different compilers/vendors?Quote from: jpelczar on January 02, 2015, 09:20:44 am

author: kody
author_rank: Contributor
timestamp: January 03, 2015, 02:03:08 am
content: @dannyf- could you please expand more on how the delisting and the counting of the instruction cycles can be done?Quote from: dannyf on December 31, 2014, 02:11:45 pm

author: tggzzz
author_rank: Super Contributor
timestamp: January 03, 2015, 09:25:55 am
content: Quote from: kody on January 03, 2015, 02:03:08 amEspecially if the processor has a cache

author: andersm
author_rank: Super Contributor
timestamp: January 03, 2015, 11:03:11 am
content: There are several options:- Use a high-frequency counter. The simplest, and works on any chip. On many MCUs you can have timers ticking at the CPU frequency or f/2.- Use tracing. Both the MCU and your development tools have to support this.- Use performance counters. Many MCUs have these nowadays, and they can count instruction cycles, memory access cycles and all kinds of things.The ARMv7-M DWT (Data Watchpoint and Trace unit) has both a cycle count timer and performance counters that can be used by software running on the MCU. Although it is optional, I would expect that all Cortex-M4 MCUs have it.

author: 0xdeadbeef
author_rank: Super Contributor
timestamp: January 03, 2015, 11:20:36 am
content: Quote from: tggzzz on January 03, 2015, 09:25:55 amObviously, a real measurement will always differ due to interrupts, pipeline effects, branch prediction, cache, waitstates, DMA blocking the bus or RAM etc.Anyway, looking at the code will make it possible to better estimate the number of cycles needed. As stated above, even looking at C code for a "fast" tangens implementation allows to say this will need > 100 cycles. With the actual source code the prediction will be better and with the ASM code, it can be quite accurate - if you don't consider the complex runtime effects discussed above.

author: tggzzz
author_rank: Super Contributor
timestamp: January 03, 2015, 04:50:57 pm
content: Quote from: 0xdeadbeef on January 03, 2015, 11:20:36 amEven 20 years ago, measurements on an i486 with its tiny cache doing nothing else, there was a measured 10:1 difference between mean and maximum times. Modern processors have much faster clocks,but DRAM memory latency hasn't changed. Processors have much bigger caches and are more dependent on them to reduce theaveragememory latency. Naturally caches cannot change the maximum latency.Hence the maximum:mean ratio has increasedsignificantlyand predicted execution times are even less valid than before.Remember the truism "cache is the new RAM, RAM is the new disk"

author: 0xdeadbeef
author_rank: Super Contributor
timestamp: January 03, 2015, 04:57:27 pm
content: The situation is a little different on microcontrollers. Some still don't have any cache at all, some have very simple implementations, only the high end controllers have complex ones.Generally, the internal SRAM is usually not cached. Cache is mainly needed to improve performance when running from flash. Note that fetching instructions from flash is a bottleneck for most faster microcontrollers. They usually use a burst read to fill a whole cache line but if there are are lot of branches and/or bad branch prediction, a cache miss can be a big performance hit.

author: mikerj
author_rank: Super Contributor
timestamp: January 03, 2015, 05:00:02 pm
content: Quote from: kody on December 30, 2014, 11:46:43 pmYou could use a simulator if one was available, but I don't think CoIDE includes this functionality? You could use the demo version of Keil etc. if you code fits into the space limitations.

author: tggzzz
author_rank: Super Contributor
timestamp: January 03, 2015, 05:56:03 pm
content: Quote from: 0xdeadbeef on January 03, 2015, 04:57:27 pmYes, as I implied in my first response.OTOH, many microcontrollers have already surpassed the i486 in terms of cache. The current microcontroller I am using, in a Zynq FPGA, is a dual-core Arm-A9, each core having 32K=32K I+D cache. (The cheapest ARM is, IIRC costs <$1) That trend will continue, although there will always be some MCUs that don't have/need cache.More interestingly, someactivelyavoid cache due to its "poor" behaviour in hard realtime systems, e.g. the very small and cheap XMOS processors with 2-10 cores.http://www.digikey.co.uk/product-search/en/integrated-circuits-ics/embedded-microcontrollers/2556109?k=xmosThose XMOS processors are the only ones I know where the compiler/IDEguaranteesthe execution time. With all other processors, all bets are off.

author: gmb42
author_rank: Frequent Contributor
timestamp: January 03, 2015, 07:12:56 pm
content: In a post,here, RedHat explain how they've improved the performance of some math functions in glibc. Eventually I suppose these will filter down to newlib\nanolib etc.