|
Оптимизация алгоритма на С, вопрос к знатокам компиляторов |
|
|
|
Aug 23 2006, 21:50
|
дятел
    
Группа: Свой
Сообщений: 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% быстрее. Собственно вопрос: а есть ли компилятор который может скомпилировать эти две(одинаковых!) функции в одинаковый(быстрый) код ?
|
|
|
|
|
 |
Ответов
|
Aug 24 2006, 09:41
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Aug 24 2006, 04:36)  Вы уверены что у вас считается именно CRC? Да уверен. Это CRC для 1-wire по полиному X8+X5+X4+1. Цитата(KRS @ Aug 24 2006, 11:52)  конечно 2 вариант быстрее! дело в организации цикла! Ну в этом и вопрос, умеет ли какой-нибудь компилятор разбираться с такой ситуацией. Цитата(vet @ Aug 24 2006, 10:56)  Цитата(singlskv @ Aug 24 2006, 01:50)  Собственно вопрос: а есть ли компилятор который может скомпилировать эти две(одинаковых!) функции в одинаковый(быстрый) код ? IAR. Вы проверяли ? Если да, то сообщите пожалуйста сколько тактов получилось у каждой функции при наилучшей оптимизации. Цитата(Old1 @ Aug 24 2006, 13:28)  К сожалению нет времени проверять... Вы уверены, что IAR эти функции скомпилирует одинаково оптимально? Вопрос задаю потому, что сами ИАРовцы рекомендуют (AN AVR035) для оптимизации кода по возможности использовать вычитающие циклические счетчики и предварительный декремент. Собственно, если кто проверит, сообщите результат.
|
|
|
|
|
Aug 24 2006, 12:41
|
Участник

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

|
Цитата(singlskv @ Aug 24 2006, 13:41)  Да уверен. Это CRC для 1-wire по полиному X8+X5+X4+1. Код U8 CRC8_1 (U8 val, U8 crc) { U8 tmp; U8 i = 8; do { tmp = (val ^ crc) & 0x01; crc >>= 1; val >>= 1; if (tmp != 0) crc ^= 0x8c; } while (--i); return crc; }
U8 CRC8_2(U8 data, U8 crc) { U8 i = data ^ crc; crc = 0; if (i & 0x01) crc ^= 0x5e; if (i & 0x02) crc ^= 0xbc; if (i & 0x04) crc ^= 0x61; if (i & 0x08) crc ^= 0xc2; if (i & 0x10) crc ^= 0x9d; if (i & 0x20) crc ^= 0x23; if (i & 0x40) crc ^= 0x46; if (i & 0x80) crc ^= 0x8c; return crc; } CRC8_1 это твой вариант для одного байта. CRC8_2 имеет тот же полином, но работает значительно быстрее.
Сообщение отредактировал µµC - Aug 24 2006, 12:43
|
|
|
|
|
Aug 24 2006, 19:35
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(µµC @ Aug 24 2006, 16:41)  Цитата(singlskv @ Aug 24 2006, 13:41)  Да уверен. Это CRC для 1-wire по полиному X8+X5+X4+1.
Код U8 CRC8_1 (U8 val, U8 crc) { U8 tmp; U8 i = 8; do { tmp = (val ^ crc) & 0x01; crc >>= 1; val >>= 1; if (tmp != 0) crc ^= 0x8c; } while (--i); return crc; }
U8 CRC8_2(U8 data, U8 crc) { U8 i = data ^ crc; crc = 0; if (i & 0x01) crc ^= 0x5e; if (i & 0x02) crc ^= 0xbc; if (i & 0x04) crc ^= 0x61; if (i & 0x08) crc ^= 0xc2; if (i & 0x10) crc ^= 0x9d; if (i & 0x20) crc ^= 0x23; if (i & 0x40) crc ^= 0x46; if (i & 0x80) crc ^= 0x8c; return crc; } CRC8_1 это твой вариант для одного байта. CRC8_2 имеет тот же полином, но работает значительно быстрее. Если несложно, то просимулируйте для 7 байт(как в изначальной задаче), и напишите сколько получилось тактов для этих двух вариантов.
|
|
|
|
|
Aug 24 2006, 20:20
|
Участник

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

