Skip to content

Digitalio performance #1285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from

Conversation

projectgus
Copy link
Contributor

Last week I put together an alternative to the digitalWriteFast library for digitalRead/Write optimisations, and it got me thinking about the digitalRead/Write implementations in Arduino and opportunities for optimisation.

I read Issue 140 on the Google project and see that it was unmerged because "the complication of providing two separate versions of the pin mapping seem like a bigger burden than the potential benefit"

This version doesn't require two copies of each pin mapping. The pin mapping macros are changed, but there's no duplication. In fact there's only 130 additional lines of code.

pinMode, digitalRead & digitalWrite will all automatically inline whenever the pin number is known at compile time.

Statistics

Before

In the current Arduino library I measured a digitalWrite() at approx 107 clock ticks (6.74us @ 16Mhz.) The digitalWrite function takes up 8 bytes in flash for each time it is called, plus 108 bytes for the implementation.

After

With this change, many pins can digitalWrite() a constant value in 2 clock ticks (125ns.) The single sbi instruction takes up 2 bytes in flash.

If the pin supports PWM, the operation takes 7 clock ticks (437ns) due to setting the timer register to turn off possible PWM. Each digitalWrite() takes up 8 bytes in flash.

For some pins on the Mega, that require a read/modify/write cycle (ie no sbi support), the operation takes 17 clock ticks (~1us) and takes up 26 bytes of flash, in part due to the need to disable interrupts.

For instances where the pin is not known at compile time, the digitalWrite() function takes approx 112 clock ticks (~7us.) The digitalWrite function takes up 8 bytes in flash for each time it is called, plus 100 bytes for the implementation (ie nearly identical to the current implementation in these cases.)

Advantages

  • Transparently improves performance where possible, obsoletes libraries like digitalWriteFast.
  • No duplication of pin mapping data.
  • Optimised cases take up less flash space, except possibly when using some pins on the Mega (flash is more plentifully available on the Mega, though!)
  • Uses inline functions almost exclusively over macros, so better type safety and error messages. :)

Disadvantages

  • Doesn't inline library functions where the pin numbers are set in the constructor and the implementation is compiled in a separate file (as per comment #12 on Issue 140.) I have some ideas about possible techniques to deal with this, but I haven't tried them out yet.
  • Will break any third party board profiles that ship their own pins_arduino.h. I don't know how common this is. It would be possible to make this technique backwards compatible to older pins_arduino.h files without too much extra complexity, but I thought this might be feature-itis unless anyone feels otherwise.

Has been tested with gcc 4.7 (Linux) and gcc 4.3.2 (Windows.)

What do you think? Please let me know if there's anything else these changes need or could use. :)

@ffissore ffissore added the New label Feb 27, 2014
@ArduinoBot
Copy link
Contributor

Can I build this pull request?

@projectgus
Copy link
Contributor Author

Hi ArduinoBot,

I think this is probably better off getting closed as abandoned. It was just an idea I had, and didn't appear to have any traction, and the code base has moved on a lot in 18 months.

Also with the new gcc versions being put into 1.5 it may be possible to use Link Time Optimisation and other tricks to make some of this "cleverness" (aka hackiness) redundant and still get nicely optimised output.

Angus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants