Jump to content

    
Sign in to follow this  
TAutomatic

Размер unsigned int или int Keil4.5

Recommended Posts

Кейлу следовало бы быть более тщательным в своей "догадливости" и разместить данные в порядке: var_b, var_a, var_c. Т. е. без разрыва, который в Вашем примере имеет место быть.

Видимо, в разрыв было уже нечего запихать и от его положение ничего не менялось.

 

Кстати, __packed char на производительность не влияет. А вот __packed short уже влияет. Даже на архитектурах, позволяющих невыравненное обращение.

Share this post


Link to post
Share on other sites
Я бы предложил не заниматься всякой фигнёй. Особенно если нет твёрдого понимания, что вообще происходит.

__packed, конечно, экономит память, но заметно сказывается на объеме программы (на не-кортексах) и на производительности (на любых армах).

 

Кейл (в частности, 4.14 с включенным оптимизатором) достаточно догадлив, чтобы собрать данные в одну кучу.

 

volatile char var_a;
volatile int var_b;
volatile char var_c;
int main(void)
{
    var_a = IOPIN0;
    var_b = IOPIN1;
    var_c = var_a + var_b;
    IOPIN0 = var_c;
    while (1);
}

 

    var_a                                    0x40000000   Data           1  main.o(.data)
    var_c                                    0x40000001   Data           1  main.o(.data)
    var_b                                    0x40000004   Data           4  main.o(.data)

 

Этот автор либо вообще решил подыграть Кейлу, написав пример "от руки", либо не понятно, кто страдает "фигней". Если автор от руки написал пример, чувствуется твердое понимание происходящего, а именно процедура упаковки. Между переменными var_c и var_b оставлена "дырка" в 2 байта, это называется "достаточной догадливостью"? А если это результат реальной работы компилятора, у меня возникает вопрос: компилятор вправе даже при использовании оптимизатора так вольно тусовать переменные? На каком основании он поменял местами переменные относительно их объявления? Да, они не привязаны к адресам, компилятор волен их свободно размещать во всем адресном пространстве. Но порядок их должен быть таким, как при объявлении. Во всяком случае, так было во всех компиляторах, которые я пользовал до Кейла.

Share this post


Link to post
Share on other sites
На каком основании он поменял местами переменные относительно их объявления?

Вставил a в первое же подходящее место. Вставил b в первое же подходящее место, по выровненному адресу. Вставил c, аналогично. Первое же подходящее место для с где? Правильно!

Share this post


Link to post
Share on other sites
Вставил a в первое же подходящее место. Вставил b в первое же подходящее место, по выровненному адресу. Вставил c, аналогично. Первое же подходящее место для с где? Правильно!

:rolleyes: Компилятор - не человек. Он не может, да не имеет права так вольно перемещать, менять местами порядок переменных. Упаковать-это одно, порядок не нарушается, а поменять местами-это другое. А вдруг такой порядок - задумка программиста? А компилятор все нарушил. Разницу в упаковке что есть и перемещении с целью "оптимизации" чувствуете? :rolleyes:

Share this post


Link to post
Share on other sites
вдруг такой порядок - задумка программиста?
тогда в структуре и объявляете поля с определённым порядком, который никто не нарушит. А так компилятор волен делать что угодно в пределах стандарта.

 

Share this post


Link to post
Share on other sites
А вдруг такой порядок - задумка программиста?

Упование на порядок переменных - моветон, причина необъяснимых глюков и бесконечные наезды на компилятор.

Share this post


Link to post
Share on other sites
А вдруг такой порядок - задумка программиста? А компилятор все нарушил.

У переменных, независимых друг от друга, нет и не может быть никакого "порядка". Об этом и в книжках пишут, и самому можно догадаться.

У компилятора (или линкера) одна цель - впихнуть впихуемое. Берет переменные попорядку, и пихает их, куда можно. Никакой фантазии, дубовая логика.

 

__packed, кстати, относится только к структурам и объединениям, целиком, или к отдельным их составляющим. Для обычных переменных этот атрибут ничего не дает. Я так думаю. :)

И, получается, aaarrr не прав.

Share this post


Link to post
Share on other sites
У переменных, независимых друг от друга, нет и не может быть никакого "порядка". Об этом и в книжках пишут, и самому можно догадаться.

У компилятора (или линкера) одна цель - впихнуть впихуемое. Берет переменные попорядку, и пихает их, куда можно. Никакой фантазии, дубовая логика.

