Skip to main content
Visitor II
September 1, 2025
Question

How to speed up function execution?

  • September 1, 2025
  • 3 replies
  • 568 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.

    This topic has been closed for replies.

    3 replies

    Graduate
    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.1Author
    Visitor 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...

    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.

    LIFER.1Author
    Visitor 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;
    }

     

    Graduate II
    September 1, 2025

    Try

    return somme / (float)remplitest;
    LIFER.1Author
    Visitor 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.