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
Python / GPIO speed
15 posts
"!.8inch TFT LCD + Switch Shield" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
- Moderator
- Posts: 1277
- Joined: Sat Mar 03, 2012 10:59 am
- Location: Berkshire, England
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.
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: 3
- Joined: Sun Jun 03, 2012 2:15 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.
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: 73
- Joined: Sun Jul 01, 2012 12:48 am
Oh good. Look forward to it. What about this wiringPi driver ?
Out of time today, it's the next thing to look at.
T.
Out of time today, it's the next thing to look at.
T.
"!.8inch TFT LCD + Switch Shield" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
- Moderator
- Posts: 1277
- Joined: Sat Mar 03, 2012 10:59 am
- Location: Berkshire, England
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.
How much faster, that is the question 
Texy
Texy
"!.8inch TFT LCD + Switch Shield" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
- Moderator
- Posts: 1277
- Joined: Sat Mar 03, 2012 10:59 am
- Location: Berkshire, England
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: 73
- Joined: Sun Jul 01, 2012 12:48 am
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.
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: 72
- Joined: Wed Mar 07, 2012 9:58 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: 73
- Joined: Sun Jul 01, 2012 12:48 am
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.
"!.8inch TFT LCD + Switch Shield" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
- Moderator
- Posts: 1277
- Joined: Sat Mar 03, 2012 10:59 am
- Location: Berkshire, England
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: 72
- Joined: Wed Mar 07, 2012 9:58 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.
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.
"!.8inch TFT LCD + Switch Shield" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
- Moderator
- Posts: 1277
- Joined: Sat Mar 03, 2012 10:59 am
- Location: Berkshire, England
- Posts: 72
- Joined: Wed Mar 07, 2012 9:58 pm
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
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
"!.8inch TFT LCD + Switch Shield" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=59&t=40674
50p goes to the Foundation
- Moderator
- Posts: 1277
- Joined: Sat Mar 03, 2012 10:59 am
- Location: Berkshire, England
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: 73
- Joined: Sun Jul 01, 2012 12:48 am