реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> Оптимизация алгоритма на С, вопрос к знатокам компиляторов
singlskv
сообщение Aug 25 2006, 12:30
Сообщение #31


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(_Bill @ Aug 25 2006, 15:47) *
Цитата(singlskv @ Aug 25 2006, 14:26) *

такты я считал по возможности честно, т.е. не учитывая такты потраченные на передачу
параметров.
А мой ASM код можно легко переписать под нужные регистры. smile.gif

В свое время я написал небольшой опус на эту тему. К сожалению, он и сейчас далек от завершения.


Несколько месяцев назад прочитал Ваш опус, очень понравилось a14.gif
Так что Вас можно считать идейным вдохновителем данного топика smile.gif
Цитата(_Bill @ Aug 25 2006, 15:47) *
Не сомневаюсь, но код все равно получится длиннее. И, опять же, если Вы используете свои собственные соглашения по передаче параметров и использованию регистров в ваших модулях на ассемблере, то Вы будете вынуждены писать Ваши функции в соответствии с принятыми Вами соглашениями. А это неизбежно приведет к увеличению кода аналогично тому, как это делается компилятором.

Вот код для IAR (если я ничего не напутал):
Код
crc8iar:            ;Input: r17:r16 buffer; r18 - number of bytes    
                    ;Output: r16 = CRC

        movw    r31:r30,r17:r16
        ldi        r16,0            ;CRC
        ldi        r19,0x8c
crc8iar_1:
        ld        r20,Z+
        ldi        r21,8
crc8iar_2:
        lsr        r16
        brbc    0,crc8iar_3
        eor        r16,r19
crc8iar_3:
        sbrc    r20,0
        eor        r16,r19
        lsr        r20
crc8iar_4:
        dec        r21
        brne    crc8iar_2
        dec        r18
        brne    crc8iar_1

        ret

Добавилась всего одна инструкция:
Код
        movw    r31:r30,r17:r16
Go to the top of the page
 
+Quote Post
_Bill
сообщение Aug 25 2006, 12:59
Сообщение #32


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(singlskv @ Aug 25 2006, 15:30) *
Вот код для IAR (если я ничего не напутал):
Код
crc8iar:;Input: r17:r16 buffer; r18 - number of bytes    
        ;Output: r16 = CRC

        movw    r31:r30,r17:r16
        ldi        r16,0;CRC
        ldi        r19,0x8c
crc8iar_1:
        ld        r20,Z+
        ldi        r21,8
crc8iar_2:
        lsr        r16
        brbc    0,crc8iar_3
        eor        r16,r19
crc8iar_3:
        sbrc    r20,0
        eor        r16,r19
        lsr        r20
crc8iar_4:
        dec        r21
        brne    crc8iar_2
        dec        r18
        brne    crc8iar_1

        ret

Добавилась всего одна инструкция:
Код
        movw    r31:r30,r17:r16

Вроде все правильно. Только я думаю, что если Вы переведете ваш код на Си, то компилятор сделает код, аналогичный вашему. Лично я добавил бы еще одну переменную - указатель:
Код
#define BIT_0   (1<<0)
unsigned char crc8iar(char *buffer, char nbytes)
    {
    char   *bp = buffer;
    char   crc = 0, tmp, x8C = 0x8C;
    char   i;

    do    {
         tmp = *bp++;
         i     = 8;
         do   {
            if ((crc >>= 1) & BIT_0)
                crc ^= x8C;
            if (tmp & BIT_0)
                crc ^= x8C;
            tmp >>= 1;
            }
        while (--i);
        }
    while (--nbytes);
    return crc;
    }

Вроде так, если я нигде не ошибся.

Сообщение отредактировал _Bill - Aug 25 2006, 13:22
Go to the top of the page
 
