|
Оптимизация алгоритма на С, вопрос к знатокам компиляторов |
|
|
|
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% быстрее. Собственно вопрос: а есть ли компилятор который может скомпилировать эти две(одинаковых!) функции в одинаковый(быстрый) код ?
|
|
|
|
|
 |
Ответов
Guest_Serg79_*
|
Aug 25 2006, 06:07
|
Guests

|
В таких случаях поступают намного проше, пишут функцию на ASM и не ломают голову на счет компилятора. Код /** \ingroup util_crc Optimized Dallas (now Maxim) iButton 8-bit CRC calculation.
Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)<br> Initial value: 0x0
See http://www.maxim-ic.com/appnotes.cfm/appnote_number/27
The following is the equivalent functionality written in C.
\code uint8_t _crc_ibutton_update(uint8_t crc, uint8_t data) { uint8_t i;
crc = crc ^ data; for (i = 0; i < 8; i++) { if (crc & 0x01) crc = (crc >> 1) ^ 0x8C; else crc >>= 1; }
return crc; } \endcode */
static __inline__ uint8_t _crc_ibutton_update(uint8_t __crc, uint8_t __data) { uint8_t __i, __pattern; __asm__ __volatile__ ( " eor %0, %4" "\n\t" " ldi %1, 8" "\n\t" " ldi %2, 0x8C" "\n\t" "1: bst %0, 0" "\n\t" " lsr %0" "\n\t" " brtc 2f" "\n\t" " eor %0, %2" "\n\t" "2: dec %1" "\n\t" " brne 1b" "\n\t" : "=r" (__crc), "=d" (__i), "=d" (__pattern) : "0" (__crc), "r" (__data)); return __crc; } И я так думаю, что эта функция будет работать быстрее приведенных выше. Реализация функции взята из заголовочного файла "crc16.h" компилятора WinAVR. А принцип простой: не изобретай велосипед. Лучше направить свои усилия на что то новое, чем пытаться заново писать стандартные функции, реализованные в библиотеках идущих вместе с компилятором.
|
|
|
|
|
Aug 25 2006, 08:24
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Serg79 @ Aug 25 2006, 10:07)  В таких случаях поступают намного проше, пишут функцию на ASM и не ломают голову на счет компилятора. Код /** \ingroup util_crc Optimized Dallas (now Maxim) iButton 8-bit CRC calculation.
Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)<br> Initial value: 0x0
See http://www.maxim-ic.com/appnotes.cfm/appnote_number/27
The following is the equivalent functionality written in C.
\code uint8_t _crc_ibutton_update(uint8_t crc, uint8_t data) { uint8_t i;
crc = crc ^ data; for (i = 0; i < 8; i++) { if (crc & 0x01) crc = (crc >> 1) ^ 0x8C; else crc >>= 1; }
return crc; } \endcode */
static __inline__ uint8_t _crc_ibutton_update(uint8_t __crc, uint8_t __data) { uint8_t __i, __pattern; __asm__ __volatile__ ( " eor %0, %4" "\n\t" " ldi %1, 8" "\n\t" " ldi %2, 0x8C" "\n\t" "1: bst %0, 0" "\n\t" " lsr %0" "\n\t" " brtc 2f" "\n\t" " eor %0, %2" "\n\t" "2: dec %1" "\n\t" " brne 1b" "\n\t" : "=r" (__crc), "=d" (__i), "=d" (__pattern) : "0" (__crc), "r" (__data)); return __crc; } И я так думаю, что эта функция будет работать быстрее приведенных выше. Реализация функции взята из заголовочного файла "crc16.h" компилятора WinAVR. А принцип простой: не изобретай велосипед. Лучше направить свои усилия на что то новое, чем пытаться заново писать стандартные функции, реализованные в библиотеках идущих вместе с компилятором. Думать не нужно, надо пробовать (С). Выполните Ваш код для 7 байтов, а потом внимательно перечитайте весь топик. Цитата(Rst7 @ Aug 25 2006, 10:13)  Цитата(singlskv @ Aug 24 2006, 22:24)  очень повеселил этот код: Код MOVW R31:R30, R17:R16 LD R22, Z+ MOVW R17:R16, R31:R30 и так 7 раз подряд  Хорошо поможет Код __z unsigned char crc8_2(unsigned char *buff,unsigned char num) Вот это ОЧЕНЬ ценный совет Цитата(Rst7 @ Aug 25 2006, 10:13)  А циклы ОЧЕНЬ желательно делать Код do{}while(--var); это помогает почти всем компиляторам и процессорам, обычно архитектура процессора позволяет изготовить нечто такое: Код DEC var JUMP_IF_NZ label Ну с этим никто и не спорит, только это уже получается не "оптимизирующий" компилятор, а "оптимизируемый пользователем" компилятор.
|
|
|
|
Сообщений в этой теме
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 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  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
|
|
|