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

 
 
> Компилятор в IAR, ньюансы обращения к переменным
king2
сообщение Nov 22 2006, 02:23
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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


Спасибо заранее!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Perepic
сообщение Dec 18 2006, 18:01
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 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, но вот полчить его в работающем виде и без ограничений по времени/коду пока сложно...
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 19 2006, 09:52
Сообщение #3


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 уже не порулил бы совсем и код был бы действительно печальным.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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


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

 


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


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