When we write a loop, most of us will use post increase or decrease, but there is a better solution. See below examples, which one is the better one?
Example1:
uint8_t CalcParity1(uint8_t* data, uint8_t len)
{
uint8_t rt = ;
for (uint8_t i = ; i < len; i++)
{
if (*data++)
{
rt++;
} }
return rt;
}
Example 2:
uint8_t CalcParity2(uint8_t* data, uint8_t len)
{
uint8_t rt = ;
for (uint8_t i = ; i < len; ++i)
{
if (*data)
{
rt++;
}
++data; }
return rt;
}
The answer is Example 2. Why? Let’s check the assemble code which is based on IAR MSP430 (note that it can be different for different compiler).
There are 32 execution codes totally. But in Example 2, there is 24 execution codes. The example 1 has a less source code, but the example 2 has a better performance with better reading.
See another example 3 below.
uint8_t CalcParity3(uint8_t* data, uint8_t len)
{
uint8_t rt = ;
for (uint8_t i = len; i > ; --i)
{
if (*data)
{
rt++;
}
++data; }
return rt;
}
It is my prefer solution. In most situations, it has a better performance than example 2. But there are same between example 2 and example 3 after checking assemble code at IAR MSP430. The IAR compiler did a good job.
It is also the recommendation of TI ULP Advisor.
" line 77: remark #1544-D: (ULP 13.1) Detected loop counting up. Recommend loops count down as detecting zeros is easier.
I list the rule13.1 here.
Rule 13.1 Count down in loops
What it means
In MSP430 assembly code, a conditional branch based on comparing a variable/register against a non-zero value requires two instructions: compare and branch. However, when branching & comparing against zero, a specific instruction, BNE, can be used to perform both actions. This also holds true for a branch statement in C. Hence a counting down loop can reduce one instruction for each iteration of the loop when compared to a loop counting up.
Risks, Severity
A counting-up loop consumes one extra instruction for every iteration of the loop.
Why it is happening
A loop with an index counting up is detected in the code.
Remedy
- Use a loop that counts down whenever possible.
- Ensure that -o2 optimization level is selected in the compiler, or greater implements are included in the project settings to enable optimization for counting down loops.
Code Example
int i;
P1OUT |= 0x01; // Set P1.0 LED on
for (i = 5000; i>0; i--) // Count down loop
// In instead of: (i = 0; i <5000; i++)
{
/* Execute your application code */
}