Вы глубоко ошибаетесь, так утверждая. Такого уж точно "в книжках не пишут". Есть такое понятие - секции. В том числе данных. Это не структурированные типы данных. Это переменные в том числе и базовых типов? Задумайтес, для чего придумали секции? Вы секциями пользуетесь?

У компилятора другая цель - транслировать конструкции языков верхнего уровня в ассемблерные инструкции. Линкер предназначен для объединения объектного кода в общее целое с расстановкой физических адресов. Они оба ничего никуда не впихивают. Об этом нужно четко знать, если вы читаете книжки, в которых что-то пишут. А вот "впихивать" - это задача оптимизатора. И эта задача распространяется на код, а не на данные. Тоже в книжках написано, которые стоит читать.

__packed, кстати, относится только к структурам и объединениям, целиком, или к отдельным их составляющим. Для обычных переменных этот атрибут ничего не дает. Я так думаю. :)

И, получается, aaarrr не прав.

Думать Вам, естественно, никто не запрещает. Но вот, прежде чем писать, что кто-то не прав-желательно самому убедиться в этом. Одну страницу назад я спрашивал об упаковке данных, и когда aaarrr ответил, я не стал утверждать ничего. Пока не смогу сам лично убедиться, что бы не "сесть в лужу". Я убедился сам реально, что __packed применим и к базовым типам данным и действительно упаковывает переменные базовых типов до минимальных размеров, тоесть до логических размеров в байтах. И aaarrr прав, а Вы вот сейчас "сели в лужу", основываясь только на думании, а не на практике.

Edited by TAutomatic

Share this post


Link to post
Share on other sites
Я убедился сам реально, что __packed применим и к базовым типам данным и действительно упаковывает переменные базовых типов до минимальных размеров...

Я проверил пример из сообщения №28 еще утром. Прежде, чем писать. Сейчас проверил еще раз. Добавьте к переменной var_b атрибут __packed, скомпилируйте, и удивите меня фрагментом из map файла, если переменная var_b окажется расположенной по невыровненному адресу.

А потом поговорим о том, кто "убедился сам реально", а кто "сел в лужу". После, чем писать :)

 

Кроме того, почитайте, что написано про __packed в первоисточнике - помощи по Keil.

P.S. Цитату из книжки позже приведу.

Share this post


Link to post
Share on other sites
Я проверил пример из сообщения №28 еще утром. Прежде, чем писать. Сейчас проверил еще раз. Добавьте к переменной var_b атрибут __packed, скомпилируйте, и удивите меня фрагментом из map файла, если переменная var_b окажется расположенной по невыровненному адресу.

А потом поговорим о том, кто "убедился сам реально", а кто "сел в лужу". После, чем писать :)

 

Кроме того, почитайте, что написано про __packed в первоисточнике - помощи по Keil.

P.S. Цитату из книжки позже приведу.

Не обижайтесь, хорошо? :rolleyes: Бывает, даже самые знатоки иногда банальных вещей не знают. А по теме вот что:

Код:

unsigned char a;
unsigned int    b;
unsigned char c;

у меня в мап-файле дает вот что:

    a                                        0x100000fc   Data           1  tx11main.o(.data)
    b                                        0x10000100   Data           4  tx11main.o(.data)
    c                                        0x10000104   Data           1  tx11main.o(.data)

а вот такой код

__packed unsigned char a;
__packed unsigned int    b;
__packed unsigned char c;

имеет результатом вот что:

    a                                        0x100000fc   Data           1  tx11main.o(.data)
    b                                        0x100000fd   Data           4  tx11main.o(.data)
    c                                        0x10000101   Data           1  tx11main.o(.data)

Мне кажется тут и комментировать нечего. Кеил 4.5 Я не знаю почему и для чего оптимизатор у Вас или у кого-то еще что-то переставляет. При чем тут вообще оптимизатор. Вот, простой пример упаковки. Логических 6 байт упакованы в 6 адресов, лучше не придумаешь. Что еще тут можно спорить. Если у кого-то не так-посмотрите, все ли вы правильно пишите. И почитайте книжки. Так что aaarrr прав, и я ему свое спасибо уже сказал.

 

Share this post


Link to post
Share on other sites

Проверил с тремя __packed. Так я не пробовал.

var_a 0x20000000 Data 1

var_c 0x20000001 Data 1

var_b 0x20000002 Data 4

Да, упаковалось. Вы правы.

 

Проверил и с двумя, одним. Тоже укладывается. Оказывается, я не обновлял map файл при просмотре, а Total Commander показывал мне старый.

