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

How can I optimize the xdata access with C51

Hi there!

I need to optimize the accessing the xdata memory (the speed) with C51.

I am sending some files via modem and the transmission could be a bit faster. At present, I am reaching a transmission speed around 2kbyte/sec, which is kinda slow.

Right now, my buffers are large arrays in xdata memory and before a byte reaches the UART, it went through a couple of buffers (for the prtotocol layers). I cannot prevent that. But maybe one or the other way can speed up my access time to xdata.

I am not sure, I have heard somewhere that C51 will be faster if pointers instead of arrays are used. I didn't find anything about that in the search (maybe due to my keywords). Does anybody know more about that topic?

Parents
  • You say that you have some large buffers. In that case you will have to place them in xdata.

    Presumably you are using an interrupt driven UART driver. Consider making the buffer that is accessed by the ISR as small as possible so that it at least can be placed in pdata – that will keep your interrupts as fast as possible.

    If you can, keep your buffers down to 256 elements or less; on the 8051, 8-bit arithmetic is very much faster that 16-bit.

    I assume that you are using circular buffers. Although having your buffers in xdata may be inevitable because of their size. Don't place the buffer and the control variables in one structure, it looks neat but is generally slower. If you can, place the control variables (read and write pointers/indexes, count etc.) in the fastest available memory e.g. pdata or preferably data.

    With a circular buffer it is necessary to increment an index modulo the length of the buffer. Make your buffer 2^n elements long and C51 will covert you modulo operator to an AND mask – which is nice and quick. This is probably the main reason why, in similar contexts, I have found no real advantage in using pointers rather than indexes – a fast increment modulo 2^n is essential.

    BTW: in general I have noticed that C51 is not very cleaver when pre/post increment/decrements are used within an expression and that it is generally the case that shorter, faster code results by placing these increments/decrements in separate C statements. The exceptions to this rule are

    unsigned char count;
    ...
    if ( --count )
    {
    ...
    }
    
    and
    do
    {
    ...
    } while( --count != 0 )
    
    In the above cases, the compiler uses DJNZ instruction for a very efficient implementation.

Reply
  • You say that you have some large buffers. In that case you will have to place them in xdata.

    Presumably you are using an interrupt driven UART driver. Consider making the buffer that is accessed by the ISR as small as possible so that it at least can be placed in pdata – that will keep your interrupts as fast as possible.

    If you can, keep your buffers down to 256 elements or less; on the 8051, 8-bit arithmetic is very much faster that 16-bit.

    I assume that you are using circular buffers. Although having your buffers in xdata may be inevitable because of their size. Don't place the buffer and the control variables in one structure, it looks neat but is generally slower. If you can, place the control variables (read and write pointers/indexes, count etc.) in the fastest available memory e.g. pdata or preferably data.

    With a circular buffer it is necessary to increment an index modulo the length of the buffer. Make your buffer 2^n elements long and C51 will covert you modulo operator to an AND mask – which is nice and quick. This is probably the main reason why, in similar contexts, I have found no real advantage in using pointers rather than indexes – a fast increment modulo 2^n is essential.

    BTW: in general I have noticed that C51 is not very cleaver when pre/post increment/decrements are used within an expression and that it is generally the case that shorter, faster code results by placing these increments/decrements in separate C statements. The exceptions to this rule are

    unsigned char count;
    ...
    if ( --count )
    {
    ...
    }
    
    and
    do
    {
    ...
    } while( --count != 0 )
    
    In the above cases, the compiler uses DJNZ instruction for a very efficient implementation.

Children
No data