This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Floating-point division uses too much memory

Other Parts Discussed in Thread: TMS320C6701

I am using CCS 5.3 with BIOS V5.42.0.7 to compile code for our TMS320C6701 DSP. Due to our RAD-HARD requirement, I cannot use any external memory. So far, we have managed to fit within the 64K code/data space of the DSP.

Note, switching from CCS V3.3 to CCS V5.3 reduced our code size and sped up our response times. We are guessing that CCS V5.3 makes more use of parallel processing in the DSP.

We just started adding trig functions for processing data and noticed that the amount of available code space dropped drastically. We have been clawing back some of the unused code space and managed to get back to 6800 bytes. We are not done adding new code so I would like to further optimize the code size.

The current compiler/linker settings are:

-mv6700 --abi=coffabi -ms3 -g --define="CHIP_6701"

I guess I could turn off all debugging info, this would save me ~2400 bytes. This might need to happen if we get stuck.

The map file indicates that both the divd lib function is included as well as the divf library function. These chew up 1824 bytes and 832 bytes respectively. My variables are declared floating point type.

So why is divd included in the compile?

Is there a way to avoid pulling in the divd lib?

Regards, Bill.

  • Hello,

    A suggestion: a double may be used in a constant, for ex. 1.0 / 3.0 instead of 1.0F / 3.0F (not always simplied by optimizer).

    Jakez

  • Jakez,

    One of my equations looks like this.

    ( pow(cosf(theta), 2) / (2.0 * pow(sigma_x, 2)) ) + ( pow(sinf(theta), 2) / (2.0 * pow(sigma_y, 2)) )

    I checked and my libraries do not have a reciprocate function.

    Regards, Bill.

  • Bill,

    My interpretation of Jakez' comment is to add the F suffix after 2.0 both places in your equation. If the compiler defaults to double for 2.0, then 2.0F may prevent it from up-casting your interim products in the equation shown.

    It will help you find the culprit quicker if you look at the assembly output to find where the divd function is being called. Then you can trace through the code to figure out the equation being implemented. That requires reading through the C6000 assembly language, though, and that is a tough job.

    Your compiler switches do not include -o to turn on optimization. -o3 is the highest, but -o2 gives very good results, and -o1 & -o0 will reduce code size some. Before turning off -g, I recommend turning on -o2, or progressively increasing the optimization from -o0 to see the results in case there are some issues with your code with optimization.

    It seems like there was a FASTLIB written for these early floating point processors. The code is smaller and faster, but some boundary values may have less accuracy or there might be one bit of accuracy lost. But it worked well for many users, as I recall.

    Regards,
    RandyP

  • Hello,

    'pow' is nominally  a double function; you may use the powf function; implementation of pow includes division (exp & log rational approximation).

    In your case, you should rewrite the line by something like:

    float x = cosf(theta);

    float y = sinf(theta);

    then:   x * x / (2.0F * sigmax * sigmax) + y * y / (2.0F * sigmay * sigmay)


    Jakez

  • Dear Jakez,

    Placing 'F' beside my constants eliminated the "divd" library call. My unused code space increased from ~6800 bytes to ~9600 bytes.

    Thank you, Bill.

     

    Dear RandyP,

    Increasing my file-level optimization from none to "-O3" increased my unused code space from ~9600 bytes to ~17000 bytes. Whoa.

    Thank you, Bill.

  • Bill,

    The problems that can come up when you turn on optimization involve variables being optimized out. This is most common with flags used from an interrupt service routine that gets tested by a function elsewhere, and that function might throw away the test instead of looping on testing the value.

    The other common place is in a for-loop that is used for a delay, for example "for ( i = 0; i < 1000; i++ );" might be optimized down to just "i=1000".

    In both cases, the variable involved needs to have the type modifier "volatile" used, such as "volatile int i;". This tells the compiler that this variable may change outside the scope of the current function or file.

    Regards,
    RandyP

  • Dear RandyP,

    All my h/w routines are located in 1 file. I added the directive "--call_assumptions=0" to the file via the CCS menu. The directive did not seem to take affect. The local variables in a routine within this file are still being optimized out. I added the word "volatile" to the local variables and they were no longer optimized out as expected. I was hoping to avoid going thru the entire file modiying all the local variables but it seems I may have to.

    Any experience with the directive? Does it some quircks not stated in the help?

    Thanks, Bill.