I'm a 4th year EE undergrad, so I'm more of a hardware guy than software. But concerning best programming techniques, is it "better" (more efficient/and/or equally effective) to use for loops when trying to change several items in an array by the same mathematical operation?
--OR--
Is it best to list each item out and have each operation performed by the rate at which the primary "void loop" cycles?
I'm using a Teensy 3.2 board and trying to get a DSP reverb effect working. I have an array of 8 delay tap lines, each with a different time multiplier. I'm trying to determine if it will take more time to process a for loop for each delay-tap line, versus multiplying each element in my array without the additional loop. I need to minimize processing time at all costs to avoid additional system lag.
Sample code:
//Set delay times
for(int i = 0; i < 8; i++)
{
delay1.delay(i, pot1*pauses[i]);
}
versus
delay1.delay(0, pot1*pauses[0]);
delay1.delay(1, pot1*pauses[1]);
delay1.delay(2, pot1*pauses[2]);
.
.
.
EDIT Added sample code.
-
1can you give some pseudo-code for each method?ratchet freak– ratchet freak2017年11月05日 18:31:51 +00:00Commented Nov 5, 2017 at 18:31
-
1Post examples of both alternatives. I'm not sure of what are you asking.user31481– user314812017年11月05日 18:44:25 +00:00Commented Nov 5, 2017 at 18:44
-
Sure, I updated the original post. It likely seems like a trivial question since any dummy wouldn't want to write out 10 lines of repetitive code--most applications that aren't time-sensitive. But I recall trying to do something similar with my Uno board (8MHz) and drawing lines to an OLED. Using "For" loops significantly increased the drawing time.Matt– Matt2017年11月05日 18:46:01 +00:00Commented Nov 5, 2017 at 18:46
2 Answers 2
Have a look at the compiler output.
The Loop option
The first alternative produce a preface (setting things) and the loop itself.
Preface
40201803: 21c9 s32i.n a12, a1, 8
40201805: 3109 s32i.n a0, a1, 12
40201807: 00a0c2 movi a12, 0
loop
4020180a: 202cc0 or a2, a12, a12
4020180d: 01ccc2 addi a12, a12, 1
40201810: ff8585 call0 4020106c <delay>
40201813: f38c66 bnei a12, 8, 4020180a <_Z6XYtestv+0xa>
The unfolded option
While the unfolded version is:
40201823: 020c movi.n a2, 0
40201825: 3109 s32i.n a0, a1, 12
40201827: ff8445 call0 4020106c <delay>
4020182a: 120c movi.n a2, 1
4020182c: ff83c5 call0 4020106c <delay>
4020182f: 220c movi.n a2, 2
40201831: ff8385 call0 4020106c <delay>
40201834: 320c movi.n a2, 3
40201836: ff8345 call0 4020106c <delay>
40201839: 420c movi.n a2, 4
4020183b: ff8305 call0 4020106c <delay>
4020183e: 520c movi.n a2, 5
40201840: ff8285 call0 4020106c <delay>
40201843: 620c movi.n a2, 6
40201845: ff8245 call0 4020106c <delay>
40201848: 720c movi.n a2, 7
4020184a: ff8205 call0 4020106c <delay>
So, the loop execute 4 instructions per each array element, while the unfolded version had only 2 instructions per array element.
But you are trading speed for space and and risking an error while coding the same repetitive thing.
However, GCC (the 'Arduino' compiler) can unfold the loop by itself, so you still can write a loop but execute a sequence. Look at Tell gcc to specifically unroll a loop
Real numbers
I run a sketch (Arduino UNO) to time loop vs unfolded. The times for 1,000 execution of each method are:
loop: 6524us
unfolded: 3808us
Quit a difference!
Sketch
int pause[8] = {1, 2, 3, 4, 5, 6, 7, 8};
typedef int (*fn)(void);
void setup() {
Serial.begin(9600);
while(!Serial);
Serial.println();
Serial.print("Timing loop: ");
Serial.print(time(met1));
Serial.println(" us");
Serial.print("Timing unfolded: ");
Serial.print(time(met2));
Serial.println(" us");
}
void loop() {
}
int time(fn f) {
unsigned long start = micros();
int x = 0;
for (int i = 0; i < 1000; i++) {
x = f();
}
unsigned long dif = micros() - start;
return dif;
}
int met1() {
int sum = 0;
for (int i=0; i < 8; i++) {
sum += pause[i];
}
return sum;
}
int met2() {
int sum = 0;
sum += pause[0];
sum += pause[1];
sum += pause[2];
sum += pause[3];
sum += pause[4];
sum += pause[5];
sum += pause[6];
sum += pause[7];
return sum;
}
is it "better" (more efficient/and/or equally effective)
depends on your definition of "better", or "efficient", ...
for example unrolling a loop is typically more efficient speed-wise, but less so space-wise. or vice versa.
on top of that, you have other potential definitions for "efficiency", like readability, etc.