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

 
 
> Оптимизация алгоритма на С, вопрос к знатокам компиляторов
singlskv
сообщение Aug 23 2006, 21:50
Сообщение #1


дятел
*****

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



Есть два варианта функции вычисления CRC:
Код
unsigned char code[8]={0x01,0xd0,0x5e,0x3c,0x0d,0x00,0x00,0x84};

unsigned char crc8_1(unsigned char *buff,unsigned char num)
{
    unsigned char i=0,j,tmp,data,crc=0;
    for (i=0;i<num;i++) {
        data=*buff++;
        for (j=0;j<8;j++) {
            tmp=1&(data^crc);
            crc>>=1;
            data>>=1;
            if (tmp!=0) crc^=0x8c;
        }
    }
    return crc;
}

unsigned char crc8_2(unsigned char *buff,unsigned char num)
{
    unsigned char i=num,j,tmp,data,crc=0;
    for (;i>0;i--) {
        data=*buff++;
        for (j=8;j>0;j--) {
            tmp=1&(data^crc);
            crc>>=1;
            data>>=1;
            if (tmp!=0) crc^=0x8c;
        }
    }
    return crc;
}

int main(int argc, char* argv[])
{
    unsigned char crc_;
    crc_=crc8_1(code,7);
    crc_=crc8_2(code,7);
    return 0;
}


Как видно из рисунка, это собственно один и тот же алгоритм.
Но, при компиляции под WinAVR(gcc), при любом уровне оптимизации, второй
вариант работает на 10-15% быстрее.
Собственно вопрос: а есть ли компилятор который может скомпилировать
эти две(одинаковых!) функции в одинаковый(быстрый) код ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
vet
сообщение Aug 24 2006, 10:20
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Скомпилировал в IAR 4.11A два цикла for с инкрементом от 0 до 8 и декрементом от 8 до 0, макс.оптимизация по скорости. Код одинаков.
Код
        RSEG CODE:CODE:NOROOT(1)
//    3 void main() {
main:
//    4 char i;

//    5   for (i=0;i<8;i++) {
        LDI    R16, 8
//    6     asm("nop");
??main_0:
        nop
//    7   }
        DEC    R16
        BRNE    ??main_0

//    8   for (i=8;i;i--) {
        LDI    R16, 8
//    9     asm("nop");
??main_1:
        nop
//   10   }
        DEC    R16
        BRNE    ??main_1

//   11 }
        RET



Выкладываю листинг компиляции вышеприведённого исходника:
Код
        RSEG CODE:CODE:NOROOT(1)
//    3 unsigned char crc8_1(unsigned char *buff,unsigned char num)
crc8_1:
//    4 {
//    5     unsigned char i=0,j,tmp,data,crc=0;
        LDI    R21, 0
//    6     for (i=0;i<num;i++) {
        LDI    R20, 0
        RJMP    ??crc8_1_0
//    7         data=*buff++;
??crc8_1_1:
        MOVW    R31:R30, R17:R16
        LD    R23, Z+
        MOVW    R17:R16, R31:R30
//    8         for (j=0;j<8;j++) {
        LDI    R19, 8
//    9             tmp=1&(data^crc);
??crc8_1_2:
        MOV    R0, R23
        BST    R0, 0
        CLR    R0
        BLD    R0, 0
        MOV    R22, R21
        ANDI    R22, 0x01
        EOR    R22, R0
        ANDI    R22, 0x01
//   10             crc>>=1;
        LSR    R21
//   11             data>>=1;
        LSR    R23
//   12             if (tmp!=0) crc^=0x8c;
        TST    R22
        BREQ    ??crc8_1_3
        LDI    R22, 140
        EOR    R21, R22
//   13         }
??crc8_1_3:
        DEC    R19
        BRNE    ??crc8_1_2
//   14     }
        INC    R20
??crc8_1_0:
        CP    R20, R18
        BRCS    ??crc8_1_1
//   15     return crc;
        MOV    R16, R21
        RET
//   16 }
//   17

        RSEG CODE:CODE:NOROOT(1)
//   18 unsigned char crc8_2(unsigned char *buff,unsigned char num)
crc8_2:
//   19 {
//   20     unsigned char i=num,j,tmp,data,crc=0;
        MOV    R19, R18
        LDI    R20, 0
        RJMP    ??crc8_2_0
//   21     for (;i>0;i--) {
//   22         data=*buff++;
??crc8_2_1:
        MOVW    R31:R30, R17:R16
        LD    R22, Z+
        MOVW    R17:R16, R31:R30
//   23         for (j=8;j>0;j--) {
        LDI    R18, 8
//   24             tmp=1&(data^crc);
??crc8_2_2:
        MOV    R23, R22
        ANDI    R23, 0x01
        MOV    R21, R20
        ANDI    R21, 0x01
        EOR    R21, R23
        ANDI    R21, 0x01
//   25             crc>>=1;
        LSR    R20
//   26             data>>=1;
        LSR    R22
//   27             if (tmp!=0) crc^=0x8c;
        TST    R21
        BREQ    ??crc8_2_3
        LDI    R21, 140
        EOR    R20, R21
//   28         }
??crc8_2_3:
        DEC    R18
        BRNE    ??crc8_2_2
//   29     }
        DEC    R19
??crc8_2_0:
        TST    R19
        BRNE    ??crc8_2_1
//   30     return crc;
        MOV    R16, R20
        RET
//   31 }
//   32

Во второй функции компилятор решил задачу по-другому, но накладные расходы на цикл одинаковы в обеих функциях.

Сообщение отредактировал vet - Aug 24 2006, 10:37


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 24 2006, 19:24
Сообщение #3


дятел
*****

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



Цитата(vet @ Aug 24 2006, 14:20) *
Скомпилировал в IAR 4.11A два цикла for с инкрементом от 0 до 8 и декрементом от 8 до 0, макс.оптимизация по скорости. Код одинаков.
Код
        RSEG CODE:CODE:NOROOT(1)
//    3 void main() {
main:
//    4 char i;

//    5   for (i=0;i<8;i++) {
        LDI    R16, 8
   ..............................................................


Вы попробуйте два вложенных цикла, как в моем примере,
да и еще что нибудь кроме nop вставте в середину.

Цитата(vet @ Aug 24 2006, 14:20) *
Выкладываю листинг компиляции вышеприведённого исходника:

Код
        RSEG CODE:CODE:NOROOT(1)
//    3 unsigned char crc8_1(unsigned char *buff,unsigned char num)
crc8_1:
//    4 {
//    5     unsigned char i=0,j,tmp,data,crc=0;
        LDI    R21, 0
//    6     for (i=0;i<num;i++) {
        LDI    R20, 0
        RJMP    ??crc8_1_0
//    7         data=*buff++;
??crc8_1_1:
        MOVW    R31:R30, R17:R16
        LD    R23, Z+
        MOVW    R17:R16, R31:R30
//    8         for (j=0;j<8;j++) {
        LDI    R19, 8
//    9             tmp=1&(data^crc);
??crc8_1_2:
        MOV    R0, R23
        BST    R0, 0
        CLR    R0
        BLD    R0, 0
        MOV    R22, R21
        ANDI    R22, 0x01
        EOR    R22, R0
        ANDI    R22, 0x01
//   10             crc>>=1;
        LSR    R21
//   11             data>>=1;
        LSR    R23
//   12             if (tmp!=0) crc^=0x8c;
        TST    R22
        BREQ    ??crc8_1_3
        LDI    R22, 140
        EOR    R21, R22
//   13         }
??crc8_1_3:
        DEC    R19
        BRNE    ??crc8_1_2
//   14     }
        INC    R20
??crc8_1_0:
        CP    R20, R18
        BRCS    ??crc8_1_1
//   15     return crc;
        MOV    R16, R21
        RET
//   16 }
//   17

        RSEG CODE:CODE:NOROOT(1)
