C embedded

荷树栋 / 2023-07-16 / 原文

Disable optimization for a piece of code

#pragma GCC push_options
#pragma GCC optimize ("O0")   

for(uint i=0; i<T; i++){__NOP()}

#pragma GCC pop_options




Multiplication and division by power of 2:

Use left shift(<<) for multiplication and right shift(>>) for division. The bit operations will be much faster than multiplication and division operations.For simple operations, the compiler may automatically optimize the code but in case of complex expressions it is always advised to use bit operations.
Example :

Multiply by 6 : a= a<<1 + a<<2; 
Multiply by 7 : a= a<<3 - a;
Divide by 8 : a= a>>3; // division by power of 2


Prefer pre Increment/Decrement to post Increment/Decrement


In pre-increment, it first increments the value and just copies the value to variable location but in post-increment, it first copies the value to a temporary variable, increments it and then copies the value to the variable location. If post-increment is 1000 times in a loop it will decrement the efficiency.

Optimizing Arrays

f you access members of array like this:

for(int i=0; i<n; i++) nArray[i]=nSomeValue;

Instead of the above code, the following is better:

for(int* ptrInt = nArray; ptrInt< nArray+n; ptrInt++) *ptrInt=nSomeValue;

Faster for() loops

It is a simple concept but effective. Ordinarily, we used to code a simple for() loop like this:

 
for( i=0;  i<10;  i++){ ... }

i loops through the values 0,1,2,3,4,5,6,7,8,9 ]

If we needn't care about the order of the loop counter, we can do this instead:

 
for( i=10; i--; ) { ... }

Using this code, i loops through the values 9,8,7,6,5,4,3,2,1,0, and the loop should be faster.

This works because it is quicker to process i-- as the test condition, which says "Is i non-zero? If so, decrement it and continue". For the original code, the processor has to calculate "Subtract i from 10. Is the result non-zero? If so, increment i and continue.". In tight loops, this makes a considerable difference.

The syntax is a little strange, put is perfectly legal. The third statement in the loop is optional (an infinite loop would be written as for( ; ; )). The same effect could also be gained by coding:

 
for(i=10; i; i--){}

or (to expand it further):

 
for(i=10; i!=0; i--){}

The only things we have to be careful of are remembering that the loop stops at 0 (so if it is needed to loop from 50-80, this wouldn't work), and the loop counter goes backwards. It's easy to get caught out if your code relies on an ascending loop counter.

We can also use register allocation, which leads to more efficient code elsewhere in the function. This technique of initializing the loop counter to the number of iterations required and then decrementing down to zero, also applies to while and do statements.