aaarrr прав! Я - посрамлен! :crying: Keil - обманщик.

Share this post


Link to post
Share on other sites
Проверил с тремя __packed. Так я не пробовал.

var_a 0x20000000 Data 1

var_c 0x20000001 Data 1

var_b 0x20000002 Data 4

Да, упаковалось. Вы правы.

Ну и слава Богу, разобрались. :rolleyes: Если кому поможет тоже эта информация - это чудненько, больше будет знатоков. Думаю, топик можно закрыть.

Share this post


Link to post
Share on other sites

Герберд Шилдт. Полный справочник по C. (в электронном виде не имею на русском языке, в книжке на русском еще понятнее).

Page 144 - 145

Another error that sometimes occurs is caused by incorrect assumptions about the placement of

variables in memory. In general, you cannot know where your data will be placed in memory, or

whether it will be placed there the same way again, or whether different compilers will treat it in the

same way. For these reasons, making any comparisons between pointers that do not point to a

common object may yield unexpected results. For example,

 

char s[80], y[80];

char *p1, *p2;

p1 = s;

p2 = y;

if(p1 < p2) . . .

 

is generally an invalid concept. (In very unusual situations, you might use something like this to

determine the relative position of the variables. But this would be rare.)

 

A related error results when you assume that two adjacent arrays may be indexed as one by simply

incrementing a pointer across the array boundaries. For example:

 

int first[10], second[10];

int *p, t;

p = first;

for(t=0; t<20; ++t) *p++ = t;

 

This is not a good way to initialize the arrays first and second with the numbers 0 through 19. Even

though it may work on some compilers under certain circumstances, it assumes that both arrays will

be placed back to back in memory with first first. This may not always be the case.

Share this post


Link to post
Share on other sites
Ребята, я вас умоляю, не делайте так в рабочем коде. Придёт после вас человек и не поймёт нифига, что вы там наоптимизировали.

А при чем тут придет и не поймет :rolleyes: Я беру к себе на работу только тех, кто способен понимать и разобраться. Тогда и Вы ответьте на вопрос: зачем тогда столько "фишек" и примочек в компиляторе? Вы этим не пользуетесь? Я пользуюсь. И максимально, что бы был максимально эффективный код, или максимально эффективное решение задачи или еще что-то в этом роде, но максимально эффективное. Почему публика привратно в основном понимает эту суть. если я спросил насчет упаковки переменных, почему -т о в основном у публики сложилось сразу впечатление, что я возьму тупо все данные упакую в кирпич. И начались советы по поводу эффективности такого использования и т.д. и т.п. Ребята, я не собираюсь так делать :rolleyes: Во всяком случае ко всему подряд и без разбора "на всякий случай". Просто иногда гдето-то в определенном месте в связи с определенными условиями нужно применить такой метод. И не более. Речь не идет о како-то глобальности. Если Вы не пользуетесь всеми инструментами, которые вам дает средство разработки, Вы либо невысокой квалификации специалист, либо не можете предложить самое эффективное решение задачи, что собственно тоже говорит о квалификации. Все, что правильно понимается и правильно применяется- никак не отражается на рабочем коде в подавляющем большенстве случаев. И почти все так называемые "глюки" контроллеров или среды - это глюки того, кто не в полной мере этим владеет. Низкая квалификация.

 

Герберд Шилдт. Полный справочник по C. (в электронном виде не имею на русском языке, в книжке на русском еще понятнее).

Page 144 - 145

Все правильно, спасибо за цитату :rolleyes: Теперь попытаюсь Вам концептуально разъяснить в чем дело. Язык С был создан в эпоху микропроцессоров, у которых память была сегментирована. Это процессоры чуть до Intel286 и 386 и в том числе эти процессоры. Так вот, что бы получить доступ к исполнительному адресу, нужно было еще опереровать с сегментным регистром. Вполне вероятно, что два массива по 10 байт оказались бы на границе сегмента. Физически это последовательные адреса, но вот логические уже нет. И тогда последовательное обращение к 20 байтам на самом деле бы привело не к обращению к двум последовательным массивам, а в пределах одного секмента 64кБ. Давайте жить реалиями сегняшнего дня. В основном все уже имеют дело с микроконтроллерами с линейным адресным пространством. В пределах этого пространства компилятор не занимается перестановкой переменных и оптимизацией их размещения, если на то нет особых инструкций, указаний и т. д. Тоесть, компилятор оптимизирует код с обязательным требованием сохранения его идентичности по функционалу исходному коду и не занимается оптимизацией памяти данных

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this