//   18 unsigned char crc8_2(unsigned char *buff,unsigned char num)
crc8_2:
//   19 {
//   20     unsigned char i=num,j,tmp,data,crc=0;
        MOV    R19, R18
        LDI    R20, 0
        RJMP    ??crc8_2_0
//   21     for (;i>0;i--) {
//   22         data=*buff++;
??crc8_2_1:
        MOVW    R31:R30, R17:R16
        LD    R22, Z+
        MOVW    R17:R16, R31:R30
//   23         for (j=8;j>0;j--) {
        LDI    R18, 8
//   24             tmp=1&(data^crc);
??crc8_2_2:
        MOV    R23, R22
        ANDI    R23, 0x01
        MOV    R21, R20
        ANDI    R21, 0x01
        EOR    R21, R23
        ANDI    R21, 0x01
//   25             crc>>=1;
        LSR    R20
//   26             data>>=1;
        LSR    R22
//   27             if (tmp!=0) crc^=0x8c;
        TST    R21
        BREQ    ??crc8_2_3
        LDI    R21, 140
        EOR    R20, R21
//   28         }
??crc8_2_3:
        DEC    R18
        BRNE    ??crc8_2_2
//   29     }
        DEC    R19
??crc8_2_0:
        TST    R19
        BRNE    ??crc8_2_1
//   30     return crc;
        MOV    R16, R20
        RET
//   31 }
//   32

Во второй функции компилятор решил задачу по-другому, но накладные расходы на цикл одинаковы в обеих функциях.


Просимулировал Ваш код в AVR Studio.
Итого: (для семи байт)
crc8_1 986 тактов
crc8_2 774 такта blink.gif
разница слегка удивила, это уже 25%. smile.gif

очень повеселил этот код:
Код
        MOVW    R31:R30, R17:R16
        LD    R22, Z+
        MOVW    R17:R16, R31:R30

и так 7 раз подряд cranky.gif
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 25 2006, 06:13
Сообщение #4


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

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



Цитата(singlskv @ Aug 24 2006, 22:24) *
очень повеселил этот код:
Код
        MOVW    R31:R30, R17:R16
        LD    R22, Z+
        MOVW    R17:R16, R31:R30

и так 7 раз подряд cranky.gif


Хорошо поможет
Код
__z unsigned char crc8_2(unsigned char *buff,unsigned char num)

А циклы ОЧЕНЬ желательно делать
Код
do{}while(--var);

это помогает почти всем компиляторам и процессорам, обычно архитектура процессора позволяет изготовить нечто такое:
Код
DEC var
JUMP_IF_NZ label


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