+Quote Post
_Bill
сообщение Aug 25 2006, 13:30
Сообщение #33


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(singlskv @ Aug 25 2006, 15:30) *
Вот код для IAR (если я ничего не напутал):
Код
crc8iar:;Input: r17:r16 buffer; r18 - number of bytes    
    ;Output: r16 = CRC

        movw    r31:r30,r17:r16
        ldi        r16,0;CRC
        ldi        r19,0x8c
crc8iar_1:
        ld        r20,Z+
        ldi        r21,8
crc8iar_2:
        lsr        r16
        brbc    0,crc8iar_3
        eor        r16,r19
crc8iar_3:
        sbrc    r20,0
        eor        r16,r19
        lsr        r20
crc8iar_4:
        dec        r21
        brne    crc8iar_2
        dec        r18
        brne    crc8iar_1

        ret

Добавилась всего одна инструкция:
Код
        movw    r31:r30,r17:r16

Вот результат трансляции. Можете сравнить.
Код
     70          #define BIT_0   (1<<0)

   \                                 In segment CODE, align 2, keep-with-next
     71          unsigned char crc8iar(char *buffer, char nbytes)
   \                     crc8iar:
     72              {
     73              char   *bp = buffer;
   \   00000000   01F8               MOVW    R31:R30, R17:R16
     74              char   crc = 0, tmp, x8C = 0x8C;
   \   00000002   E000               LDI     R16, 0
     75              char   i;
     76          
     77              do    {
     78                   tmp = *bp++;
   \                     ??crc8iar_0:
   \   00000004   9141               LD      R20, Z+
     79                   i     = 8;
   \   00000006   E018               LDI     R17, 8
     80                   do   {
     81                      if ((crc >>= 1) & BIT_0)
   \                     ??crc8iar_1:
   \   00000008   9506               LSR     R16
   \   0000000A   FB00               BST     R16, 0
   \   0000000C   F416               BRTC    ??crc8iar_2
     82                          crc ^= x8C;
   \   0000000E   E83C               LDI     R19, 140
   \   00000010   2703               EOR     R16, R19
     83                      if (tmp & BIT_0)
   \                     ??crc8iar_2:
   \   00000012   FB40               BST     R20, 0
   \   00000014   F416               BRTC    ??crc8iar_3
     84                          crc ^= x8C;
   \   00000016   E83C               LDI     R19, 140
   \   00000018   2703               EOR     R16, R19
     85                      tmp >>= 1;
   \                     ??crc8iar_3:
   \   0000001A   9546               LSR     R20
     86                      }
     87                  while (--i);
   \   0000001C   951A               DEC     R17
   \   0000001E   F7A1               BRNE    ??crc8iar_1
     88                  }
     89              while (--nbytes);
   \   00000020   952A               DEC     R18
   \   00000022   F781               BRNE    ??crc8iar_0
     90              return crc;
   \   00000024   9508               RET
     91              }
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 25 2006, 13:49
Сообщение #34


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(_Bill @ Aug 25 2006, 17:30) *
Вот результат трансляции. Можете сравнить.
Код
     70          #define BIT_0   (1<<0)

   \                                 In segment CODE, align 2, keep-with-next
     71          unsigned char crc8iar(char *buffer, char nbytes)
   \                     crc8iar:
     72              {
     73              char   *bp = buffer;
   \   00000000   01F8               MOVW    R31:R30, R17:R16
     74              char   crc = 0, tmp, x8C = 0x8C;
   \   00000002   E000               LDI     R16, 0
     75              char   i;
     76          
     77              do    {
     78                   tmp = *bp++;
   \                     ??crc8iar_0:
   \   00000004   9141               LD      R20, Z+
     79                   i     = 8;
   \   00000006   E018               LDI     R17, 8
     80                   do   {
     81                      if ((crc >>= 1) & BIT_0)
   \                     ??crc8iar_1:
   \   00000008   9506               LSR     R16
   \   0000000A   FB00               BST     R16, 0
   \   0000000C   F416               BRTC    ??crc8iar_2
     82                          crc ^= x8C;
   \   0000000E   E83C               LDI     R19, 140
   \   00000010   2703               EOR     R16, R19
     83                      if (tmp & BIT_0)
   \                     ??crc8iar_2:
   \   00000012   FB40               BST     R20, 0
   \   00000014   F416               BRTC    ??crc8iar_3
     84                          crc ^= x8C;
   \   00000016   E83C               LDI     R19, 140
   \   00000018   2703               EOR     R16, R19
     85                      tmp >>= 1;
   \                     ??crc8iar_3:
   \   0000001A   9546               LSR     R20
     86                      }
     87                  while (--i);
   \   0000001C   951A               DEC     R17
   \   0000001E   F7A1               BRNE    ??crc8iar_1
     88                  }
     89              while (--nbytes);
   \   00000020   952A               DEC     R18
   \   00000022   F781               BRNE    ??crc8iar_0
     90              return crc;
   \   00000024   9508               RET
     91              }

696 тактов однако ???
Код
   \   0000000E   E83C               LDI     R19, 140
   \   00000010   2703               EOR     R16, R19
     83                      if (tmp & BIT_0)
   \                     ??crc8iar_2:
   \   00000012   FB40               BST     R20, 0
   \   00000014   F416               BRTC    ??crc8iar_3
     84                          crc ^= x8C;
   \   00000016   E83C               LDI     R19, 140

А не слишком ли мы часто загружаем константу 140 (0x8c).
Go to the top of the page
 
+Quote Post
µµC
сообщение Aug 25 2006, 15:26
Сообщение #35


Участник
*

Группа: Новичок
Сообщений: 44
Регистрация: 2-05-06
Пользователь №: 16 710



Приятный алгоритм, возьму на вооружение. IAR - 515 циклов.
Код
U8 crc8_3(U8 *buff, U8 num)
{
  U8 i, crc = 0;
  
  do {
    crc ^= *buff++;
    i   = 8;
    do {  
      if (crc & 0x01) {
        crc >>= 1;
        crc ^= 0x8C;
      } else {
        crc >>= 1;
      }
    } while (--i);  
  } while (--num);
  return crc;
}
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 25 2006, 15:38
Сообщение #36


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(µµC @ Aug 25 2006, 19:26) *
Приятный алгоритм, возьму на вооружение. IAR - 515 циклов.
Код
U8 crc8_3(U8 *buff, U8 num)
{
  U8 i, crc = 0;
  
  do {
    crc ^= *buff++;
    i   = 8;
    do {  
      if (crc & 0x01) {
        crc >>= 1;
        crc ^= 0x8C;
      } else {
        crc >>= 1;
      }
    } while (--i);  
  } while (--num);
  return crc;
}

а листинг можно в студию ? (ну не стоит у меня IAR)



Цитата(µµC @ Aug 25 2006, 19:26) *
Приятный алгоритм, возьму на вооружение. IAR - 515 циклов.
Код
U8 crc8_3(U8 *buff, U8 num)
{
  U8 i, crc = 0;
  
  do {
    crc ^= *buff++;
    i   = 8;
    do {  
      if (crc & 0x01) {
        crc >>= 1;
        crc ^= 0x8C;
      } else {
        crc >>= 1;
      }
    } while (--i);  
  } while (--num);
  return crc;
}

а листинг можно в студию ? (ну не стоит у меня IAR)
Go to the top of the page
 
+Quote Post
µµC
сообщение Aug 25 2006, 16:19
Сообщение #37


Участник
*

Группа: Новичок
Сообщений: 44
Регистрация: 2-05-06
Пользователь №: 16 710



Цитата(singlskv @ Aug 25 2006, 19:38) *
а листинг можно в студию ? (ну не стоит у меня IAR)


Код
        NAME crc8

        RSEG CSTACK:DATA:NOROOT(0)
        RSEG RSTACK:DATA:NOROOT(0)

        EXTERN ?need_segment_init

        PUBWEAK `?<Segment init: TINY_I>`
        PUBWEAK `?<Segment init: TINY_Z>`
        PUBWEAK __?EEARL
        PUBWEAK __?EECR
        PUBWEAK __?EEDR
        PUBLIC code
        PUBLIC crc8_3
        PUBLIC main
        PUBLIC result

// C:\1z\CRC8\crc8.c
//    1 #define U8 unsigned char
//    2

        RSEG TINY_I:DATA:NOROOT(0)
        REQUIRE `?<Segment init: TINY_I>`
//    3 U8 code[8] = {0x01, 0xd0, 0x5e, 0x3c, 0x0d, 0x00, 0x00, 0x84};
code:
        DS 8
        REQUIRE `?<Initializer for code>`
//    4 /*

//  100 */

        RSEG CODE:CODE:NOROOT(1)
//  101 U8 crc8_3(U8 *buff, U8 num)
crc8_3:
//  102 {
//  103   U8 i, crc = 0;
        LDI    R18, 0
//  104  
//  105   do {
//  106     crc ^= *buff++;
??crc8_3_0:
        MOV    R30, R16
        LD    R19, Z+
        MOV    R16, R30
        EOR    R18, R19
//  107     i   = 8;
        LDI    R19, 8
//  108     do {  
//  109       if (crc & 0x01) {
??crc8_3_1:
        BST    R18, 0
        LSR    R18
        BRTC    ??crc8_3_2
//  110         crc >>= 1;
//  111         crc ^= 0x8C;
        MOV    R20, R18
        LDI    R18, 140
        EOR    R18, R20
//  112       } else {
//  113         crc >>= 1;
//  114       }
//  115     } while (--i);  
??crc8_3_2:
        DEC    R19
        BRNE    ??crc8_3_1
//  116   } while (--num);
        DEC    R17
        BRNE    ??crc8_3_0
//  117   return crc;
        MOV    R16, R18
        RET
//  118 }
//  119

        RSEG TINY_Z:DATA:NOROOT(0)
        REQUIRE `?<Segment init: TINY_Z>`
//  120 volatile U8 result[4];
result:
        DS 4
//  121

        RSEG CODE:CODE:NOROOT(1)
//  122 void main(void)
main:
??main_0:
//  123 {
//  124   while (1) {
//  125     result[0] = 0;
        LDI    R16, 0
        LDI    R30, result
        ST    Z, R16
//  126  /*  
    
//  147  */  
//  148    
//  149 //result[0] = crc8_2(code, 7);
//  150     result[1] = crc8_3(code, 7);
        LDI    R17, 7
        LDI    R16, code
        RCALL    crc8_3
        LDI    R30, result
        STD    Z+1, R16
//  151 //    result[2] = crc8_2(code, 7);
//  152     result[3] = crc8_3(code, 7);
        LDI    R17, 7
        LDI    R16, code
        RCALL    crc8_3
        LDI    R30, result
        STD    Z+3, R16
        RJMP    ??main_0
//  153    
//  154   }
//  155 }

        ASEGN ABSOLUTE:DATA:NOROOT,01cH
__?EECR:

        ASEGN ABSOLUTE:DATA:NOROOT,01dH
__?EEDR:

        ASEGN ABSOLUTE:DATA:NOROOT,01eH
__?EEARL:

        RSEG TINY_ID:CODE:NOROOT(0)
`?<Initializer for code>`:
        DB 1, 208, 94, 60, 13, 0, 0, 132

        RSEG INITTAB:CODE:NOROOT(0)
`?<Segment init: TINY_I>`:
        DB    SFE(TINY_I) - SFB(TINY_I)
        DB    SFB(TINY_I)
        DW    SFB(TINY_ID)
        REQUIRE ?need_segment_init

        RSEG INITTAB:CODE:NOROOT(0)
`?<Segment init: TINY_Z>`:
        DB    SFE(TINY_Z) - SFB(TINY_Z)
        DB    SFB(TINY_Z)
        DW    0
        REQUIRE ?need_segment_init

        END
