Page 3 of 4

Re: Matrix library for MicroPython

Posted: Wed Aug 22, 2018 4:42 pm
by Roberthh
I tried something like "c=a/b" with all variants of viper, native and plain python (viper as c=a * (b ** -1)
The viper version of division is the slowest. native code is like 60% faster than plain python. Embedding the division into a inversion functions offer no gain, because calling a function takes time too, which makes it even worse.

Re: Matrix library for MicroPython

Posted: Wed Aug 22, 2018 4:53 pm
by Roberthh
Some more trials:
a single inverse() call does not affect the speed gain of viper in the other operations. I used a float multiply for tests instead. However, the speed advantage for float operations compared to native code is not really big.
Viper 3.1 µs
native 5.5 µs
plain: 8 µs
Since the test also include the test loop, it may be none. So using the native decorators with unchanged code may be the most effective improvement.
The speed advantage of viper code for integer operations is huge.
Edit: Modifying the test a little bit to put more weight on the computation instead of the loop control brings viper and native close together at the level of the viper code.
Viper: 2.93 µs
Native: 3.2 µs
Plain: 5.14 µs

Re: Matrix library for MicroPython

Posted: Wed Aug 22, 2018 6:13 pm
by jickster
Roberthh wrote:Some more trials:
a single inverse() call does not affect the speed gain of viper in the other operations. I used a float multiply for tests instead. However, the speed advantage for float operations compared to native code is not really big.
Viper 3.1 µs
native 5.5 µs
plain: 8 µs
Since the test also include the test loop, it may be none. So using the native decorators with unchanged code may be the most effective improvement.
The speed advantage of viper code for integer operations is huge.
Why would float speed gain be so much lower compared to int speed gain?

Re: Matrix library for MicroPython

Posted: Wed Aug 22, 2018 6:22 pm
by Iyassou
Roberthh wrote:
Wed Aug 22, 2018 4:53 pm
So using the native decorators with unchanged code may be the most effective improvement.
I just tried the inverse and __add__ functions with nothing different other than the micropython.native decorator and the time savings were about 0.1 ms for both, nothing monumental.

Re: Matrix library for MicroPython

Posted: Wed Aug 22, 2018 6:51 pm
by Roberthh
Tried the same & agree. Also for __add__, the viper decorator leads to a compiler error, requiring more changes.
Trivial lesson learned. Viper & native code is not always a method for gaining speed.

Matrix library for MicroPython

Posted: Wed Aug 22, 2018 9:08 pm
by jickster
Iyassou wrote:
Wed Aug 22, 2018 6:22 pm
Roberthh wrote:
Wed Aug 22, 2018 4:53 pm
So using the native decorators with unchanged code may be the most effective improvement.
I just tried the inverse and __add__ functions with nothing different other than the micropython.native decorator and the time savings were about 0.1 ms for both, nothing monumental.

You seem to care a lot about time savings.
Coding in C is going to give you the maximum time savings but then you have to combine it with the firmware.

They’re working on being able to execute an .obj within an already compiled virtual machine.

Re: Matrix library for MicroPython

Posted: Thu Aug 23, 2018 5:13 am
by Iyassou
jickster wrote:
Wed Aug 22, 2018 9:08 pm
You seem to care a lot about time savings.
Just wanted it to go as fast as possible :)
jickster wrote:
Wed Aug 22, 2018 9:08 pm
Coding in C is going to give you the maximum time savings
The part about adding your module to the firmware is clear, it's writing the library in C that seems daunting to me. As I've said before, I'm not proficient in C and will probably either give up or finish this much later in the future.
jickster wrote:
Wed Aug 22, 2018 9:08 pm
They’re working on being able to execute an .obj within an already compiled virtual machine.
What does this mean?

Re: Matrix library for MicroPython

Posted: Thu Aug 23, 2018 6:07 am
by pythoncoder
Iyassou wrote:
Thu Aug 23, 2018 5:13 am
...
What does this mean?
Dynamically loadable modules. You would be able to write a module in C and compile it. You would then be able to import it at runtime. At present you have to compile it into the build, and re-flash the firmware.

For the ultimate in speed (at the cost of making the module STM-specific) you could use the inline assembler ;) It does floating point arithemtic like a bat out of hell...

Re: Matrix library for MicroPython

Posted: Thu Aug 23, 2018 4:04 pm
by jickster
Iyassou wrote:
Thu Aug 23, 2018 5:13 am
jickster wrote:
Wed Aug 22, 2018 9:08 pm
Coding in C is going to give you the maximum time savings
The part about adding your module to the firmware is clear, it's writing the library in C that seems daunting to me. As I've said before, I'm not proficient in C and will probably either give up or finish this much later in the future.
It may be possible to do this incrementally.

If it's possible to inherit in `.py` from a C-native class - should be? - then you should be able to incrementally port your class to C.
By incrementally I mean: instead of having to transform everything in C in order to test it, you could do one function at a time.

To practice, I wouldn't start with your matrix class but create a super basic class to practice on.

Code: Select all

class basic:
	def ret0(self):
		return 0
	def ret1(self):
		return 1
Then create the native version `native_basic` in C and move one function, `ret0`, to the native implementation.
Then in `.py` inherit remove the definition of `ret0`:

Code: Select all

import native_basic		
class basic(native_basic):	
	def ret1(self):
		return 1
And test;

Code: Select all

a = basic()
print(a.ret0())
It should work if inheritance from native to `.py` works.

Re: Matrix library for MicroPython

Posted: Fri Aug 24, 2018 7:57 pm
by efahl
Just an aside, what are you using these 3x3 matrices for? If they are 3D spatial transformations, then the matrix is orthonormal and its inverse is also its transpose. Our multibody dynamics code uses this to good advantage, and we have also added multiply_inverse and divide_inverse methods on the matrix class so we don't even take the transpose, we just flip the order of evaluation in the inner loop, resulting in enormous speed improvements over actually calculating inverses.