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

 
 
> Компилятор в 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
zltigo
сообщение Dec 28 2006, 12:13
Сообщение #11


Гуру
******

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



Цитата(dxp @ Dec 28 2006, 06:32) *
И как, например, запретить размещать переменную в регистре? Какое ключевое слово для этого используется?

-r-
Про Builder, правда ничего не скажу и отключением никогда не пользовался и пользоваться не буду smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
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
|||- - 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   Или вот еще, тоже шедевр. Блин, чем больше в дизас...   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 Текстовая версия Сейчас: 22nd July 2025 - 12:23
Рейтинг@Mail.ru


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