Skip to main content
LIFER.1
Associate II
September 1, 2025
Question

How to speed up function execution?

  • September 1, 2025
  • 3 replies
  • 570 views

I'm currently implementing very low current measurement electronics, such as Femto Amps.

To do this, I'm using the STM32G431CBU MCU. I'm acquiring the output voltages of a float voltage transimpetance amplifier, and I'm taking a running average.
My MCU is clocked by a 24 MHz quartz crystal, with the instruction frequency set to its maximum of 170 MHz.
But my function is still slow, between 24 µs and 50 µs.

float MoyenneGlissante(float valeurI, uint8_t MeanMoving)
{
 static float buffer[50] = {0}; // capacité max : 50 échantillons
 static uint8_t index = 0;
 static uint8_t rempli = 0;

 // Protection : on limite MeanMoving au max du buffer
 if (MeanMoving > 50) MeanMoving = 50;

 // Stocke la nouvelle valeur dans le buffer circulaire
 buffer[index] = valeurI;
 index = (index + 1) % MeanMoving;

 // Marqueur pour savoir si le buffer est rempli au moins une fois
 if (rempli < MeanMoving) rempli++;

 // Calcul de la moyenne glissante
 float somme = 0;
 for (uint8_t i = 0; i < rempli; i++) {
 somme = somme + buffer[i];
 }

 return somme / rempli;
	// return valeurI;

}

clk.jpg

How can I significantly reduce the processing time for this function?

Thank you for your help.

3 replies

Danish1
Lead III
September 1, 2025

Your moving average has to do 50 float additions for every new sample, even though you know you have only changed one value in the buffer. This is slow.

If you remember the total of all 50 values between calls, then update one value, all you need do is change the total by (newValue - oldValue).

LIFER.1
LIFER.1Author
Associate II
September 1, 2025

Thanks for your quick response.

Yes, you're right, that's what the next step is.

float MoyenneGlissante(float valeurI, uint8_t MeanMoving)
{
 static float buffer[50] = {0}; // capacité max : 50 échantillons
 static uint8_t index = 0;
 static uint8_t rempli = 0;

 // Protection : on limite MeanMoving au max du buffer
 if (MeanMoving > 50) MeanMoving = 50;

 // Stocke la nouvelle valeur dans le buffer circulaire
 buffer[index] = valeurI;
 index = (index + 1) % MeanMoving;

 // Marqueur pour savoir si le buffer est rempli au moins une fois
 if (rempli < MeanMoving) rempli++;

 // Calcul de la moyenne glissante
 float somme = 0;
 for (uint8_t i = 0; i < rempli; i++) {
 somme = somme + buffer[i];
 }

 return somme / rempli;
	// return valeurI;

}

But still, too slow...

TDK
Super User
September 1, 2025

Your code hasn't changed... Saving the sum as @Danish1 recommends will dramatically speed things up. However, since you are using floats, the math is not exact and you'll eventually have some error in the calculation. It would be better to reconfigure things and save integer values instead, if possible.

Otherwise, storing data in CCMRAM will improve speed a little as will executing from RAM.

Seems like the code only works if MeanMoving is constant. I'd remove it as a variable and keep it fixed.

"If you feel a post has answered your question, please click ""Accept as Solution""."
LIFER.1
LIFER.1Author
Associate II
September 1, 2025

 

 

Oops, sorry, it's this one. 

float MoyenneGlissante(float valeurI, uint8_t MeanMoving)
{
 static float buffertest[50] = {0}; // capacité max : 50 échantillons
 static uint8_t indextest = 0;
 static uint8_t remplitest = 0;
 static float somme = 0; // somme cumulative

 // Protection : on limite MeanMoving au max du buffer
 if (MeanMoving > 50) MeanMoving = 50;

 // Retire l’ancienne valeur du buffer de la somme
 somme -= buffertest[indextest];

 // Stocke la nouvelle valeur
 buffertest[indextest] = valeurI;

 // Ajoute la nouvelle valeur à la somme
 somme += valeurI;

 // Avance l’index circulaire
 indextest = (indextest + 1) % MeanMoving;

 // Incrémente jusqu’à ce que le buffer soit rempli
 if (remplitest < MeanMoving) remplitest++;

 // Retourne la moyenne glissante
 return somme / remplitest;
}

 

MM..1
Chief III
September 1, 2025

Try

return somme / (float)remplitest;
LIFER.1
LIFER.1Author
Associate II
September 7, 2025

Sorry for the lack of feedback, I was interrupted, and
Thank you for your help and the solution I'll try.