Python / GPIO speed


15 posts
by texy » Mon Jul 02, 2012 6:37 am
Hi,
as you can see from my limited LCD screen threads, it seems that python is very slow when it comes to GPIO access.
If you run equivalent code in C, it runs so much faster.
So the question is, is it because python is slow, or that the RPi.GPIO driver implementation is slow?

Texy
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2402
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by tenspot » Mon Jul 02, 2012 9:01 am
The speed difference is because Python is an interpreted language and C is compiled. Generally compiled code runs much faster.
An advantage of an interpreted language is that you can execute single commands or blocks of code “on the fly” to try things out. Whereas with C you would have to go through the compile/link/run cycle, which can be slower.
Posts: 4
Joined: Sun Jun 03, 2012 2:15 pm
by MadCow42 » Mon Jul 02, 2012 7:47 pm
Actually, it's a bit of both. The RPi.GPIO implementation is very easy to use, and very simple - but it's not nearly optimized for speed (yet). Plus, it accesses the GPIO system through reading/writing to the system files under /sys/class/gpio/...

Example: each call to GPIO.output() opens the file, writes to it, and then closes it again. Repeated calls means the file is opened/closed each time. I've written a very short class object that holds the files in pre-opened state for multiple writes, increasing performance somewhere around 5x. I'll be testing that a bit more tonight, but intend to submit it as an improvement for the RPi.GPIO module if Ben Croston will add it in (otherwise I'll simply share it separately - but it's not rocket science).

I'm sure there are other optimizations available too, but 5x for very little work here is a good start.
Posts: 86
Joined: Sun Jul 01, 2012 12:48 am
by texy » Mon Jul 02, 2012 9:02 pm
Oh good. Look forward to it. What about this wiringPi driver ?
Out of time today, it's the next thing to look at.
T.
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2402
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by croston » Mon Jul 02, 2012 9:26 pm
MadCow42 wrote:Actually, it's a bit of both. The RPi.GPIO implementation is very easy to use, and very simple - but it's not nearly optimized for speed (yet). Plus, it accesses the GPIO system through reading/writing to the system files under /sys/class/gpio/...

Example: each call to GPIO.output() opens the file, writes to it, and then closes it again. Repeated calls means the file is opened/closed each time. I've written a very short class object that holds the files in pre-opened state for multiple writes, increasing performance somewhere around 5x. I'll be testing that a bit more tonight, but intend to submit it as an improvement for the RPi.GPIO module if Ben Croston will add it in (otherwise I'll simply share it separately - but it's not rocket science).

I'm sure there are other optimizations available too, but 5x for very little work here is a good start.


I originally tried the method of keeping the files open and it didn't work for me reliably at the time. This is why the files are opened and closed every time in the current release. I am however working on a new release which uses the control registers in memory instead of the kernel. This way there will be a lot more control such as edge detection.
User avatar
Posts: 450
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
by texy » Mon Jul 02, 2012 9:35 pm
How much faster, that is the question ;-)
Texy
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2402
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by MadCow42 » Tue Jul 03, 2012 1:12 am
croston wrote:I originally tried the method of keeping the files open and it didn't work for me reliably at the time. This is why the files are opened and closed every time in the current release. I am however working on a new release which uses the control registers in memory instead of the kernel. This way there will be a lot more control such as edge detection.


Interesting - how did the reliability show itself in your testing? I haven't hooked it up to a scope (or closed loop on an input GPIO) to be sure, but I haven't had any errors. It's certainly making my LED's light up as expected, but I can't really tell if they're strobing at 9kHz or just on solid. :)

The class I wrote is actually showing 10x improvement from the standard open/close for each write method. I absolutely agree that the direct register access would be best in the long term, but the current interface is very easy to use and a great place to start (thanks for the work on it!).

I've posted the class test module at: www.cazabon.com/temp/GPIO_OUT_class.py

My results are as follows:

pi@raspberrypi:~/softwareTesting$ sudo python GPIO_OUT_class.py
10000 writes using standard output method: 5.38122606277 seconds (929.156281798 Hz)

10000 writes using GPIO_OUT class output method: 0.523293018341 seconds (9554.87618744 Hz)

