Skip to content

tests/periph_gpio: added benchmark capabilities#8040

Merged
kaspar030 merged 3 commits intoRIOT-OS:masterfrom
haukepetersen:add_bench_periphgpiototest
Feb 19, 2018
Merged

tests/periph_gpio: added benchmark capabilities#8040
kaspar030 merged 3 commits intoRIOT-OS:masterfrom
haukepetersen:add_bench_periphgpiototest

Conversation

@haukepetersen
Copy link
Copy Markdown
Contributor

alternative to #7478

Instead of adding a dedicated benchmark application this PR simply adds the same functionality as shell command to the existing periph_gpio test application (as done some time ago also for the periph_spi test). For convenience and potentially more advanced improvements I added also a make bench target using pexpect. This way one can (semi-) automatically run the benchmark on any platform.

I know there is a 1000 things that can be build upon this (and possible also improved), but I'd like to get this in in the current state for now and we can always improve this later. But it is quite useful already and I prefer this solution over #7478.

@haukepetersen haukepetersen added Area: drivers Area: Device drivers Area: tests Area: tests and testing framework labels Nov 15, 2017
#include "periph/gpio.h"
#include "xtimer.h"

#define BENCH_RUNS_DEFAULT (1000 * 1000UL)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be 1000UL * 1000

gpio_t pin = GPIO_PIN(atoi(argv[1]), atoi(argv[2]));
unsigned long runs = BENCH_RUNS_DEFAULT;
if (argc > 3) {
runs = (unsigned long)atoi(argv[3]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value needs to be checked (for >0). Otherwise, later on, this can lead to div by zero. (atio() returns 0 for non-number strings...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And maybe use atol() or atoll() so 16bitter can do more than 2^15?

unsigned state = irq_disable();
time = xtimer_now_usec();
for (unsigned long i = 0; i < runs; i++) {
__asm("nop");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__asm__, and maybe add volatile?

irq_restore(state);
bench_print_time(time, runs, "gpio_read");


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove extra spaces

state = irq_disable();
time = xtimer_now_usec();
for (unsigned long i = 0; i < runs; i++) {
int tmp = gpio_read(pin);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why save the return and then void it? does it prevent optimizing the function call away?

bench_print_time(time, runs, "gpio_write");

/* gpio_read */
state = irq_disable();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it, in this case, make sense to create a BENCHMARK(name, runs, command) macro?

@haukepetersen haukepetersen force-pushed the add_bench_periphgpiototest branch from 4abcba6 to d823ff1 Compare December 20, 2017 10:33
@haukepetersen
Copy link
Copy Markdown
Contributor Author

Addressed comments and introduced an independent benchmark module for running this type of trivial function timing benchmarks. This makes the code much nicer to read, indeed.

Making use of the benchmak modules in other tests (e.g. periph_spi) is open for follow up PRs...

@jnohlgard
Copy link
Copy Markdown
Member

I have been thinking about something similar to this benchmark module using the Cortex-M systick timer to measure actual cycles. However, that would be a platform specific hack if I ever get around to implementing it. It could be useful to be able to measure the overhead in ISRs or other low level functionality.

@haukepetersen
Copy link
Copy Markdown
Contributor Author

I think for the Cortex tick counter, it would make sense to write a (sub) module to the cortexm_common code, which allows to use this capability in an easy way. This would indeed be very useful thing!

@haukepetersen haukepetersen force-pushed the add_bench_periphgpiototest branch from d823ff1 to 2bfdade Compare January 23, 2018 11:08
@haukepetersen
Copy link
Copy Markdown
Contributor Author

rebased.

@kaspar030 what do you say?

Copy link
Copy Markdown
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the benchmark print function needs to use stdint types. Other than that, looks good. will do a test run now.

uint32_t div = (time - (full * runs)) / (runs / 1000);

printf("%11s: %9luus --- %2u.%03uus per call\n", name,
(unsigned long) time, (unsigned)full, (unsigned)div);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better use PRIu32 et al ...

* @}
*/

#include <stdio.h>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and below: usually we put a new line after system headers

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually do this, too, but in cases where there is only a small (roughly up to 2 or 3 ) includes in a file I tend to put them in a single block, as I think its quite ugly to have a single include per 'newline separated block'... But will fix this here to make you happy :-)

@kaspar030
Copy link
Copy Markdown
Contributor

Tested, works flawlessly. Feel free to directly squash the printf fixes.

@haukepetersen
Copy link
Copy Markdown
Contributor Author

rebased, squashed, and fixed style and printf issues pointed out above.

Copy link
Copy Markdown
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK.

@haukepetersen haukepetersen added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jan 29, 2018
@haukepetersen
Copy link
Copy Markdown
Contributor Author

triggered Mudock (forgot earlier...)

@haukepetersen haukepetersen force-pushed the add_bench_periphgpiototest branch from 0262530 to 563002a Compare January 29, 2018 13:07
@haukepetersen
Copy link
Copy Markdown
Contributor Author

fixed style issues in the bench python script (as pointed out by the flake8 check). Bus something is broken now when running it, looking into it now.

@haukepetersen haukepetersen force-pushed the add_bench_periphgpiototest branch from 563002a to 542b4a9 Compare January 29, 2018 13:12
@haukepetersen
Copy link
Copy Markdown
Contributor Author

fixed, should be all good now.

@PeterKietzmann
Copy link
Copy Markdown
Member

nope, still not good:
tests/periph_gpio/main.c:221: style (unsignedLessThanZero): Checking if unsigned variable 'runs' is less than zero.

@haukepetersen
Copy link
Copy Markdown
Contributor Author

ups, missed that one.

This commit enables the GPIO benchmark to be run automatically
(through 'make bench') using pexpect.
@haukepetersen haukepetersen force-pushed the add_bench_periphgpiototest branch from 542b4a9 to 9b557d2 Compare January 31, 2018 12:55
@haukepetersen
Copy link
Copy Markdown
Contributor Author

next try (squashed fix right in)

@kaspar030
Copy link
Copy Markdown
Contributor

Let's go!

@kaspar030
Copy link
Copy Markdown
Contributor

I'll give travis another chance. Different cppcheck versions?

@kaspar030
Copy link
Copy Markdown
Contributor

I'll give travis another chance. Different cppcheck versions?

Yeah, and it complains about timex.h, thus unrelated.

@kaspar030 kaspar030 merged commit f59e824 into RIOT-OS:master Feb 19, 2018
@haukepetersen haukepetersen deleted the add_bench_periphgpiototest branch March 6, 2018 10:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: drivers Area: Device drivers Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants