Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- Community Forums
- :
- Forums
- :
- Embedded Software Development
- :
- Embedded Development Tools
- :
- Time taken for execution of trigonometric function...

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

leo_skadoosh23

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-10-2019 09:14 AM

868 Views

Registered:
06-03-2019

Hello everyone,

I have a few Interrupt service routines in my C program. Each of these uses math functions, sqrt() and asin(), both a couple of times. I faced some glitches in my code operation but couldn't find the reason until the I measured the total execution time of the ISR. It was 5 us each which is HUGE. I tried to reduce the calculations as much as possible but couldn't reduce this execution time significantly.

Is there a way to optmize the math functions to save time? Or is there any other solution to this issue?

Thank you.

Best regards,

Pramod

1 Solution

Accepted Solutions

ericv

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-11-2019 12:30 PM

745 Views

Registered:
04-13-2015

To use loook-up tables you have to remap your input between 0 and N-1 (N being the size of the table, idealy a power of 2). For asin(), it is the simplest because the input is bounded between -1.0 and +1.0 and asin(-x) == -asin(x). If the input is negative, memo it is and use -x. The input value is multiplied by N-1, giving you the index in the table. The larger the table, the more resolution/precision your result will have; you can also interpolate between Idx & Idx+1 using the remainder, i.e. input * (N-1) % 1. Then use - table value if the inpur was -ve.

For sqrt(), the idea is alike, except sqrt(4n) == 2*sqrt(n). By bringing the input between 0. and 4.0-epsilon (memorizing the scaling factor used, divided by 2) you read the table with the index (ScaledInput * N-1) and then apply the scaling factor / 2.

I assume your input and output are integers, if so, then all these manipulations can done with int meaning almost no CPU as they involve shfts and mutiplfy (for sqrt) if you play a bit with the size of the table, or index remapping or special handling when the index would be N. As for how to create the tables, look at what the indexes are vs the value used to determine the index and generate the tables accordingly.

6 Replies

drjohnsmith

Teacher

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-10-2019 09:39 AM

855 Views

Registered:
07-09-2009

For a real time type system one would expect that all the ISR does is makes a note of the interrupt, along with any time stamp or such like,

Doing slow functions such as sqrt or sin, is generally not done in the interrupt, but the main loop.

You are lucky, this sort of interrupt problem is inherent, "whilst your interrupted, you can be missing interrupts", you need to design the system such that this doe snot affect how the system runs, you can not rely upon the interrupt being fast. No matter how fast, with random interrupt,s at some point you are going to have a situation where your in an interrupt and another happens,

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>

ericv

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-10-2019 06:40 PM

808 Views

Registered:
04-13-2015

I agree with @drjohnsmith for using trigonometrics in an interrupt.. As for your question(s): *"Is there a way to optmize the math functions to save time? Or is there any other solution to this issue?"*. Likely, but more details should be provided.

The ubiquitous solution, if a high precision is not required, is to use look-up tables for these functions. Else, if a high precision is required, then you'll have to get your hands dirty by writing your own, either using low order polynomial approximation or with Cordic iterations using just a few iterations.

leo_skadoosh23

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-11-2019 06:40 AM - edited 12-11-2019 06:42 AM

768 Views

Registered:
06-03-2019

Hello @drjohnsmith ,

Thank you for your answer. ISRs in my code are used for control and modulation of a converter as I need to update variables synchronous to all the ISRs. My main loop has bare minimum calculations. There is no way around for me but to make these calculations in these interrupts. I had read that these PL-PS interrupts are queued up until they are executed. Also, I am not worried if I lose a lower priority interrupt but my higher priority interrupt gets executed.

Hello @ericv ,

Could you tell me what more details are needed? I did think of using look-up tables but I had no idea how much faster they are compared to the math functions.

ericv

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-11-2019 12:30 PM

746 Views

Registered:
04-13-2015

To use loook-up tables you have to remap your input between 0 and N-1 (N being the size of the table, idealy a power of 2). For asin(), it is the simplest because the input is bounded between -1.0 and +1.0 and asin(-x) == -asin(x). If the input is negative, memo it is and use -x. The input value is multiplied by N-1, giving you the index in the table. The larger the table, the more resolution/precision your result will have; you can also interpolate between Idx & Idx+1 using the remainder, i.e. input * (N-1) % 1. Then use - table value if the inpur was -ve.

For sqrt(), the idea is alike, except sqrt(4n) == 2*sqrt(n). By bringing the input between 0. and 4.0-epsilon (memorizing the scaling factor used, divided by 2) you read the table with the index (ScaledInput * N-1) and then apply the scaling factor / 2.

I assume your input and output are integers, if so, then all these manipulations can done with int meaning almost no CPU as they involve shfts and mutiplfy (for sqrt) if you play a bit with the size of the table, or index remapping or special handling when the index would be N. As for how to create the tables, look at what the indexes are vs the value used to determine the index and generate the tables accordingly.

ericv

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-11-2019 01:31 PM

733 Views

Registered:
04-13-2015

2 corrections for sqrt():

- the scaling factor to apply is sqrt(scaling) and not divided by 2. sqrt(scaling) is easy to calclated using int because for every >>4 f te input, the scaling factor is incremented by 1 (starting at 1.0).

- the index is scaledinput *(N-1)/4 and not scaldeinput*(N-1) because the entry at N-1 is 4.0.

leo_skadoosh23

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

12-16-2019 01:24 AM

659 Views

Registered:
06-03-2019

Thank you Eric. I will try and see if the implementation of look-up tables helps/is necessary.