The difference of LPCOpen version to use division ROM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

The difference of LPCOpen version to use division ROM

1,696 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gl_belre9 on Thu Mar 17 00:36:20 MST 2016
Hello,
I found it takes process time of division ROM in LPCOpen version 2.15 more than in 2.19, using LPCXpresso824-MAX board.
I'd like to know the reason of this difference.

I verified the process time by using SysTick timer, showing source code below.
I compiled this code in Optimization Level -O0.

It takes 115us in LPCOpen 2.19, and 144us in 2.15.

Thank you.

/*
===============================================================================
 Name        : lpc824_divtest.c
 Author      : gl_belre9
 Version     :
 Description : main definition
===============================================================================
*/

#if defined (__USE_LPCOPEN)
#if defined(NO_BOARD_LIB)
#include "chip.h"
#else
#include "board.h"
#endif
#endif

#include <cr_section_macros.h>

#define TICKRATE_HZ (2)/// Frequency for SysTick Timer
#define LOOP_NUMBER24

/*****************************************************************************
 * Public types/enumerations/variables
 ****************************************************************************/
static volatile uint32_t ticks;

/*****************************************************************************
 * Private functions
 ****************************************************************************/


/*****************************************************************************
 * Public functions
 ****************************************************************************/
/**
 * @briefHandle interrupt from SysTick timer, measurement of time
 * @returnNothing
 */
void SysTick_Handler(void)
{
volatile float time = (float)((1.0 / TICKRATE_HZ) / (float)ticks);
time *= 1000000;
ticks = 0;
}
int main(void) {
    // Read clock settings and update SystemCoreClock variable
    SystemCoreClockUpdate();

    // Set up and initialize all required blocks and
    // functions related to the board hardware
    Board_Init();
    // Set the LED to the state of "On"
    Board_LED_Set(0, true);

    /// Enable SysTick Timer
SysTick_Config(SystemCoreClock / TICKRATE_HZ);

volatile int i;
    volatile int x = 3;
    volatile int y = 100;
    volatile int z = 0;
    volatile int count = 0;

    /// Simple Division
    while(1) {
    for(i = 0 ; i < LOOP_NUMBER; i ++) {
z = y / x;
if( z == 0) {
count --;
} else {
count++;
}
    }
ticks++;
    }
    return 0 ;
}



Labels (1)
0 Kudos
Reply
5 Replies

1,622 Views
lpcware
NXP Employee
NXP Employee
bump
0 Kudos
Reply

1,622 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gl_belre9 on Mon Mar 21 17:49:09 MST 2016
Sorry for replying late.
I considered my code to calculate the process time of division ROM again.

I checked the value of numerator and denominator at division and Systick handles.
In addition, I won't use interrupt to measure process time directly.

It takes some time of division ROM(x24):
2.19
Proc Time:0.108800[ms]

2.15
Proc Time:0.136000[ms]

I'll show my source code below.
Thanks.

/*
===============================================================================
 Name        : lpc824_divtest.c
 Author      : gl_belre9
 Version     :
 Description : main definition
===============================================================================
*/

#if defined (__USE_LPCOPEN)
#if defined(NO_BOARD_LIB)
#include "chip.h"
#else
#include "board.h"
#endif
#endif

#include <cr_section_macros.h>

#define TICKRATE_HZ (1000)/// Frequency for SysTick Timer
#define CALC_NUMBER10000
#define LOOP_NUMBER24*CALC_NUMBER

/*****************************************************************************
 * Public types/enumerations/variables
 ****************************************************************************/
static volatile uint32_t ticks;

/*****************************************************************************
 * Private functions
 ****************************************************************************/


/*****************************************************************************
 * Public functions
 ****************************************************************************/
/**
 * @briefHandle interrupt from SysTick timer, measurement of time
 * @returnNothing
 */
/// 1. Change your Systick handler so that it just counts ticks. Don't try to do time calcluations here
void SysTick_Handler(void)
{
ticks++;
}
int main(void) {
    // Read clock settings and update SystemCoreClock variable
    SystemCoreClockUpdate();

    // Set up and initialize all required blocks and
    // functions related to the board hardware
    Board_Init();
    // Set the LED to the state of "On"
    Board_LED_Set(0, true);

    /// Enable SysTick Timer
SysTick_Config(SystemCoreClock / TICKRATE_HZ);

volatile int i;
    volatile int x = 1000;
    volatile int y = 100;
    volatile int z = 0;
    volatile int count = 0;

    /// Simple Division
    while(1) {
    /// 2. Do a large number of divisions (100's or 1000's). This will reduce any timing variations
    x = 100;
    y = 1000;

    /// 4. Note the number of ticks at the start of your division loop
    /// Simple Division
    volatile int startticks = ticks;

    /// 6. Repeat several times to give an average
    for(i = 0 ; i < LOOP_NUMBER; i ++ )
    {
        /// 3. Change the numbers used in each division. You are always using the same numbers
    z = ++y / ++x;
    }


    /// 5. Note the number of ticks at the end of the division and calculate the difference from #4
    volatile int endticks = ticks;

    /// Calculate Process Time
    float tickstime = (float)(endticks - startticks) / CALC_NUMBER;

    /// UART Debug
    DEBUGOUT("Proc Time(x%d):%f[ms]\r\n", LOOP_NUMBER/CALC_NUMBER, tickstime);

    /// Reset Ticks
    ticks = 0;
    }
    return 0 ;
}
0 Kudos
Reply

1,622 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by vtw.433e on Fri Mar 18 01:56:39 MST 2016
I don't understand your code. The main problem is that you are not actually measuring how long it takes to do the division(s).

You should:
1. Change your Systick handler so that it just counts ticks. Don't try to do time calcluations here
2. Do a large number of divisions (100's or 1000's). This will reduce any timing variations
3. Change the numbers used in each division. You are always using the same numbers
4. Note the number of ticks at the start of your division loop
5. Note the number of ticks at the end of the division and calculate the difference from #4
6. Repeat several times to give an average

This will then give you a meaningful average time to do a division.
0 Kudos
Reply

1,622 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gl_belre9 on Thu Mar 17 17:31:23 MST 2016
OK, I tried to benchmark in optimized level -O2. I wrote 'volatile' on variable 'x', 'y', 'z' because division procedure is ignored.
As a result, it takes 140us in 2.15 and 111us in 2.19.

I have no idea about the time differences.
0 Kudos
Reply

1,622 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by vtw.433e on Thu Mar 17 04:22:22 MST 2016
Do not try to benchmark unoptimized (aka Debug and -O0) code. The compiler generates very poor code that works, but that is all you can say about it. When benchmarking, use -O2 or -O3 or -Os.

In your example the ROM code obviously does not change so you are comparing the compiler generated code that stack the parameters and calls the ROM code.
0 Kudos
Reply