Hello,
I create in my setup a long array, like:
int unsigned x[1000];
void setup() {
for(int n=0; n<1000; n = n+1){
x[n] = n*n;
}
}
After its creation, the array remains unchanged.
However the code is quite slow, probably due to the fact that the x array is quite long and it is a variable.
Therefore after the "for" loop (i.e. the computation of each value of x array), I want to convert "x" from a variable into a contstant. How to do it?
Thank you and best regards.
Print the values to serial monitor. Copy and paste into a const array in the IDE.
You are dealing with an unsigned int array and sin values.
The expression sin(f_signal * n) gives allways a value in the range -1.0 to +1.0.
The conversion int(...) generates so always 0.
A possible solution: Use a float or double array.
You are right Rudolf. Anyhow it was a simple code to help you to understand better the problem. Now I changed the main post to fix the problem that you found. Thanks!
I use Excel to generate some of my code. Do all the calculation, formatting and even semicolons in the cell formulae. Then copy-paste to a .h file.
PROGMEM is your friend.
Which Arduino board are you using ?
However the code is quite slow, probably due to the fact that the x array is quite long and it is a variable.
Do you mean that populating the array is slow or that accessing it is slow ?
Would making it a const really make accessing the data faster and if so, why ?
How exactly are you accessing it ?
Which Arduino board are you using ?
Arduino DUE
How exactly are you accessing it ?
I am using the array x as duty cycle for create a PWM signal.
Every time I update the duty cycle of the PWM, I select one element of x array: x[n]
I am already using port manipulation to increase the speed of the code but it is still slow.
So how will having the array as a 'const' make it faster?
However the code is quite slow, probably due to the fact that the x array is quite long and it is a variable.
Why do you think this? Array access with an index variable is optimally fast, and the const and variable arrays are both in SRAM.
Array access with an index variable is optimally fast, and the const and variable arrays are both in SRAM.
Thank you cattledog for your clarification. I thougth that using const could help to speed-up the code. I will perform other optimization instead of using const.
Regards.
PieterP
October 14, 2019, 7:24pm
11
I don't think the array is the cause of the performance issues here, but anyway, for future reference:
The latest version of the Arduino AVR Core comes with GCC 7, which supports a large portion of C++17, including for-loops in constexpr
functions. This allows you to populate an array at compile time.
For example, here's a sketch that populates an array with samples of a sine wave. The first version uses a regular variable and a for-loop, while the second version uses a constexpr array that is generated by a constexpr immediately invoked lambda function.
The speed difference is immense, as expected:
When tested on an Arduino Leonardo, the first version takes 30692 microseconds at run time, and the second version takes no time at all (at run time).
[color=#5e6d03]template[/color] [color=#434f54]<[/color][color=#00979c]class[/color] [color=#000000]T[/color][color=#434f54],[/color] [b][color=#d35400]size_t[/color][/b] [color=#000000]N[/color][color=#434f54]>[/color]
[color=#00979c]struct[/color] [b][color=#d35400]Array[/color][/b] [color=#000000]{[/color]
[color=#000000]T[/color] [color=#000000]data[/color][color=#000000][[/color][color=#000000]N[/color][color=#000000]][/color][color=#000000];[/color]
[color=#000000]constexpr[/color] [color=#00979c]static[/color] [b][color=#d35400]size_t[/color][/b] [color=#d35400]length[/color] [color=#434f54]=[/color] [color=#000000]N[/color][color=#000000];[/color]
[color=#000000]constexpr[/color] [color=#000000]T[/color] [color=#434f54]&[/color][color=#00979c]operator[/color][color=#000000][[/color][color=#000000]][/color][color=#000000]([/color][b][color=#d35400]size_t[/color][/b] [color=#000000]index[/color][color=#000000])[/color] [color=#000000]{[/color] [color=#5e6d03]return[/color] [color=#000000]data[/color][color=#000000][[/color][color=#000000]index[/color][color=#000000]][/color][color=#000000];[/color] [color=#000000]}[/color]
[color=#000000]constexpr[/color] [color=#00979c]const[/color] [color=#000000]T[/color] [color=#434f54]&[/color][color=#00979c]operator[/color][color=#000000][[/color][color=#000000]][/color][color=#000000]([/color][b][color=#d35400]size_t[/color][/b] [color=#000000]index[/color][color=#000000])[/color] [color=#00979c]const[/color] [color=#000000]{[/color] [color=#5e6d03]return[/color] [color=#000000]data[/color][color=#000000][[/color][color=#000000]index[/color][color=#000000]][/color][color=#000000];[/color] [color=#000000]}[/color]
[color=#000000]}[/color][color=#000000];[/color]
[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]115200[/color][color=#000000])[/color][color=#000000];[/color]
[color=#5e6d03]while[/color] [color=#000000]([/color][color=#434f54]![/color][b][color=#d35400]Serial[/color][/b][color=#000000])[/color][color=#000000];[/color]
[color=#000000]{[/color]
[color=#00979c]auto[/color] [color=#000000]start[/color] [color=#434f54]=[/color] [color=#d35400]micros[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[b][color=#d35400]Array[/color][/b][color=#434f54]<[/color][color=#00979c]float[/color][color=#434f54],[/color] [color=#000000]200[/color][color=#434f54]>[/color] [color=#00979c]array[/color][color=#000000];[/color]
[color=#5e6d03]for[/color] [color=#000000]([/color][color=#00979c]uint16_t[/color] [color=#000000]i[/color] [color=#434f54]=[/color] [color=#000000]0[/color][color=#000000];[/color] [color=#000000]i[/color] [color=#434f54]<[/color] [color=#00979c]array[/color][color=#434f54].[/color][color=#d35400]length[/color][color=#000000];[/color] [color=#434f54]++[/color][color=#000000]i[/color][color=#000000])[/color]
[color=#00979c]array[/color][color=#000000][[/color][color=#000000]i[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#d35400]sin[/color][color=#000000]([/color][color=#000000]i[/color] [color=#434f54]*[/color] [color=#00979c]PI[/color] [color=#434f54]/[/color] [color=#000000]100.0[/color][color=#000000])[/color][color=#000000];[/color]
[color=#00979c]auto[/color] [color=#d35400]end[/color] [color=#434f54]=[/color] [color=#d35400]micros[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#d35400]end[/color] [color=#434f54]-[/color] [color=#000000]start[/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// Print the duration: 30692 µs[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#00979c]array[/color][color=#000000][[/color][color=#00979c]array[/color][color=#434f54].[/color][color=#d35400]length[/color] [color=#434f54]-[/color] [color=#000000]1[/color][color=#000000]][/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// Print so the compiler doesn't optimize it away [/color]
[color=#000000]}[/color]
[color=#000000]{[/color]
[color=#00979c]auto[/color] [color=#000000]start[/color] [color=#434f54]=[/color] [color=#d35400]micros[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]constexpr[/color] [color=#00979c]auto[/color] [color=#00979c]array[/color] [color=#434f54]=[/color] [color=#000000][[/color][color=#000000]][/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
[b][color=#d35400]Array[/color][/b][color=#434f54]<[/color][color=#00979c]float[/color][color=#434f54],[/color] [color=#000000]200[/color][color=#434f54]>[/color] [color=#00979c]array[/color][color=#000000]{[/color][color=#000000]}[/color][color=#000000];[/color]
[color=#5e6d03]for[/color] [color=#000000]([/color][color=#00979c]uint16_t[/color] [color=#000000]i[/color] [color=#434f54]=[/color] [color=#000000]0[/color][color=#000000];[/color] [color=#000000]i[/color] [color=#434f54]<[/color] [color=#00979c]array[/color][color=#434f54].[/color][color=#d35400]length[/color][color=#000000];[/color] [color=#434f54]++[/color][color=#000000]i[/color][color=#000000])[/color]
[color=#00979c]array[/color][color=#000000][[/color][color=#000000]i[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#d35400]sin[/color][color=#000000]([/color][color=#000000]i[/color] [color=#434f54]*[/color] [color=#00979c]PI[/color] [color=#434f54]/[/color] [color=#000000]100.0[/color][color=#000000])[/color][color=#000000];[/color]
[color=#5e6d03]return[/color] [color=#00979c]array[/color][color=#000000];[/color]
[color=#000000]}[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// IIFE[/color]
[color=#00979c]auto[/color] [color=#d35400]end[/color] [color=#434f54]=[/color] [color=#d35400]micros[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#d35400]end[/color] [color=#434f54]-[/color] [color=#000000]start[/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// Print the duration: 4 µs (0 µs)[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#00979c]array[/color][color=#000000][[/color][color=#00979c]array[/color][color=#434f54].[/color][color=#d35400]length[/color] [color=#434f54]-[/color] [color=#000000]1[/color][color=#000000]][/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// Print so the compiler doesn't optimize it away [/color]
[color=#000000]}[/color]
[color=#000000]}[/color]
[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color][color=#000000]}[/color]
You can enable C++17 by editing the ~/.arduino15/packages/arduino/hardware/avr/1.8.1/platform.txt
file and replacing -std=gnu++11
with -std=gnu++1z
.
Sadly, the Arduino SAM / DUE Core seems to be stuck on an ancient compiler, so it doesn't support this.
Pieter
PieterP
October 14, 2019, 7:49pm
12
You can also use it to generate look-up tables stored in PROGMEM:
[color=#000000]constexpr[/color] [color=#00979c]auto[/color] [color=#00979c]array[/color] [color=#00979c]PROGMEM[/color] [color=#434f54]=[/color] [color=#000000][[/color][color=#000000]][/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
[b][color=#d35400]Array[/color][/b][color=#434f54]<[/color][color=#00979c]float[/color][color=#434f54],[/color] [color=#000000]200[/color][color=#434f54]>[/color] [color=#00979c]array[/color][color=#000000]{[/color][color=#000000]}[/color][color=#000000];[/color]
[color=#5e6d03]for[/color] [color=#000000]([/color][color=#00979c]uint16_t[/color] [color=#000000]i[/color] [color=#434f54]=[/color] [color=#000000]0[/color][color=#000000];[/color] [color=#000000]i[/color] [color=#434f54]<[/color] [color=#00979c]array[/color][color=#434f54].[/color][color=#d35400]length[/color][color=#000000];[/color] [color=#434f54]++[/color][color=#000000]i[/color][color=#000000])[/color]
[color=#00979c]array[/color][color=#000000][[/color][color=#000000]i[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#d35400]sin[/color][color=#000000]([/color][color=#000000]i[/color] [color=#434f54]*[/color] [color=#00979c]PI[/color] [color=#434f54]/[/color] [color=#000000]100.0[/color][color=#000000])[/color][color=#000000];[/color]
[color=#5e6d03]return[/color] [color=#00979c]array[/color][color=#000000];[/color]
[color=#000000]}[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// IIFE[/color]
[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]115200[/color][color=#000000])[/color][color=#000000];[/color]
[color=#5e6d03]while[/color] [color=#000000]([/color][color=#434f54]![/color][b][color=#d35400]Serial[/color][/b][color=#000000])[/color][color=#000000];[/color]
[color=#5e6d03]for[/color] [color=#000000]([/color][b][color=#d35400]size_t[/color][/b] [color=#000000]i[/color] [color=#434f54]=[/color] [color=#000000]0[/color][color=#000000];[/color] [color=#000000]i[/color] [color=#434f54]<[/color] [color=#00979c]array[/color][color=#434f54].[/color][color=#d35400]length[/color][color=#000000];[/color] [color=#434f54]++[/color][color=#000000]i[/color][color=#000000])[/color] [color=#000000]{[/color]
[color=#00979c]float[/color] [color=#000000]val[/color] [color=#434f54]=[/color] [color=#000000]pgm_read_float[/color][color=#000000]([/color][color=#434f54]&[/color][color=#00979c]array[/color][color=#000000][[/color][color=#000000]i[/color][color=#000000]][/color][color=#000000])[/color][color=#000000];[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]val[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]
[color=#000000]}[/color]
[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color][color=#000000]}[/color]