|
Компилятор в IAR, ньюансы обращения к переменным |
|
|
|
Nov 22 2006, 02:23
|
Местный
  
Группа: Свой
Сообщений: 255
Регистрация: 17-08-06
Из: Москва
Пользователь №: 19 646

|
Снова не пойму как IAR работает с переменными... Оптимизация вся выключена, дабы не влиять излишне. Имеем такой вот код: Код 111 tmpByte <<= 1; \ 00000464 9100.... LDS R16, tmpByte \ 00000468 0F00 LSL R16 \ 0000046A 9300.... STS tmpByte, R16 112 tmpByte |= tmp_bit; \ 0000046E 8108 LD R16, Y \ 00000470 .... LDI R30, LOW(tmpByte) \ 00000472 .... LDI R31, (tmpByte) >> 8 \ 00000474 8110 LD R17, Z \ 00000476 2B10 OR R17, R16 \ 00000478 8310 ST Z, R17 Почему компилятор, имея в регистре значение переменной, и следующую операцию с ней же, тем не менее сначала сохраняет ее, а потом загружает? Переменная не volatile. Почему в первом и втором случае обращение к одной и той же переменной делается по разному?? Как избежать такого извращенного обращения к переменным? Эквивалентный (нормальный) код: Код 114 tmpByte = (tmpByte<<1) | tmp_bit; \ 0000047A 9100.... LDS R16, tmpByte \ 0000047E 0F00 LSL R16 \ 00000480 8118 LD R17, Y \ 00000482 2B10 OR R17, R16 \ 00000484 9310.... STS tmpByte, R17 Спасибо заранее!
|
|
|
|
|
 |
Ответов
|
Dec 18 2006, 18:01
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 14-08-06
Пользователь №: 19 528

