Перейти к содержанию
    

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

__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 байта, это называется "достаточной догадливостью"? А если это результат реальной работы компилятора, у меня возникает вопрос: компилятор вправе даже при использовании оптимизатора так вольно тусовать переменные? На каком основании он поменял местами переменные относительно их объявления? Да, они не привязаны к адресам, компилятор волен их свободно размещать во всем адресном пространстве. Но порядок их должен быть таким, как при объявлении. Во всяком случае, так было во всех компиляторах, которые я пользовал до Кейла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На каком основании он поменял местами переменные относительно их объявления?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вдруг такой порядок - задумка программиста?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вдруг такой порядок - задумка программиста? А компилятор все нарушил.

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

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

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

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

Изменено пользователем TAutomatic

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я убедился сам реально, что __packed применим и к базовым типам данным и действительно упаковывает переменные базовых типов до минимальных размеров...

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

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

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я проверил пример из сообщения №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 прав, и я ему свое спасибо уже сказал.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

var_a 0x20000000 Data 1

var_c 0x20000001 Data 1

var_b 0x20000002 Data 4

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

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

var_a 0x20000000 Data 1

var_c 0x20000001 Data 1

var_b 0x20000002 Data 4

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Герберд Шилдт. Полный справочник по 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

Page 144 - 145

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...