//  156
//  157 //IAR, opt = max speed, остальные опции выкл.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 25 2006, 17:15
Сообщение #38


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(µµC @ Aug 25 2006, 19:26) *
Приятный алгоритм, возьму на вооружение. IAR - 515 циклов.
Код
U8 crc8_3(U8 *buff, U8 num)
{
  U8 i, crc = 0;
  
  do {
    crc ^= *buff++;
    i   = 8;
    do {  
      if (crc & 0x01) {
        crc >>= 1;
        crc ^= 0x8C;
      } else {
        crc >>= 1;
      }
    } while (--i);  
  } while (--num);
  return crc;
}

Вот, ЭТО уже по настоящему КРУТОЙ алгоритм cheers.gif ,
НО, если уже пошла такая пьянка, то ВОТ:
Код
crc8new:            ;Input: r17:r16 buffer; r18 - number of bytes    
                    ;Output: r16 = CRC

        movw    r31:r30,r17:r16

    ldi    r16,0x00
    ldi    r19,0x8c
crc8new_1:
    ld        r17,Z+
    eor        r16,r17
    ldi        r17,0x08
    rjmp    crc8new_3
crc8new_2:
    lsr        r16
    eor        r16,r19
    dec        r17
    breq    crc8new_4
crc8new_3:
    sbrc    r16,0
    rjmp    crc8new_2
    lsr        r16
    dec        r17
    brne    crc8new_3
crc8new_4:
    dec        r18
    brne    crc8new_1


Всего 427 тактов.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 26 2006, 05:42
Сообщение #39


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Чето слабовато:
Код
__z char crc8_3(char *buff, char num, char poly)
{
  char i, crc = 0;
  do
  {
    crc ^= *buff++;
    i   = 8;
    do
    {
      crc >>=1;
      if (SREG_Bit0) crc^=poly;
    }
    while (--i);
  }
  while (--num);
  return crc;
}

__z char crc8(char *buff, char num)
{
  return crc8_3(buff, num, 0x8C);
}

Зовем конечно crc8

Код
   \                                 In segment CODE, align 2, keep-with-next
     58          __z char crc8_3(char *buff, char num, char poly)
   \                     crc8_3:
     59          {
     60            char i, crc = 0;
   \   00000000   E030               LDI     R19, 0
     61            do
     62            {
     63              crc ^= *buff++;
   \                     ??crc8_3_0:
   \   00000002   9121               LD      R18, Z+
   \   00000004   2732               EOR     R19, R18
     64              i   = 8;
   \   00000006   E028               LDI     R18, 8
     65              do
     66              {
     67                crc >>=1;
   \                     ??crc8_3_1:
   \   00000008   9536               LSR     R19
     68                if (SREG_Bit0) crc^=poly;
   \   0000000A   F408               BRBC    0, ??crc8_3_2
   \   0000000C   2731               EOR     R19, R17
     69              }
     70              while (--i);
   \                     ??crc8_3_2:
   \   0000000E   952A               DEC     R18
   \   00000010   F7D9               BRNE    ??crc8_3_1
     71            }
     72            while (--num);
   \   00000012   950A               DEC     R16
   \   00000014   F7B1               BRNE    ??crc8_3_0
     73            return crc;
   \   00000016   2F03               MOV     R16, R19
   \   00000018   9508               RET
     74          }
     75          

   \                                 In segment CODE, align 2, keep-with-next
     76          __z char crc8(char *buff, char num)
   \                     crc8:
     77          {
     78            return crc8_3(buff, num, 0x8C);
   \   00000000   E81C               LDI     R17, 140
   \   00000002   ....               RJMP    crc8_3
     79          }


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 26 2006, 21:29
Сообщение #40


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Rst7 @ Aug 26 2006, 09:42) *
Чето слабовато:

Цитата
НО, если уже пошла такая пьянка, то ВОТ:
Код
crc8new:           ;Input: r17:r16 buffer; r18 - number of bytes    
                   ;Output: r16 = CRC

        movw    r31:r30,r17:r16

    ldi    r16,0x00
    ldi    r19,0x8c
crc8new_1:
    ld        r17,Z+
    eor        r16,r17
    ldi        r17,0x08
    rjmp    crc8new_3
crc8new_2:
    lsr        r16
    eor        r16,r19
    dec        r17
    breq    crc8new_4
crc8new_3:
    sbrc    r16,0
    rjmp    crc8new_2
    lsr        r16
    dec        r17
    brne    crc8new_3
crc8new_4:
    dec        r18
    brne    crc8new_1


Всего 427 тактов.

Дык это Вообще не мой код, это код сгенерированный WinAVR(-o3) из:

Код
U8 crc8_3(U8 *buff, U8 num)
{
  U8 i, crc = 0;
  
  do {
    crc ^= *buff++;
    i   = 8;
    do {  
      if (crc & 0x01) {
        crc >>= 1;
        crc ^= 0x8C;
      } else {
        crc >>= 1;
      }
    } while (--i);  
  } while (--num);
  return crc;
}

алгоритма предложенного µµC и просто тупо переведенный мною для IAR.
Свой код не готов был уже сгенерить :cheers для данного алгоритма.

Код
__z char crc8_3(char *buff, char num, char poly)
{
  char i, crc = 0;
  do
  {
    crc ^= *buff++;
    i   = 8;
    do
    {
      crc >>=1;
      if (SREG_Bit0) crc^=poly;
    }
    while (--i);
  }
  while (--num);
  return crc;
}

__z char crc8(char *buff, char num)
{
  return crc8_3(buff, num, 0x8C);
}


Вот это мне очень понравилось a14.gif, незнал что так можно писать:
Код
      crc >>=1;
      if (SREG_Bit0) crc^=poly;

КРУТО!!! a14.gif
Но, это уже какой-то асемблерный код smile.gif
Хотя так и не понял зачем там лишняя функция:
Код
__z char crc8(char *buff, char num)
{
  return crc8_3(buff, num, 0x8C);
}

типа для общности???

ИТОГО: (типа подводим итоги): (как автор данного топика кажись мне это можно smile.gif )
1. компиляторам нужно подсказывать как они должны компилировать.
2. алгоритм имеет значительно большее влияние на производительность
чем просто тупое улучшение неудачного алгоритма.
3. учим матчасть:
Код
__z

Код
      crc >>=1;
      if (SREG_Bit0) crc^=poly;


ИТОГО N 2:

µµC a14.gif за оригинальный алгоритм.
Rst7 a14.gif за "__z".
Rst7 a14.gif за очень грамонтную реализацию предложенного алгоритма :
Код
__z char crc8_3(char *buff, char num, char poly)
{
  char i, crc = 0;
  do
  {
    crc ^= *buff++;
    i   = 8;
    do
    {
      crc >>=1;
      if (SREG_Bit0) crc^=poly;
    }
    while (--i);
  }
  while (--num);
  return crc;
}

__z char crc8(char *buff, char num)
{
  return crc8_3(buff, num, 0x8C);
}


Все кто принял участие в данном обсуждение, спасибо.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 27 2006, 05:20
Сообщение #41


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(singlskv @ Aug 27 2006, 00:29) *
Хотя так и не понял зачем там лишняя функция:
Код
__z char crc8(char *buff, char num)
{
  return crc8_3(buff, num, 0x8C);
}

типа для общности???


Нет, тут хитрость, без этого IAR психует и грузит 0x8C непосредственно перед выполнением xor, т.е. каждый раз в цикле, итого +1*8*sizeof по тактам. Чето там у него не срослось с отделением инвариантного кода. А так лечим, заставляем его принципиально xor с переменной делать. Так что это тоже шаманство wink.gif

Цитата
Все кто принял участие в данном обсуждение, спасибо.

Лишь бы на здоровье wink.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 27 2006, 05:38
Сообщение #42


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



В досыл...

