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.

Array alignment seems to leave large holes

Using code composer 3.3 & 4.1.3 compiler targeted at 2812 using LARGE_MODEL

We have a growth requirement to only use n% of physical memory, but I'm finding that only 3/4 of the .ebss 'used' by the linker relates to .usect data requested by the generated assembler. The remaining 1/4 appear to be holes.

These seem mainly to appear before a large array. For example, of 3 arrays declared in order physically 130, 170 and 512 bytes, these actually occupy 192, 192 and 512.

I notice that 64 byte boundaries are mentioned, which seems huge, is there any simple way of shrinking these holes? 

thanks.

  • This is happening because that section is being "blocked" by the compiler. This means it needs to either fit completely within a page or begin at a page boundary. The compiler does this to optimize the data page (DP) register load.

    Please take a look at this post for more information: http://e2e.ti.com/support/microcontrollers/tms320c2000_32-bit_real-time_mcus/f/171/p/21702/83828.aspx#83828

    This FAQ should also be helpful: http://processors.wiki.ti.com/index.php/C28x_Compiler_-_Understanding_Linking#Q:_The_linker_says_.22placement_fails_for_object.22_but_the_available_memory_is_larger_than_the_section

     

  • Is there a way to use the holes for smaller variables that do not need blocking?

    It seems as if the linker does not use these holes, so a lot of RAM is wasted if many arrays are used.

  • The linker automatically tries to use the holes for other variables.  Do you have an example where it fails to do so?

  • Okay, I tried to set up an example.

    It is based on DSP2803x Piccolo Periph Examples V1_21/hrpwm, with reduced RAML2 (0x300 instead of 0x400).

    When adding some global variables and especially arrays to Example_2803xHRPWM.c, these holes are not filled.

    The code snippet is

    ......

    Uint16 i,j,    DutyFine, n,update;

    Uint16 array1[92];
    Uint16 array2[92];
    Uint16 array3[92];
    Uint16 array4[92];
    Uint16 array5[92];

    Uint16 array6[32];
    Uint16 array7[32];
    Uint16 array8[32];

    Uint16 array9[4];

    Uint16 dummy1;
    Uint16 dummy2;
    Uint16 dummy3;
    Uint16 dummy4;
    Uint16 dummy5;
    Uint16 dummy6;
    Uint16 dummy7;
    Uint16 dummy8;
    Uint16 dummy9;
    Uint16 dummy10;
    Uint16 dummy11;
    Uint16 dummy12;
    Uint16 dummy13;
    Uint16 dummy14;
    Uint16 dummy15;
    Uint16 dummy16;
    Uint16 dummy17;
    Uint16 dummy18;
    Uint16 dummy19;
    Uint16 dummy20;

    Uint16 dummy21;
    //Uint16 dummy22;

    Uint32 temp;

    void main(void)

    ......

    The default make via CCS 3.3 and cgtools 5.2.5 shows:

    [Example_2803xHRPWM.c] "C:\ti33\C2000\cgtools_5_2_5\bin\cl2000" -g -k -q -al -as -fr"E:/Projekte/DSP/TI_Code_28x/DSP2803x_Piccolo_Periph_Examples_V1_21/DSP2803x_examples/hrpwm/Debug" -fs"E:/Projekte/DSP/TI_Code_28x/DSP2803x_Piccolo_Periph_Examples_V1_21/DSP2803x_examples/hrpwm/Debug" -i"../../DSP2803x_headers/include" -i"../../DSP2803x_common/include" -d"_DEBUG" -d"LARGE_MODEL" -ml -mt -v28 -@"Debug.lkf" "Example_2803xHRPWM.c"

    [Linking...] "C:\ti33\C2000\cgtools_5_2_5\bin\cl2000" -@"Debug.lkf"
    <Linking>
    warning: entry-point symbol other than "_c_int00" specified:  "code_start"

    This is okay so far.
    When also adding (uncommenting) dummy22, I get

    "E:\\Projekte\\DSP\\TI_Code_28x\\DSP2803x_Piccolo_Periph_Examples_V1_21\\DSP2803x_common\\cmd\\28035_RAM_lnk.cmd", line 120: error:
       run placement fails for object ".ebss", size 0x324 (page 1).  Available
       ranges:
       RAML2        size: 0x300        unused: 0x300        max hole: 0x300    
    warning: entry-point symbol other than "_c_int00" specified:  "code_start"
    error: errors encountered during linking; "./Debug/Example_2803xHRPWM.out" not   built
    >> Compilation failure

    The map file when having no error shows:

    000085ee   etext
    00008c00   _dummy10
    00008c01   _dummy18
    00008c02   _dummy8
    00008c03   _dummy20
    00008c04   _dummy21
    00008c05   _dummy9
    00008c06   _dummy19
    00008c07   _dummy4
    00008c08   _dummy3
    00008c09   _dummy6
    00008c0a   _dummy1
    00008c0b   _dummy7
    00008c0c   _dummy5
    00008c0d   _dummy2
    00008c0e   _dummy15
    00008c0f   _dummy16
    00008c10   _dummy13
    00008c11   _dummy17
    00008c12   _dummy14
    00008c13   _n
    00008c14   _DutyFine
    00008c15   _dummy11
    00008c16   _i
    00008c17   _dummy12
    00008c18   _update
    00008c19   _j
    00008c1a   _temp
    00008c1c   _array9
    00008c20   _array7
    00008c40   _array6
    00008c60   _array8
    00008c80   _array2
    00008d00   _array1
    00008d80   _array4
    00008e00   _array3
    00008e80   _array5
    00008edc   __unlock
    00008ede   __lock
    00008ee0   __cleanup_ptr
    00008ee2   __dtors_ptr
    00008f00   _PieVectTableInit

    There is no filled hole at all.... The arrays of size 92 occupy 128 words (0x80) each, no dummy variable filled.

    I hope this example is clear and complete enough to reproduce it.

    So what can I do to use/fill  the holes?

  • As addition: This is the same with latest cgtools 5.2.10.

  • What's going on here is that the assembler creates a single section containing all of those variables.   The layout of this section is set by the assembler, and the linker never gets a chance to even seen the holes between the arrays.  Worse, the compiler apparently sorts variables by size in an attempt to deal with allocation problems, so you can't reorder the arrays yourself in that file.

    Workarounds:

    • put each variable in its own file, or use a #pragma DATA_SECTION to put each variable in its own section.  Then the assembler can't merge them into a single section with holes, allowing the linker to do its thing.
    • put the arrays in a struct and order them however you like.  The compiler is not allowed to reorder the elements of a struct,

    This might be a good example to use to argue for better data object sorting in the compiler, or some better way to manage layout.  I've submitted SDSCM00039553 to investigate this issue

  • I agree that this is really a good example to argue for better data object sorting in the compiler or some better way to manage layout.

    Since the holes are not marked as holes in the mapfile, many users won't even recognize them until they run out of RAM....

    Thanks for submitting the case for investigation.

     

    The workarounds mean a lot of manual work and are not really suited for us.

    So I hope the compiler can and will be improved.

  • I can offer another workaround.  Place only the arrays in a file on their own, then build that file with the option --disable_dp_load_opt, or -md for short.  Build all other files as before.

    The trouble occurs due to a compiler optimization regarding DP load instructions.  The optimization occurs, roughly speaking, in 2 parts.  One part is to arrange for blocking of all the global variables.  Such blocking allows the compiler to know the location of the global variables with regard to page boundaries.  The second part is to take advantage of that knowledge to issue DP load instructions only when absolutely necessary.  One possible side effect of the blocking, as seen here, is wasted space in data memory.

    Placing the arrays in a separate file that is built with -md, in effect, disables the DP load optimization for direct accesses to the arrays.  This is unlikely to matter.  Most array accesses look like "array[i]".  Such accesses do not require the DP.  An access to a constant location such as "array[10]" uses the DP, but that is rare in practice.  Accesses to scalars such as dummy1 continue to be optimized.

    Thanks and regards,

    -George

  • Ah, thanks George, that works pretty good.

    Still only a workaround and I would really appreciate a compiler switch (or general behaviour) that avoids holes, but keeps normal DP optimizations, but for the moment, this works and avoids the holes.