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

 
 
> Компилятор в 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
Ответов
rezident
сообщение Nov 22 2006, 02:42
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



ИМХО потому что запись
Код
tmpByte <<= 1;

на самом деле краткая и обозначает
Код
tmpByte = tmpByte << 1;

Аналогично
Код
tmpByte |= tmp_bit;

обозначает
Код
tmpByte = tmpByte | tmp_bit;

Поскольку tmpByte является и источником-операндом и приемником результата, то компилятор вполне логично каждую команду раскладывает так, как ему предписано. А вот с включенной оптимизацией он возможно соптимизирует код к такому виду, который вы считаете нормальным.
Go to the top of the page
 
+Quote Post
Perepic
сообщение Dec 18 2006, 16:58
Сообщение #3


Участник
*

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



Цитата(rezident @ Nov 22 2006, 02:42) *
ИМХО потому что запись
Код
tmpByte <<= 1;

на самом деле краткая и обозначает
Код
tmpByte = tmpByte << 1;


Поскольку tmpByte является и источником-операндом и приемником результата, то компилятор вполне логично каждую команду раскладывает так, как ему предписано. А вот с включенной оптимизацией он возможно соптимизирует код к такому виду, который вы считаете нормальным.


Интересно мыслите, однако! Как вам такой пример, я честно говоря до сих пор не понимаю отчего IAR 4.11a так себя ведет. Оптимизация включена на максимум, окромя "cross-call"
Код
UCHAR TimeOut;            // глобальная переменная

__interrupt void TimerInt()
{
    if(TimeOut) TimeOut--;
};

Все это компилится в ледующий код:
Код
     LDS     R16, TimeOut
     TST     R16
     BREQ    0x392
  
    LDI     R30,0x9F
    LDI     R31,0x02
    LD      R16,Z
    DEC     R16
    ST      Z,R16

Сохраниение и восстановление стека я опустил.
Что мы видим? Грузим переменную, проверяем ее, если условие выполняется, опять ее же грузим (ЗАЧЕМ?), причем засоряя адресные регистры, модифицируем и сохраняем. В результате имеем 3 лишних комманды + 4 для сохраниения-восстановления адресных регистров. Более чем в 2 раза, однако! Никак оптимальным такой код не назовешь. Что скажете..?
Go to the top of the page
 
+Quote Post
Rst7
сообщение Dec 26 2006, 16:09
Сообщение #4


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(Perepic @ Dec 18 2006, 15:58) *
Интересно мыслите, однако! Как вам такой пример, я честно говоря до сих пор не понимаю отчего IAR 4.11a так себя ведет. Оптимизация включена на максимум, окромя "cross-call"
Код
UCHAR TimeOut;            // глобальная переменная

__interrupt void TimerInt()
{
    if(TimeOut) TimeOut--;
};


В принципе, я придерживаюсь мнения, что компилятору надо подсказывать, что делать. А также помнить об особеностях процессора - в данном случае не надо забывать, что у нас не аккумуляторная машина, и регистров валом. Имеет смысл написать так:
Код
char TimeOut;            // ãëîáàëüíàÿ ïåðåìåííàÿ

__interrupt void TimerInt()
{
  char to=TimeOut;
  if (to) TimeOut=--to;
}


В результате имеем нормальный код:
Код
    294            char to=TimeOut;
   \   00000006   9100....           LDS     R16, TimeOut
    295            if (to) TimeOut=--to;
   \   0000000A   2300               TST     R16
   \   0000000C   F019               BREQ    ??TimerInt_0
   \   0000000E   950A               DEC     R16
   \   00000010   9300....           STS     TimeOut, R16
    296          };
   \                     ??TimerInt_0:


Да, я понимаю, хотелось бы, чтобы компилятор сам это делал... Но с другой стороны, если лень-матушка, программируйте на Делфи для большого брата, вообще не надо думать...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 26 2006, 16:27
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Rst7 @ Dec 26 2006, 15:09) *
Имеет смысл написать так:
Код
  char to=TimeOut;

Если уж подсказывать, то подсказывать по полной программе:
Код
register char to=TimeOut;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_Bill
сообщение Dec 27 2006, 10:27
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(zltigo @ Dec 26 2006, 16:27) *
Цитата(Rst7 @ Dec 26 2006, 15:09) *

Имеет смысл написать так:
Код
  char to=TimeOut;

Если уж подсказывать, то подсказывать по полной программе:
Код
register char to=TimeOut;


Вообще-то, IAR игнорирует ключевое слово register. Или нет?
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Dec 27 2006, 14:18
Сообщение #7


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(_Bill @ Dec 27 2006, 09:27) *
Вообще-то, IAR игнорирует ключевое слово register. Или нет?

Может игнорировать если нельзя обеспечить.
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 27 2006, 14:48
Сообщение #8


Adept
******

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



Цитата(IgorKossak @ Dec 27 2006, 17:18) *
Цитата(_Bill @ Dec 27 2006, 09:27) *

Вообще-то, IAR игнорирует ключевое слово register. Или нет?

Может игнорировать если нельзя обеспечить.

Причем игнорировать молча. Иными словами, если можно обеспечить, то и так задействует регистр, если нельзя, то не задействует, ничего не сообщая. Так сегодня поступает подавляющее большинство (если не все) компиляторов. От ключевого слова register ничего не зависит, оно является рудиментом и артефактом. Оставленным в языке для совместимости со старым кодом. Есть не просит, пусть будет.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
_Bill
сообщение Dec 27 2006, 19:03
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(dxp @ Dec 27 2006, 14:48) *
Цитата(IgorKossak @ Dec 27 2006, 17:18) *

Цитата(_Bill @ Dec 27 2006, 09:27) *

Вообще-то, IAR игнорирует ключевое слово register. Или нет?

Может игнорировать если нельзя обеспечить.

Причем игнорировать молча. Иными словами, если можно обеспечить, то и так задействует регистр, если нельзя, то не задействует, ничего не сообщая. Так сегодня поступает подавляющее большинство (если не все) компиляторов. От ключевого слова register ничего не зависит, оно является рудиментом и артефактом. Оставленным в языке для совместимости со старым кодом. Есть не просит, пусть будет.

Это не совсем так. Просто в IAR сделано именно так. Где размещать переменные решает только компилятор. В других средах (например, в Borland) имеется возможность выбора: не размещать переменные в регистрах, размещать автоматически или размещать по ключевому слову register. Сейчас, когда ресурсов в PC предостаточно, компиляторы стали достаточно "умными", то необходимость в использовании register как бы отпадает. Но в контроллерах с ограниченными ресурсами иногда желательно дать возможность решать вопрос о размещении переменных самому программисту.
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 28 2006, 07:32
Сообщение #10


Adept
******

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



Цитата(_Bill @ Dec 27 2006, 22:03) *
Это не совсем так. Просто в IAR сделано именно так. Где размещать переменные решает только компилятор. В других средах (например, в Borland) имеется возможность выбора: не размещать переменные в регистрах, размещать автоматически или размещать по ключевому слову register.

И как, например, запретить размещать переменную в регистре? Какое ключевое слово для этого используется?

Цитата(_Bill @ Dec 27 2006, 22:03) *
Сейчас, когда ресурсов в PC предостаточно, компиляторы стали достаточно "умными", то необходимость в использовании register как бы отпадает. Но в контроллерах с ограниченными ресурсами иногда желательно дать возможность решать вопрос о размещении переменных самому программисту.

Борланд - это PC. Неужто в нем недостаток регистров? Ни разу не встречал в коде для Борланда (начиная с версий оного 4 и выше) подобных попыток оптимизаций.

Имхо, уже давным давно прошла необходимость рулить такими оптимизациями из С-кода. Компилятор с этим разберется лучше. Программисту надо состредоточиться на алгоритме, а уж как по регистрам совать - тут все карты на руках у компилятора. Если хочется адекватного результата ручному контролю, то это ассемблер (вызов функции или вставки).

Кроме IAR, еще несколько компиляторов не замечены во внимании к ключевому слову register: CCS/TMS320F28xx, VDSP++/Blackfin, avr-gcc (правда, с последним знакомство поверхностное).

P.S. Посмотрел в доку на Билдер:

Цитата
Category

Storage class specifiers

Syntax

register <data definition> ;

Description

Use the register storage class specifier to store the variable being declared in a CPU register (if possible), to optimize access and reduce code.

Note: The C++Builder compiler can ignore requests for register allocation. Register allocation is based on the compiler’s analysis of how a variable is used.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 4 2007, 00:22
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(dxp @ Dec 28 2006, 08:32) *
Борланд - это PC. Неужто в нем недостаток регистров? Ни разу не встречал в коде для Борланда (начиная с версий оного 4 и выше) подобных попыток оптимизаций.


Похоже Вы немного пошутили или не то имели ввиду. biggrin.gif По сравнению с AVR в PC регистров почти нет. biggrin.gif

А если учитывать, что часть из них связано с определёнными функциями (CX - регистр счётчик, BX,EX -базы, AX - аккумулятор). То такая оптимизация вообще не имеет смысла. Да и при таком построении процессора, вопрос такой экономии не ставится. Там оптимизация строится на базе совершенно других принципов. Длина цикла - размер кэша - объём данных по работе с памятью, "грамотное обращение" к переферии и т.д.
Go to the top of the page
 