Цитата(singlskv @ Aug 27 2006, 00:29) *
Вот это мне очень понравилось a14.gif, незнал что так можно писать:
Код
      crc >>=1;
      if (SREG_Bit0) crc^=poly;

КРУТО!!! a14.gif
Но, это уже какой-то асемблерный код smile.gif


Ну с этим надо поаккуратнее, а то в следующий раз может переоптимизировать нафиг все, например местами поменять сдвиг и проверку. А вообще-то эта идея родилась при реализации TCP/IP стека, там надо считать контрольные суммы с учетом переноса при прибавлении к 16-битному инту, его надо добавлять к сумме. А код, как вы понимаете, все время кривой. В результате родилось такое:
Код
unsigned int rxcrc; //Контрольная сумма в принимаемом пакете

#pragma optimize=no_inline
void subrxcrc(unsigned int i)
{
i=rxcrc-i;
if (_CARRY) i--;
rxcrc=i;
}


Быстро и качественно:
Код
     98          #pragma optimize=no_inline

   \                                 In segment CODE, align 2, keep-with-next
     99          void subrxcrc(unsigned int i)
   \                     subrxcrc:
    100          {
   \   00000000                      REQUIRE __RSTACK_in_external_ram
    101           i=rxcrc-i;
   \   00000000   ....               LDI     R30, LOW(rxcrc)
   \   00000002   ....               LDI     R31, (rxcrc) >> 8
   \   00000004                      REQUIRE ?Subroutine0
   \   00000004                     ;               // Fall through to label ?Subroutine0
    102           if (_CARRY) i--;
    103           rxcrc=i;
    104          }

   \                                 In segment CODE, align 2, keep-with-next
   \                     ?Subroutine0:
   \   00000000   8120               LD      R18, Z
   \   00000002   8131               LDD     R19, Z+1
   \   00000004   1B20               SUB     R18, R16
   \   00000006   0B31               SBC     R19, R17
   \   00000008   0189               MOVW    R17:R16, R19:R18
   \   0000000A   F410               BRBC    0, ??Subroutine0_0
   \   0000000C   5001               SUBI    R16, 1
   \   0000000E   4010               SBCI    R17, 0
   \                     ??Subroutine0_0:
   \   00000010   8300               ST      Z, R16
   \   00000012   8311               STD     Z+1, R17
   \   00000014   9508               RET


Тоже гон, конечно (MOVW там совсем лишний), но намного лучше других способов...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
µµC
сообщение Aug 27 2006, 09:30
Сообщение #43


Участник
*

Группа: Новичок
Сообщений: 44
Регистрация: 2-05-06
Пользователь №: 16 710



А что такое "__z"? Что нужно сделать чтоб этим пользоваться, где почитать? WinAVR 2006421 пишет: * crc8.c, line 104: error: syntax error before "unsigned"
В описании упоминаний не нашел.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 27 2006, 09:56
Сообщение #44


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(µµC @ Aug 27 2006, 12:30) *
А что такое "__z"? Что нужно сделать чтоб этим пользоваться, где почитать? WinAVR 2006421 пишет: * crc8.c, line 104: error: syntax error before "unsigned"
В описании упоминаний не нашел.


Это IAR-овская фича, в GNU такого нет. В IAR-е этот модификатор говорит, что первый указатель будет передан через регистр Z. Еще есть модификаторы __x, __z_x, __x_z, соответственно использование X для передачи первого указателя, использование Z для первого, X для второго и наоборот.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
µµC
сообщение Aug 27 2006, 10:10
Сообщение #45


Участник
*

Группа: Новичок
Сообщений: 44
Регистрация: 2-05-06
Пользователь №: 16 710



Цитата(Rst7 @ Aug 27 2006, 13:56) *
Понял. спасибо. В IAR этим пользуюсь. Просто мне почему-то показалось, что singlskv тоже может, а IAR у него нет.
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 9th August 2025 - 17:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.0165 секунд с 7
ELECTRONIX ©2004-2016