|
как побороть WinAVR?, и заставить просто скомпиллить как написано |
|
|
|
Aug 7 2008, 17:01
|
Частый гость
 
Группа: Участник
Сообщений: 152
Регистрация: 18-03-06
Пользователь №: 15 366

|
написана функция:
volatile int32_t _corr[2 * 8];//result of correlations volatile uint8_t _corr_index;//index for sample table int8_t PROGMEM _dtmf_samples[] = {...};
int8_t d = ADCH; for( uint8_t i = 16; i--; ) { int16_t mul = d * pgm_read_byte( &_dtmf_samples[_corr_index] ); _corr[i] += mul; }
в результате генерится совершенно безобразный код. умножение производится в 32-х битном виде, хотя явно написано умножение 2-х байтов включена оптимизация O3
если массив объявить как int8_t, то умножение делается для 2-х байтов, но!!!! используется mul вместо muls (хотя написано, что величины знаковые!!!) и в результате он зануляет старший байт, даже если идет приведение результата операции к int16_t
как побороть WinAVR?
что хочется: сделать знаковое умножение 2-х байтов, получить 16-ти битное значение. затем расширить его до 32-х бит, сложить с 32-х битной величиной из массива и запомнить в массиве результат.
и еще: ткните, плиз, носом где понятно написано как делать ассемблерные вставки. собственно, непонятно, как из асма взять данные из Сишной переменной и в нужную Сишную переменную отдать
|
|
|
|
|
 |
Ответов
|
Aug 8 2008, 13:39
|
Частый гость
 
Группа: Участник
Сообщений: 152
Регистрация: 18-03-06
Пользователь №: 15 366

|
мда.... ни с О3 ни с Os код нормально не генерит так чтоб нормально было. С Os он циклы строит, где ему явно прописано 3 раза сдвинуть (я уж не говорю, что он зачем-то перегрузку регистров в другую пару делает. В O3 тоже, кстати, зачем-то регистры туда-сюда гоняет) O3 дает 3 умножения вместо одного Os делает байтовое умножение, только регистры туда -сюда тусует зачем-то блин, а у меня это критичные места по времени. делать асмовские вставки в сишные код ну так не хочется. от асма изначально и отказался только потому, чтоб переносимость была. вместо программирования борьба с компилем. придется, видимо, отказываться от 8-бит контроллера и переходить на ARM  компиль все ресурсы убивает в никуда
Сообщение отредактировал VDV - Aug 8 2008, 13:50
|
|
|
|
|
Aug 8 2008, 14:04
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(VDV @ Aug 8 2008, 17:39)  блин, а у меня это критичные места по времени. НЕВЕРЮ!!!!!! Код int8_t d = ADCH; for( uint8_t i = 16; i--; ) { int16_t mul = d * pgm_read_byte( &_dtmf_samples[_corr_index] ); _corr[i] += mul; } Если б дейсвительно это было для Вас критично по времени, то первым делом Вы бы вынесли "int16_t mul = d * pgm_read_byte( &_dtmf_samples[_corr_index] );" из цикла. Анатолий.
Сообщение отредактировал aesok - Aug 8 2008, 14:11
|
|
|
|
|
Aug 8 2008, 14:14
|
Частый гость
 
Группа: Участник
Сообщений: 152
Регистрация: 18-03-06
Пользователь №: 15 366

|
Цитата(aesok @ Aug 8 2008, 18:04)  НЕВЕРЮ!!!!!! Код int8_t d = ADCH; for( uint8_t i = 16; i--; ) { int16_t mul = d * pgm_read_byte( &_dtmf_samples[_corr_index] ); _corr[i] += mul; } Если б дейсвительно это было для Вас критично по времени, то первым делом Вы бы вынесли "pgm_read_byte( &_dtmf_samples[_corr_index] )" из цикла. Анатолий. операция lpm r0, z выполняется быстро и умножение всего 2 такта. так что весь кусок поги занял бы очень мало времени гораздно быстрее, чем 3 умножения, которые туда лепит компиль или, при другой оптимизации, дважды туда-сюда гоняет данные из регистров. и раположение таблицы в памяти программ - это обычное дело. самый обычный корреляционный алгоритм. еще на 8051 делал с его 1 мипсом. и уж организация цикла для тройного сдвига явно медленнее, чем три раза подряд сдвинуть. + экономии памяти точно никакой - достаточно написать на асме код и убедиться в этом.
Сообщение отредактировал VDV - Aug 8 2008, 14:18
|
|
|
|
|
Aug 8 2008, 14:20
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(VDV @ Aug 8 2008, 18:14)  А вот ЭТО "&_dtmf_samples[_corr_index]" сколько выполняеться Вы не заметили? И вообще зачем в цикле выполнять код который не зависит от пременной цикла???? Во всех учебниках советуют такой код выносить из цикла. достаточно написать на асме код и убедиться в этом: Код ldi r18,3; 85 *lshrhi3_const/5 [length = 5] 1: lsr r25 ror r24 dec r18 brne 1b 5 инструкций. 3 последовательных сдвига на 1 это 6. Что короче? Поэтому на -Os цикл, на -O3 - 3 сдвига. Анатолий.
Сообщение отредактировал aesok - Aug 8 2008, 14:27
|
|
|
|
Сообщений в этой теме
VDV как побороть WinAVR? Aug 7 2008, 17:01 aesok Цитата(VDV @ Aug 7 2008, 21:01) в результ... Aug 7 2008, 19:36 demiurg_spb Цитата(VDV @ Aug 7 2008, 21:01) что хочет... Aug 7 2008, 20:20 777777 Цитата(VDV @ Aug 7 2008, 21:01) ткните, п... Aug 8 2008, 04:36 AHTOXA Цитата(777777 @ Aug 8 2008, 10:36) Ассемб... Aug 8 2008, 05:59 aesok Цитата(VDV @ Aug 7 2008, 21:01) int8_t d ... Aug 8 2008, 06:37 demiurg_spb Цитата(aesok @ Aug 8 2008, 10:37) Макрос ... Aug 8 2008, 07:25  VDV спасибо за ответы,
я ошибся написав, что он делает... Aug 8 2008, 08:49   aesok Цитата(VDV @ Aug 8 2008, 12:49) такой код... Aug 8 2008, 13:04   ReAl Цитата(VDV @ Aug 8 2008, 11:49) Os оптими... Aug 8 2008, 13:13 VDV код приведен для пояснения смысла проблемы, а не о... Aug 8 2008, 14:57 AHTOXA Цитата(VDV @ Aug 8 2008, 20:57) проигрышь... Aug 8 2008, 16:02 _Pasha Цитата(777777 @ Aug 8 2008, 08:36) Что не... Aug 9 2008, 08:53
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|