Trig functions executing very slowly
Mauvai
Posts: 45
I have an attitude and heading system, using the code detailed below.
A class was defined which operates the sparkfun 9dof (https://www.sparkfun.com/products/10724), reads from its chips using i2c, and process the data (get tilt, heading, etc).
Based on using standard i2c, I was expecting to see a refresh rate of perhaps 60Hz (200Hz maximum, based on 100KHz i2c, divided by 3 for 3 chips) - what i got was closer to 20Hz (i.e 5ms per read cycle). Removing the trig functions (as i have form the attached files, should anyone choose to peruse them) brought it back to about 60Hz.
Is it typical for 5-6 trig functions to take ~3.4ms to run? even at 80Mhz?
Could this be improved by running a function inside a separate core? (unlikely, seeing as it has to fetch new values from main ram every cycle...)
Potential other problems for slow performance:
Final question: We have an Arduino, executing similar code to fetch values form the sensor stick - no trig. It appears to be able to sample from all 3 at 200Hz (where i only get 60) - is there a reasonably reason behind this (bad code, bad libraries, etc.) or is the value likely wrong?
dof_class.cpp
dof_class.h
Full_AHRS.cpp
A class was defined which operates the sparkfun 9dof (https://www.sparkfun.com/products/10724), reads from its chips using i2c, and process the data (get tilt, heading, etc).
Based on using standard i2c, I was expecting to see a refresh rate of perhaps 60Hz (200Hz maximum, based on 100KHz i2c, divided by 3 for 3 chips) - what i got was closer to 20Hz (i.e 5ms per read cycle). Removing the trig functions (as i have form the attached files, should anyone choose to peruse them) brought it back to about 60Hz.
Is it typical for 5-6 trig functions to take ~3.4ms to run? even at 80Mhz?
Could this be improved by running a function inside a separate core? (unlikely, seeing as it has to fetch new values from main ram every cycle...)
Potential other problems for slow performance:
- Using a class
- Over use of functions to do things
- Using struct to box xyz data
- Not running class in a separate core (this is planned)
Final question: We have an Arduino, executing similar code to fetch values form the sensor stick - no trig. It appears to be able to sample from all 3 at 200Hz (where i only get 60) - is there a reasonably reason behind this (bad code, bad libraries, etc.) or is the value likely wrong?
dof_class.cpp
dof_class.h
Full_AHRS.cpp
Comments
Do you know what frequency that I2C protocol actually runs? I took a 15 second perusal through the Simple source code and I didn't see any delays in there - which makes me think that even in LMM mode, it runs so slow that author figured no extra delay was needed.
Maybe someone else can chime in that knows Simple's I2C frequency. If it's too slow, you may need to look at another I2C implementation.
Glad to see another C++ user. Don't worry about object orientation bogging you down. You're doing great. libpropeller and PropWare (I think OmniaCreator uses C++ too?) are both excellent examples of how you can use C++ classes without sacrificing speed or code size.
http://forums.parallax.com/showthread.php/157270-Propeller-9-DOF-Experimenter-board-%E2%80%93-LIMITED-QUANTY/page3
I won't go in to all the details. But if you desire to use a Propeller, it may be best to follow his lead. There are other examples that work, but not so well.
I couldn't find this code in the thread anywhere - can someone provide a link?
Twas a good point, but after some research i discovered that sin and so on are overloaded in cpp to take floatt arguments, return float answers, so im assuming all the computation is in floats ( I was always passing float arguments). either way i tried switching to sinf , atan2f, and so on, but there was no performance increase - 50ms for all the trig, of which 17ms is for i2c. 32bit doubles is specified by the checkbox compiler options.
My current plan is to linearize most of the trig around 0, as that will be the operating point. Also probably run it in a new cog.
I believe it runs at close to 100kHz - it would be consistent with out results. probably around the 95k mark. I read somehwere (i cant find it again anywhere) that the max you can read from a chip with 100k i2c is 200Hz - we seems to be getting about 180. A new i2c protocol is certainly something im going to look into - preferably one with fast i2c.
A final, unrelated question: Is "extern volatile" a bad thing? I seem to have globals that i need access to outside my class...