|
Цитата(singlskv @ Aug 24 2006, 23:35)  Если несложно, то просимулируйте для 7 байт(как в изначальной задаче), и напишите сколько получилось тактов для этих двух вариантов. Код #define U8 unsigned char
U8 code[8] = {0x01, 0xd0, 0x5e, 0x3c, 0x0d, 0x00, 0x00, 0x84};
U8 crc8_1(U8 *buff, U8 num) { U8 i, tmp, val, crc = 0; do { val = *buff++; i = 8; do { tmp = (val ^ crc); crc >>= 1; val >>= 1; if (tmp & 0x01) crc ^= 0x8c; } while (--i); } while (--num); return crc; }
U8 crc8_2(U8 *buff, U8 num) { U8 val, crc = 0; do { val = *buff++; val ^= crc; crc = 0; if(val & 0x01) crc ^= 0x5e; if(val & 0x02) crc ^= 0xbc; if(val & 0x04) crc ^= 0x61; if(val & 0x08) crc ^= 0xc2; if(val & 0x10) crc ^= 0x9d; if(val & 0x20) crc ^= 0x23; if(val & 0x40) crc ^= 0x46; if(val & 0x80) crc ^= 0x8c; } while (--num); return crc; }
volatile U8 result[4];
void main(void) { while (1) { result[0] = crc8_1(code, 7); //649 result[1] = crc8_2(code, 7); //265 result[2] = crc8_1(code, 7); result[3] = crc8_2(code, 7); } } IAR, opt = max speed, остальные опции выкл. 649 циклов к 265.
|
|
|
|
|
Aug 24 2006, 20:45
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(µµC @ Aug 25 2006, 00:20)  Цитата(singlskv @ Aug 24 2006, 23:35)  Если несложно, то просимулируйте для 7 байт(как в изначальной задаче), и напишите сколько получилось тактов для этих двух вариантов.
Код #define U8 unsigned char
U8 code[8] = {0x01, 0xd0, 0x5e, 0x3c, 0x0d, 0x00, 0x00, 0x84};
U8 crc8_1(U8 *buff, U8 num) { U8 i, tmp, val, crc = 0; do { val = *buff++; i = 8; do { tmp = (val ^ crc); crc >>= 1; val >>= 1; if (tmp & 0x01) crc ^= 0x8c; } while (--i); } while (--num); return crc; }
U8 crc8_2(U8 *buff, U8 num) { U8 val, crc = 0; do { val = *buff++; val ^= crc; crc = 0; if(val & 0x01) crc ^= 0x5e; if(val & 0x02) crc ^= 0xbc; if(val & 0x04) crc ^= 0x61; if(val & 0x08) crc ^= 0xc2; if(val & 0x10) crc ^= 0x9d; if(val & 0x20) crc ^= 0x23; if(val & 0x40) crc ^= 0x46; if(val & 0x80) crc ^= 0x8c; } while (--num); return crc; }
volatile U8 result[4];
void main(void) { while (1) { result[0] = crc8_1(code, 7); //649 result[1] = crc8_2(code, 7); //265 result[2] = crc8_1(code, 7); result[3] = crc8_2(code, 7); } } IAR, opt = max speed, остальные опции выкл. 649 циклов к 265. 649 уже намного ближе к правде (если не сложно, листинг в студию), но у WinAVR 544. 265 - отличный результат, но мы обсуждаем алгоритм(оптимизацию компилятором) в общем виде (таблицой из 256 значений как в даташите "1-wire" все равно быстрее).
|
|
|
|
|
Aug 24 2006, 21:03
|
Участник

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

|
Цитата(singlskv @ Aug 25 2006, 00:45)  если не сложно, листинг в студию 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_1 PUBLIC crc8_2 PUBLIC main PUBLIC result RSEG TINY_I:DATA:NOROOT(0) REQUIRE `?<Segment init: TINY_I>` // 49 U8 code[8] = {0x01, 0xd0, 0x5e, 0x3c, 0x0d, 0x00, 0x00, 0x84}; code: DS 8 REQUIRE `?<Initializer for code>` // 50 RSEG CODE:CODE:NOROOT(1) // 51 U8 crc8_1(U8 *buff, U8 num) crc8_1: // 52 { // 53 U8 i, tmp, val, crc = 0; LDI R19, 0 // 54 // 55 do { // 56 val = *buff++; ??crc8_1_0: MOV R30, R16 LD R21, Z+ MOV R16, R30 // 57 i = 8; LDI R18, 8 // 58 do { // 59 tmp = (val ^ crc); ??crc8_1_1: MOV R20, R19 EOR R20, R21 // 60 crc >>= 1; LSR R19 // 61 val >>= 1; LSR R21 // 62 if (tmp & 0x01) crc ^= 0x8c; BST R20, 0 BRTC ??crc8_1_2 LDI R20, 140 EOR R19, R20 // 63 } while (--i); ??crc8_1_2: DEC R18 BRNE ??crc8_1_1 // 64 } while (--num); DEC R17 BRNE ??crc8_1_0 // 65 return crc; MOV R16, R19 RET // 66 } // 67 RSEG CODE:CODE:NOROOT(1) // 68 U8 crc8_2(U8 *buff, U8 num) crc8_2: // 69 { // 70 U8 val, crc = 0; LDI R18, 0 // 71 // 72 do { // 73 val = *buff++; ??crc8_2_0: MOV R30, R16 LD R20, Z+ MOV R16, R30 // 74 val ^= crc; EOR R20, R18 // 75 crc = 0; LDI R18, 0 // 76 if(val & 0x01) crc ^= 0x5e; BST R20, 0 BRTC ??crc8_2_1 LDI R18, 94 // 77 if(val & 0x02) crc ^= 0xbc; ??crc8_2_1: BST R20, 1 BRTC ??crc8_2_2 LDI R19, 188 EOR R18, R19 // 78 if(val & 0x04) crc ^= 0x61; ??crc8_2_2: BST R20, 2 BRTC ??crc8_2_3 LDI R19, 97 EOR R18, R19 // 79 if(val & 0x08) crc ^= 0xc2; ??crc8_2_3: BST R20, 3 BRTC ??crc8_2_4 LDI R19, 194 EOR R18, R19 // 80 if(val & 0x10) crc ^= 0x9d; ??crc8_2_4: BST R20, 4 BRTC ??crc8_2_5 LDI R19, 157 EOR R18, R19 // 81 if(val & 0x20) crc ^= 0x23; ??crc8_2_5: BST R20, 5 BRTC ??crc8_2_6 LDI R19, 35 EOR R18, R19 // 82 if(val & 0x40) crc ^= 0x46; ??crc8_2_6: BST R20, 6 BRTC ??crc8_2_7 LDI R19, 70 EOR R18, R19 // 83 if(val & 0x80) crc ^= 0x8c; ??crc8_2_7: BST R20, 7 BRTC ??crc8_2_8 LDI R19, 140 EOR R18, R19 // 84 } while (--num); ??crc8_2_8: DEC R17 BRNE ??crc8_2_0 // 85 return crc; MOV R16, R18 RET // 86 } // 87 RSEG TINY_Z:DATA:NOROOT(0) REQUIRE `?<Segment init: TINY_Z>` // 88 volatile U8 result[4]; result: DS 4 // 89 RSEG CODE:CODE:NOROOT(1) // 90 void main(void) main: ??main_0: // 91 { // 92 while (1) { // 93 result[0] = crc8_1(code, 7); //649 LDI R17, 7 LDI R16, code RCALL crc8_1 LDI R30, result ST Z, R16 // 94 result[1] = crc8_2(code, 7); //265 LDI R17, 7 LDI R16, code RCALL crc8_2 LDI R30, result STD Z+1, R16 // 95 result[2] = crc8_1(code, 7); LDI R17, 7 LDI R16, code RCALL crc8_1 LDI R30, result STD Z+2, R16 // 96 result[3] = crc8_2(code, 7); LDI R17, 7 LDI R16, code RCALL crc8_2 LDI R30, result STD Z+3, R16 RJMP ??main_0 // 97 } // 98 } 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
|
|
|
|
Сообщений в этой теме
singlskv Оптимизация алгоритма на С Aug 23 2006, 21:50       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 vet Скомпилировал в IAR 4.11A два цикла for с инкремен... Aug 24 2006, 10:20 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 singlskv Цитата(vet @ Aug 24 2006, 14:20) Скомпили... Aug 24 2006, 19:24  Rst7 Цитата(singlskv @ Aug 24 2006, 22:24) оче... Aug 25 2006, 06:13 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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|