+Quote Post
_Bill
сообщение Jan 4 2007, 23:20
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(SasaVitebsk @ Jan 4 2007, 00:22) *
Цитата(dxp @ Dec 28 2006, 08:32) *

Борланд - это PC. Неужто в нем недостаток регистров? Ни разу не встречал в коде для Борланда (начиная с версий оного 4 и выше) подобных попыток оптимизаций.


Похоже Вы немного пошутили или не то имели ввиду. biggrin.gif По сравнению с AVR в PC регистров почти нет. biggrin.gif

А если учитывать, что часть из них связано с определёнными функциями (CX - регистр счётчик, BX,EX -базы, AX - аккумулятор). То такая оптимизация вообще не имеет смысла. Да и при таком построении процессора, вопрос такой экономии не ставится. Там оптимизация строится на базе совершенно других принципов. Длина цикла - размер кэша - объём данных по работе с памятью, "грамотное обращение" к переферии и т.д.

Не стоит забывать, что эти регистры 32-разрядные. И есть возможность использовать их и как 16-, и как 8-разрядные. К тому же, у AVR есть определенные проблемы с использованием младших 16 регистров. Так что реально используются только 16 старших регистров. А если требуются данные типа long или float, так их останется на все про все всего 4. И опять же, у PC инструкции позволяют оперировать с ячейками памяти как с регистрами (при увеличении длины инструкции и времени ее выполнения). Так что вопросы оптимизации программы за счет использования регистров остаются весьма актуальными.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 5 2007, 03:58
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(_Bill @ Jan 5 2007, 00:20) *
Не стоит забывать, что эти регистры 32-разрядные. И есть возможность использовать их и как 16-, и как 8-разрядные. К тому же, у AVR есть определенные проблемы с использованием младших 16 регистров. Так что реально используются только 16 старших регистров. А если требуются данные типа long или float, так их останется на все про все всего 4. И опять же, у PC инструкции позволяют оперировать с ячейками памяти как с регистрами (при увеличении длины инструкции и времени ее выполнения). Так что вопросы оптимизации программы за счет использования регистров остаются весьма актуальными.


Ну это скорее желаемое чем действительное. smile.gif Регистры действительно 32-ух битные, но их нельзя использовать, например как 2 16-ти битных или 4 - восьми битных. Если говорить о "определённых проблемах по использованию отдельных регистров", то здесь INTEL явно лидирует. Например сложить B и С Вам не удастся. Если же Вы попытаетесь написать реальную прогу, даже на ассемблере, длиной хотябы листа два, используя расширенные команды, то Вам врятли удастся съэкономить даже один регистр. А компилятор даже не будет пытаться это делать.
Но это и не нужно. Вы совершенно правы, во второй части. INTEL имеет развитой механизм работы с памятью. Учитывая все мыслимые способы адресации. А сама архитектура (кэш буфер данных) позволяет к значительным массивам используемых данных обращаться, фактически как к регистрам. Кроме кэша данных есть кэш программы, что накладывает свои особенности. Ну и наконец, наличие нескольких ALU (в пнях уже по-моему 2-целочисленных и 1 с плавающей запятой) - тоже имеет значение. Поэтому оптимизация программ там имеет совершенно другие принципы и особенности. Согласно литературе это всё учитывается компиляторами. Я читал, что в Windows используются циклы определённой длины, а компилятор прогу делает так, что бы распаралеливание было максимальным.

Но я, боже упаси, не собираюсь затевать спор в той области, где имею поверхностные знания. Я просто пошутил. biggrin.gif Очевидно что само число регистров - просто крайне мало. dxp, думаю, явно имел ввиду не регистры, а сам принцип экономии таким способом. И я его тут полностью поддерживаю. Просто выразился неудачно. А я пошутил. biggrin.gif Надеюсь никого не обидел.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- king2   Компилятор в IAR   Nov 22 2006, 02:23
|- - 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
|- - _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   Цитата(zltigo @ Dec 26 2006, 15:27) Цитат...   Dec 26 2006, 16:31
||- - 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
||- - 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
|- - 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   Или вот еще, тоже шедевр. Блин, чем больше в дизас...   Dec 18 2006, 18:01
|- - dxp   Цитата(Perepic @ Dec 18 2006, 21:01) Или ...   Dec 19 2006, 09:52
|- - Perepic   Цитата(dxp @ Dec 19 2006, 09:52) Код, кот...   Dec 19 2006, 11:29
- - SasaVitebsk   Тем не менее местами просто сказка и песня! ...   Dec 18 2006, 23:36


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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 09:04
Рейтинг@Mail.ru


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