Сообщений в этой теме
- singlskv   Оптимизация алгоритма на С   Aug 23 2006, 21:50
- - defunct   Вы уверены что у вас считается именно CRC? Попробу...   Aug 24 2006, 00:36
|- - singlskv   Цитата(defunct @ Aug 24 2006, 04:36) Вы у...   Aug 24 2006, 09:41
|- - µµC   Цитата(singlskv @ Aug 24 2006, 13:41) Да ...   Aug 24 2006, 12:41
|- - singlskv   Цитата(µµC @ Aug 24 2006, 16:41) Цитата(s...   Aug 24 2006, 19:35
|- - µµC   Цитата(singlskv @ Aug 24 2006, 23:35) Есл...   Aug 24 2006, 20:20
|- - singlskv   Цитата(µµC @ Aug 25 2006, 00:20) Цитата(s...   Aug 24 2006, 20:45
|- - µµC   Цитата(singlskv @ Aug 25 2006, 00:45) есл...   Aug 24 2006, 21:03
|- - singlskv   Цитата(µµC @ Aug 25 2006, 01:03) Цитата(s...   Aug 24 2006, 21:20
- - KRS   конечно 2 вариант быстрее! дело в организации ...   Aug 24 2006, 07:52
- - vet   Цитата(singlskv @ Aug 24 2006, 01:50) Соб...   Aug 24 2006, 07:56
|- - Old1   Цитата(vet @ Aug 24 2006, 10:56) Цитата(s...   Aug 24 2006, 09:28
|- - Old1   Цитата(vet @ Aug 24 2006, 13:20) Скомпили...   Aug 24 2006, 17:12
||- - µµC   Цитата(Old1 @ Aug 24 2006, 21:12) Но если...   Aug 24 2006, 19:24
||- - singlskv   Цитата(µµC @ Aug 24 2006, 23:24) Человек ...   Aug 24 2006, 20:29
||- - µµC   Цитата(singlskv @ Aug 25 2006, 00:29) Луч...   Aug 24 2006, 20:41
|||- - zltigo   Цитата(µµC @ Aug 24 2006, 23:41) Цитата(s...   Aug 24 2006, 21:00
|||- - singlskv   Цитата(zltigo @ Aug 25 2006, 01:00) Быстр...   Aug 24 2006, 21:50
||- - _Bill   Цитата(singlskv @ Aug 24 2006, 23:29) Цит...   Aug 25 2006, 11:17
||- - singlskv   Цитата(_Bill @ Aug 25 2006, 15:17) Цитата...   Aug 25 2006, 11:26
||- - _Bill   Цитата(singlskv @ Aug 25 2006, 14:26) так...   Aug 25 2006, 11:47
||- - singlskv   Цитата(_Bill @ Aug 25 2006, 15:47) Цитата...   Aug 25 2006, 12:30
||- - _Bill   Цитата(singlskv @ Aug 25 2006, 15:30) Вот...   Aug 25 2006, 12:59
||- - _Bill   Цитата(singlskv @ Aug 25 2006, 15:30) Вот...   Aug 25 2006, 13:30
||- - singlskv   Цитата(_Bill @ Aug 25 2006, 17:30) Вот ре...   Aug 25 2006, 13:49
- - Serg79   В таких случаях поступают намного проше, пишут фун...   Aug 25 2006, 06:07
|- - singlskv   Цитата(Serg79 @ Aug 25 2006, 10:07) В так...   Aug 25 2006, 08:24
|- - Rst7   Цитата(singlskv @ Aug 25 2006, 11:24) Ну ...   Aug 25 2006, 08:42
- - TomaT   Эх... у 51-го чудная инструкция есть -- DJNZ   Aug 25 2006, 06:25
|- - Rst7   Цитата(TomaT @ Aug 25 2006, 09:25) Эх... ...   Aug 25 2006, 07:48
- - SpiritDance   Она особенно чудна для конвееров.   Aug 25 2006, 07:23
- - µµC   Приятный алгоритм, возьму на вооружение. IAR - 515...   Aug 25 2006, 15:26
|- - singlskv   Цитата(µµC @ Aug 25 2006, 19:26) Приятный...   Aug 25 2006, 15:38
||- - µµC   Цитата(singlskv @ Aug 25 2006, 19:38) а л...   Aug 25 2006, 16:19
|- - singlskv   Цитата(µµC @ Aug 25 2006, 19:26) Приятный...   Aug 25 2006, 17:15
- - Rst7   Чето слабовато: Код__z char crc8_3(char *buff,...   Aug 26 2006, 05:42
|- - singlskv   Цитата(Rst7 @ Aug 26 2006, 09:42) Чето сл...   Aug 26 2006, 21:29
|- - Rst7   Цитата(singlskv @ Aug 27 2006, 00:29) Хот...   Aug 27 2006, 05:20
|- - Rst7   В досыл... Цитата(singlskv @ Aug 27 2006, 00...   Aug 27 2006, 05:38
- - µµC   А что такое "__z"? Что нужно сделать что...   Aug 27 2006, 09:30
- - Rst7   Цитата(µµC @ Aug 27 2006, 12:30) А что та...   Aug 27 2006, 09:56
- - µµC   Цитата(Rst7 @ Aug 27 2006, 13:56) Понял. ...   Aug 27 2006, 10:10


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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 12:37
Рейтинг@Mail.ru


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