Optimization by xC on for loops
Posted: Fri May 26, 2017 10:23 am
Hey everyone,
Have been running into an interesting issue regarding the xC compiler optimization. I have been implementing a matrix mixer on an xcore-200 processor. This matrix mixer uses a for loop to handle the mixing of the signals. I've found that my for loop behaviour is not as expected. If I do a plain for loop with the "#pragma loop unroll", it doesn't seem to iterate through the loop. This seems to be fixed by adding a counter and printintln at the end of the loop - this printintln seems to force the compiler to have to iterate through the loop as expected at runtime.
This works --->
This doesn't ---->
Now, when trying a similar thing on another for loop i my code I don't get the expected behaviour at all, even after adding the printintln fix.
so I have to resort to this which is definitely not a flexible solution
Does anyone have any idea why this keeps happening, or how I could make it handle a for loop as expected?
Have been running into an interesting issue regarding the xC compiler optimization. I have been implementing a matrix mixer on an xcore-200 processor. This matrix mixer uses a for loop to handle the mixing of the signals. I've found that my for loop behaviour is not as expected. If I do a plain for loop with the "#pragma loop unroll", it doesn't seem to iterate through the loop. This seems to be fixed by adding a counter and printintln at the end of the loop - this printintln seems to force the compiler to have to iterate through the loop as expected at runtime.
This works --->
Code: Select all
char n = 0; // counter for number of channels active
/* Do Mixing */
#pragma loop unroll
for (int i = 0; i < MAX_SPEAKERS; i++){
for (int j = 0; j < MAX_CHANNELS; j++){
n++
/* mix samples */
samples_mixed[i][j] = sample_out_buf[j]*fifoMixVals[i][j];
samples_mixed[i][j] = samples_mixed[i][j] >> 8; // Shift right to prevent overflow
samples_out[i] += samples_mixed[i][j];
}
printintln(n);
}
printintln(n); // Force compiler to go through each iteration
Code: Select all
/* Do Mixing */
#pragma loop unroll
for (int i = 0; i < MAX_SPEAKERS; i++){
for (int j = 0; j < MAX_CHANNELS; j++){
/* mix samples */
samples_mixed[i][j] = sample_out_buf[j]*fifoMixVals[i][j];
samples_mixed[i][j] = samples_mixed[i][j] >> 8; // Shift right to prevent overflow
samples_out[i] += samples_mixed[i][j];
}
}
Code: Select all
#pragma loop unroll
char count = 0;
for (int j = 0; j < 4; j++){
count++;
ambi_dec_mix[0][j] = sample_out_buf[j]*decoderVals[0][j];
ambi_dec_mix[1][j] = sample_out_buf[j]*decoderVals[1][j];
samples_out[0] += (ambi_dec_mix[0][j]);
samples_out[1] += (ambi_dec_mix[1][j]);
}
printintln(count);
Code: Select all
samples_out[0] = (sample_out_buf[0]*decoderVals[0][0]) +
(sample_out_buf[1]*decoderVals[0][1]) +
(sample_out_buf[2]*decoderVals[0][2]) +
(sample_out_buf[3]*decoderVals[0][3]);
samples_out[1] = (sample_out_buf[0]*decoderVals[1][0]) +
(sample_out_buf[1]*decoderVals[1][1]) +
(sample_out_buf[2]*decoderVals[1][2]) +
(sample_out_buf[3]*decoderVals[1][3]);