This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiler produces inefficient assembly code?

I and a co-worker are programming an 8051 uController in C. Last week we were struggling with a poor perfomance time of our program. So I talked to the assembly guy and we figured that our way of software timer handling was too slow. We were using 16 bit variables. Now I tweaked the timer software a bit and it runs about 4x faster, which is fast enough.

Digging a little deeper in the produced assembly code we found a 'persistent nuisance'. As a test I wrote these lines in code:

uint8 j;
        for(j=10;j--;){
                rightTorqueArray[j] = j; }


The array is an unsigned char array but when we observe the assembly

        MOV     R7,#0AH
?C0001:
        MOV     R6,AR7
        DEC     R7
        MOV     A,R6
        JZ      ?C0002
;               rightTorqueArray[j] = j; }
                        ; SOURCE LINE # 52
        MOV     A,#LOW (rightTorqueArray)
        ADD     A,R7
        MOV     DPL,A
        CLR     A
        ADDC    A,#HIGH (rightTorqueArray)
        MOV     DPH,A
        MOV     A,R7
        MOVX    @DPTR,A
        SJMP    ?C0001
?C0002:

We noticed that the array is adressed with LOW and HIGH so apparantly it is treated as a 16 bit variable. But my assembly-nese is not so well, so please correct me if I am wrong.

I set the Code Optimalization at level 8: reuse Common entry code and the emphasis at Favor speed.

The assembly was produced as a .SRC file using #pragma SRC on top of the C-file.

Parents
  • @Neil The "assembly guy" cannot help, he is 66 years, worked his entire live at this company and most importantly: he does not know anything about C or Keil. The one programming language he ever learned is assembly.

    Well a funny thing. If I remove xdata there is no difference in the ammount of assembly lines. We (me and he co-worker who isn't the assembly guy) already suspected it.

    We only have 64 bytes memory for non-xdata memory and over 65kB of xdata, which I personally call "unlimited variable memory".

    Co-worker already tried using pointers but his attempt produced the same problem. According to the link I sent: Optimal C Constructs for 8051 Microcontrollers by Nigel Jones.

    Accessing xdata via for-loop supposed to be faster than using pointers. I will however examin appendix C first. See what that files has to say over the matter

    I have another smaller question. For my software timers I removed most loops and I used constants instead. It uses more code but should have a quicker execution timer. Most of the arrays are still members of structs. Does it benefit if I were to remove the structs and use separate arrays instead?

Reply
  • @Neil The "assembly guy" cannot help, he is 66 years, worked his entire live at this company and most importantly: he does not know anything about C or Keil. The one programming language he ever learned is assembly.

    Well a funny thing. If I remove xdata there is no difference in the ammount of assembly lines. We (me and he co-worker who isn't the assembly guy) already suspected it.

    We only have 64 bytes memory for non-xdata memory and over 65kB of xdata, which I personally call "unlimited variable memory".

    Co-worker already tried using pointers but his attempt produced the same problem. According to the link I sent: Optimal C Constructs for 8051 Microcontrollers by Nigel Jones.

    Accessing xdata via for-loop supposed to be faster than using pointers. I will however examin appendix C first. See what that files has to say over the matter

    I have another smaller question. For my software timers I removed most loops and I used constants instead. It uses more code but should have a quicker execution timer. Most of the arrays are still members of structs. Does it benefit if I were to remove the structs and use separate arrays instead?

Children
  • But, surely, he can explain the assembler to you? And explain why this is inherent in the 8051 architecture?

    "Well a funny thing. If I remove xdata there is no difference in the ammount of assembly lines"

    That's not funny at all - it is to be expected if you are using a Memory Model which defaults to XDATA.

    As already noted, XDATA memory access is inherently slow & "inefficient".

    "Co-worker already tried using pointers but his attempt produced the same problem"

    So show what, exactly, he tried - and what, exactly, was the result.

    As the "inefficiency" is inherent in the underlying hardware architecture, it is bound to happen!

    "Accessing xdata via for-loop supposed to be faster than using pointers"

    Says who?

    "Does it benefit if I were to remove the structs and use separate arrays instead?"

    Most likely not. More detail needed to answer specifically.

  • 
    void test(void)
    {
       uint8 rightTorqueArray[10], j;
          for(j = 10;j > 0; --j)
          {
             rightTorqueArray[j] = j;
          }
    }
    /////////////////////////////////////////////
        88: void test(void)
        89: {
        90:    uint8 rightTorqueArray[10], j;
    
        91:       for(j = 10; j > 0; --j)
    C:0x199C    7F0A     MOV      R7,#0x0A
        92:       {
        93:          rightTorqueArray[j] = j;
    C:0x199E    7453     MOV      A,#0x53
    C:0x19A0    2F       ADD      A,R7
    C:0x19A1    F8       MOV      R0,A
    C:0x19A2    A607     MOV      @R0,0x07
        93:       }
    C:0x19A4    DFF8     DJNZ     R7,C:199E
    C:0x19A6    22       RET
    

  • But that example is not using XDATA - is it?

  • Yes, it is in data memory.
    It was done intentionally, to demonstrate different memory and access type in x51.
    It was not any restriction for it in the beginning of the topic.

  • OK - That's true.

    A fundamental problem seems to be that the OP hasn't understood (or didn't originally understand) the implications of using XDATA - hence my early question about the significance of the xdata keyword.