Improvement: 928.338975329 %


Kevin.
Posts: 86
Joined: Sun Jul 01, 2012 12:48 am
by gadgetoid » Tue Jul 03, 2012 1:22 pm
To test WiringPython, which accesses GPIO using shared-memory ( requires root ) I hacked WiringPython into GPIO_OUT_class.py and added an additional test:

10000 writes using standard output method: 6.21796417236 seconds (804.121712734 Hz)

10000 writes using GPIO_OUT class output method: 0.589258909225 seconds (8485.23445589 Hz)

10000 writes using WiringPython: 0.0959978103638 seconds (52084.5213141 Hz)

At the moment, if you're willing to sacrifice security you can gain a whole lot of performance.

I'm no Python expert; so if anyone wants to independently verify this, please do.
Posts: 74
Joined: Wed Mar 07, 2012 9:58 pm
by MadCow42 » Tue Jul 03, 2012 1:54 pm
gadgetoid wrote:10000 writes using WiringPython: 0.0959978103638 seconds (52084.5213141 Hz)

At the moment, if you're willing to sacrifice security you can gain a whole lot of performance.


Wow, that's smokin'. :)

I'll have to look deeper. I haven't even looked at WiringPython, but maybe it's easy enough to simply extract the part that's communicating with the GPIO on its own (I'm not sure what else WiringPython does). Another 6x performance over what I have done is pretty impressive.

Kevin.
Posts: 86
Joined: Sun Jul 01, 2012 12:48 am
by texy » Tue Jul 03, 2012 2:10 pm
gadgetoid wrote:To test WiringPython, which accesses GPIO using shared-memory ( requires root ) I hacked WiringPython into GPIO_OUT_class.py and added an additional test:

10000 writes using standard output method: 6.21796417236 seconds (804.121712734 Hz)

10000 writes using GPIO_OUT class output method: 0.589258909225 seconds (8485.23445589 Hz)

10000 writes using WiringPython: 0.0959978103638 seconds (52084.5213141 Hz)

At the moment, if you're willing to sacrifice security you can gain a whole lot of performance.

I'm no Python expert; so if anyone wants to independently verify this, please do.


Lookin' good! Any chance you could give access to the updated code please?

T.
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2402
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by gadgetoid » Tue Jul 03, 2012 2:18 pm
texy wrote:Lookin' good! Any chance you could give access to the updated code please?


WiringPython is a Python-wrapped version of Gordon's WiringPi C/C++ library, which you can get from here: https://github.com/Gadgetoid/WiringPython
Posts: 74
Joined: Wed Mar 07, 2012 9:58 pm
by texy » Tue Jul 03, 2012 2:27 pm
You modifed the code here :
http://www.cazabon.com/temp/GPIO_OUT_class.py

to give you extra timings with the WiringPython class. I was asking for the modified code ;)

T.
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2402
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by gadgetoid » Tue Jul 03, 2012 3:44 pm
Ahh that code!

You can find it here: http://pi.gadgetoid.co.uk/GPIO_OUT_class.py
Posts: 74
Joined: Wed Mar 07, 2012 9:58 pm
by texy » Sat Jul 07, 2012 8:33 am
Hi,
just to confirm, using the additional GPIO_OUT class in a real world situation, driving a pcd8544 Nokia display there is a reduction from 14.2 seconds to 1.24 seconds for the initialisation and initial 'hello world' message. See thread here :
viewtopic.php?f=32&t=9814

Many thanks to all involved,
Next job is to get wiringpi working.

Texy
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2402
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by MadCow42 » Sat Jul 07, 2012 3:26 pm
texy wrote:Hi,
just to confirm, using the additional GPIO_OUT class in a real world situation, driving a pcd8544 Nokia display there is a reduction from 14.2 seconds to 1.24 seconds for the initialisation and initial 'hello world' message. See thread here :
viewtopic.php?f=32&t=9814

Many thanks to all involved,
Next job is to get wiringpi working.

Texy


I love this stage in any new technology... so much room to play and improve things! :)
Posts: 86
Joined: Sun Jul 01, 2012 12:48 am