|
Или вот еще, тоже шедевр. Блин, чем больше в дизассемблере лажу - тем больше расстраиваюсь! Код ;p_Mask[0] = RxBuf[0]; 00011A 910C LD R16,X 00011C 01FC MOVW R30,R24 00011E 8300 ST Z,R16
;p_Mask[1] = RxBuf[1]; 000120 01FD MOVW R30,R26 000122 8101 LDD R16,Z+1 000124 01FC MOVW R30,R24 000126 8301 STD Z+1,R16
;p_Mask[2] = RxBuf[2]; 000128 01FD MOVW R30,R26 00012A 8102 LDD R16,Z+2 00012C 01FC MOVW R30,R24 00012E 8302 STD Z+2,R16
;p_Mask[3] = RxBuf[3]; 000130 01FD MOVW R30,R26 000132 8103 LDD R16,Z+3 000134 01FC MOVW R30,R24 000136 8303 STD Z+3,R16 Простое копирование двух массивов. Ну почему не задействовать пару свободных регистров указателей, скажем Х и Z? Нет, мы будем каждый раз грузить новые значения указателей в ОДНУ регистровую пару, теряя по 2 машинных цикла на каждой итерции. Вроде ж начало получилось хорошее, а дальше... Не понимаю! То же самое, реализованное в цикле. Еще хуже: Код ;for(i=0; i<4; i++) p_Mask[i] = RxBuf[i]; 000118 019C MOVW R18,R24 00011A 018D MOVW R16,R26 00011C E044 LDI R20,0x04
00011E 01F8 MOVW R30,R16 000120 9151 LD R21,Z+ 000122 018F MOVW R16,R30 000124 01F9 MOVW R30,R18 000126 9351 ST Z+,R21 000128 019F MOVW R18,R30 00012A 954A DEC R20 00012C F7C1 BRNE 0x11E Лучший код генерит только ICC, но вот полчить его в работающем виде и без ограничений по времени/коду пока сложно...
|
|
|
|
|
Dec 19 2006, 09:52
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Perepic @ Dec 18 2006, 21:01)  Или вот еще, тоже шедевр. Блин, чем больше в дизассемблере лажу - тем больше расстраиваюсь! Код ;p_Mask[0] = RxBuf[0]; 00011A 910C LD R16,X 00011C 01FC MOVW R30,R24
[...]
000134 01FC MOVW R30,R24 000136 8303 STD Z+3,R16 Простое копирование двух массивов. Ну почему не задействовать пару свободных регистров указателей, скажем Х и Z? Нет, мы будем каждый раз грузить новые значения указателей в ОДНУ регистровую пару, теряя по 2 машинных цикла на каждой итерции. Вроде ж начало получилось хорошее, а дальше... Не понимаю! Попробовал ради интереса. Получил другие результаты. Код: Код char buf1[16]; char buf2[16];
// -------------------------------------------------------------------------- void main(void) {
buf1[0] = buf2[0]; buf1[1] = buf2[1]; buf1[2] = buf2[2]; buf1[3] = buf2[4]; } // -------------------------------------------------------------------------- Результат: Код buf1[0] = buf2[0]; .... LDI R30, LOW(buf1) .... LDI R31, (buf1) >> 8 8900 LDD R16, Z+16 8300 ST Z, R16 buf1[1] = buf2[1]; 8901 LDD R16, Z+17 8301 STD Z+1, R16 buf1[2] = buf2[2]; 8902 LDD R16, Z+18 8302 STD Z+2, R16 buf1[3] = buf2[3]; 8903 LDD R16, Z+19 8303 STD Z+3, R16 Ага, но тут массивы объявлены в одном файле, компилятор их "кластеризовал" и обошелся эффективно одним указателем, благо размеры массивов это позволяют. Усложним компилятору задачу, объявив один из массивов внешним: Код char buf1[16]; extern char buf2[16]; Результат: Код buf1[0] = buf2[0]; .... LDI R26, LOW(buf1) .... LDI R27, (buf1) >> 8 .... LDI R30, LOW(buf2) .... LDI R31, (buf2) >> 8 8100 LD R16, Z 930D ST X+, R16 buf1[1] = buf2[1]; 8101 LDD R16, Z+1 930D ST X+, R16 buf1[2] = buf2[2]; 8102 LDD R16, Z+2 930C ST X, R16 9712 SBIW R27:R26, 2 buf1[3] = buf2[3]; 8103 LDD R16, Z+3 01FD MOVW R31:R30, R27:R26 8303 STD Z+3, R16 Он не так печален, как вашем примере. Может все-таки с оптимизацией что-то не то? Цитата(Perepic @ Dec 18 2006, 21:01)  То же самое, реализованное в цикле. Еще хуже: Код ;for(i=0; i<4; i++) p_Mask[i] = RxBuf[i]; 000118 019C MOVW R18,R24 00011A 018D MOVW R16,R26
[...]
00012A 954A DEC R20 00012C F7C1 BRNE 0x11E Лучший код генерит только ICC, но вот полчить его в работающем виде и без ограничений по времени/коду пока сложно... Код: Код char buf1[16]; extern char buf2[16];
// -------------------------------------------------------------------------- void main(void) {
for(char i = 0; i < sizeof(buf1); i++) { buf1[i] = buf2[i]; } } // -------------------------------------------------------------------------- Результат: Код void main(void) main: { 019D MOVW R19:R18, R27:R26
for(char i = 0; i < sizeof(buf1); i++) .... LDI R26, LOW(buf1) .... LDI R27, (buf1) >> 8 .... LDI R30, LOW(buf2) .... LDI R31, (buf2) >> 8 E100 LDI R16, 16 { buf1[i] = buf2[i]; ??main_0: 9111 LD R17, Z+ 931D ST X+, R17 } 950A DEC R16 F7E1 BRNE ??main_0 } 01D9 MOVW R27:R26, R19:R18 9508 RET Что может быть короче? IAR, как уже неоднократно говорилось и доказывалось, является лучшим компилятором для AVR на сегодняшний день. На втором месте с небольшим отставанием прочно находится AVR-GCC. Никакие ICC по качеству кодогенерации с этими двумя соревноваться не могут. Код, который вы показали, был характерен для IAR'овских компляторов версий 2.хх - они там упорно делали все подобные обращения в память через Z-pointer, что далеко не всегда хорошо, на что было указано и в версиях 3.хх уже ситуация изменилась к лучшему. Основная же причина сидит не в компиляторах, а в самом AVR, в котором мало (всего два) полноценных аппаратных регистра-указателя (Y и Z, X - неполноценный, у него отсутствует очень важный режим адресации со смещением). Т.е. один из указателей занят под указатель стека данных (еще один, мягко говоря, неудачный момент AVR - обо всех этих "фичах" AVR уже подробно говорилось, если интересно, поищите по форуму), остается один Z-pointer, который компилятор и пытается использовать. В данном случае удалось выйти с честью из положения, т.к. производится просто последовательное копирование. А вот если бы надо было выборочно извлекать байты из массивов, то тут X-pointer уже не порулил бы совсем и код был бы действительно печальным.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
Сообщений в этой теме
king2 Компилятор в IAR Nov 22 2006, 02:23 rezident ИМХО потому что запись
КодtmpByte <<= 1;
... Nov 22 2006, 02:42 king2 А почему оно в одном случае загружает переменную и... Nov 22 2006, 03:26  IgorKossak Цитата(king2 @ Nov 22 2006, 02:26) А поче... Nov 22 2006, 10:50   dxp ЦитатаЦитата(king2 @ Nov 22 2006, 02:26) ... Nov 22 2006, 11:57 Perepic Цитата(rezident @ Nov 22 2006, 02:42) ИМХ... Dec 18 2006, 16:58  _Bill Цитата(Perepic @ Dec 18 2006, 16:58) Цита... Dec 19 2006, 23:17   Perepic Цитата(_Bill @ Dec 19 2006, 23:17) Попроб... Dec 20 2006, 08:16    _Bill Цитата(Perepic @ Dec 20 2006, 08:16) Цита... Dec 20 2006, 11:50     SasaVitebsk Цитата(_Bill @ Dec 20 2006, 11:50) Все пр... Dec 21 2006, 02:12      Perepic Цитата(SasaVitebsk @ Dec 21 2006, 02:12) ... Dec 21 2006, 12:07       HARMHARM Цитата(Perepic @ Dec 21 2006, 11:07) Цита... Dec 21 2006, 18:48        IgorKossak Цитата(HARMHARM @ Dec 21 2006, 17:48) Цит... Dec 26 2006, 11:15      _Bill Цитата(SasaVitebsk @ Dec 21 2006, 02:12) ... Dec 21 2006, 16:30  Rst7 Цитата(Perepic @ Dec 18 2006, 15:58) Инте... Dec 26 2006, 16:09   zltigo Цитата(Rst7 @ Dec 26 2006, 15:09) Имеет с... Dec 26 2006, 16:27    Rst7 Цитата(zltigo @ Dec 26 2006, 15:27) Цитат... Dec 26 2006, 16:31    _Bill Цитата(zltigo @ Dec 26 2006, 16:27) Цитат... Dec 27 2006, 10:27     IgorKossak Цитата(_Bill @ Dec 27 2006, 09:27) Вообще... Dec 27 2006, 14:18      dxp Цитата(IgorKossak @ Dec 27 2006, 17:18) Ц... Dec 27 2006, 14:48       zltigo Цитата(dxp @ Dec 27 2006, 13:48) Иными сл... Dec 27 2006, 15:41        Сергей Борщ Цитата(zltigo @ Dec 27 2006, 14:41) Цитат... Jan 7 2007, 01:33         zltigo Цитата(Сергей Борщ @ Jan 7 2007, 00:33) P... Jan 7 2007, 02:03       _Bill Цитата(dxp @ Dec 27 2006, 14:48) Цитата(I... Dec 27 2006, 19:03        dxp Цитата(_Bill @ Dec 27 2006, 22:03) Это не... Dec 28 2006, 07:32         zltigo Цитата(dxp @ Dec 28 2006, 06:32) И как, н... Dec 28 2006, 12:13          IgorKossak Цитата(dxp @ Dec 28 2006, 06:32) И как, н... Dec 28 2006, 12:29         _Bill Цитата(dxp @ Dec 28 2006, 07:32) И как, н... Jan 2 2007, 22:33         SasaVitebsk Цитата(dxp @ Dec 28 2006, 08:32) Борланд ... Jan 4 2007, 00:22          _Bill Цитата(SasaVitebsk @ Jan 4 2007, 00:22) Ц... Jan 4 2007, 23:20           SasaVitebsk Цитата(_Bill @ Jan 5 2007, 00:20) Не стои... Jan 5 2007, 03:58   Perepic Цитата(Rst7 @ Dec 26 2006, 16:09) В принц... Dec 27 2006, 08:44 SasaVitebsk На этот раз для меня не понятный момент. До этого ... Dec 7 2006, 23:06 rezident Цитата(SasaVitebsk @ Dec 8 2006, 01:06) С... Dec 8 2006, 01:01  zltigo Цитата(rezident @ Dec 8 2006, 00:01) заме... Dec 8 2006, 02:52 SasaVitebsk Информация к размышлению. Объявление не менял. Пом... Dec 8 2006, 03:12 _Bill Цитата(SasaVitebsk @ Dec 8 2006, 03:12) И... Dec 8 2006, 12:16  SasaVitebsk Цитата(_Bill @ Dec 8 2006, 12:16) Все пра... Dec 8 2006, 13:24   _Bill Цитата(SasaVitebsk @ Dec 8 2006, 13:24) В... Dec 8 2006, 17:31 SasaVitebsk Спасибо, разъяснили доступно. Извините за наглость... Dec 11 2006, 21:34 zltigo Цитата(SasaVitebsk @ Dec 11 2006, 20:34) ... Dec 11 2006, 22:38  Perepic Цитата(dxp @ Dec 19 2006, 09:52) Код, кот... Dec 19 2006, 11:29 SasaVitebsk Тем не менее местами просто сказка и песня! ... Dec 18 2006, 23:36
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|