Dron_Gus 2 5 июня, 2012 Опубликовано 5 июня, 2012 · Жалоба Кейлу следовало бы быть более тщательным в своей "догадливости" и разместить данные в порядке: var_b, var_a, var_c. Т. е. без разрыва, который в Вашем примере имеет место быть. Видимо, в разрыв было уже нечего запихать и от его положение ничего не менялось. Кстати, __packed char на производительность не влияет. А вот __packed short уже влияет. Даже на архитектурах, позволяющих невыравненное обращение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TAutomatic 0 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба Я бы предложил не заниматься всякой фигнёй. Особенно если нет твёрдого понимания, что вообще происходит. __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 байта, это называется "достаточной догадливостью"? А если это результат реальной работы компилятора, у меня возникает вопрос: компилятор вправе даже при использовании оптимизатора так вольно тусовать переменные? На каком основании он поменял местами переменные относительно их объявления? Да, они не привязаны к адресам, компилятор волен их свободно размещать во всем адресном пространстве. Но порядок их должен быть таким, как при объявлении. Во всяком случае, так было во всех компиляторах, которые я пользовал до Кейла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба На каком основании он поменял местами переменные относительно их объявления? Вставил a в первое же подходящее место. Вставил b в первое же подходящее место, по выровненному адресу. Вставил c, аналогично. Первое же подходящее место для с где? Правильно! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TAutomatic 0 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба Вставил a в первое же подходящее место. Вставил b в первое же подходящее место, по выровненному адресу. Вставил c, аналогично. Первое же подходящее место для с где? Правильно! :rolleyes: Компилятор - не человек. Он не может, да не имеет права так вольно перемещать, менять местами порядок переменных. Упаковать-это одно, порядок не нарушается, а поменять местами-это другое. А вдруг такой порядок - задумка программиста? А компилятор все нарушил. Разницу в упаковке что есть и перемещении с целью "оптимизации" чувствуете? :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба вдруг такой порядок - задумка программиста?тогда в структуре и объявляете поля с определённым порядком, который никто не нарушит. А так компилятор волен делать что угодно в пределах стандарта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба А вдруг такой порядок - задумка программиста? Упование на порядок переменных - моветон, причина необъяснимых глюков и бесконечные наезды на компилятор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба А вдруг такой порядок - задумка программиста? А компилятор все нарушил. У переменных, независимых друг от друга, нет и не может быть никакого "порядка". Об этом и в книжках пишут, и самому можно догадаться. У компилятора (или линкера) одна цель - впихнуть впихуемое. Берет переменные попорядку, и пихает их, куда можно. Никакой фантазии, дубовая логика. __packed, кстати, относится только к структурам и объединениям, целиком, или к отдельным их составляющим. Для обычных переменных этот атрибут ничего не дает. Я так думаю. :) И, получается, aaarrr не прав. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TAutomatic 0 6 июня, 2012 Опубликовано 6 июня, 2012 (изменено) · Жалоба У переменных, независимых друг от друга, нет и не может быть никакого "порядка". Об этом и в книжках пишут, и самому можно догадаться. У компилятора (или линкера) одна цель - впихнуть впихуемое. Берет переменные попорядку, и пихает их, куда можно. Никакой фантазии, дубовая логика. Вы глубоко ошибаетесь, так утверждая. Такого уж точно "в книжках не пишут". Есть такое понятие - секции. В том числе данных. Это не структурированные типы данных. Это переменные в том числе и базовых типов? Задумайтес, для чего придумали секции? Вы секциями пользуетесь? У компилятора другая цель - транслировать конструкции языков верхнего уровня в ассемблерные инструкции. Линкер предназначен для объединения объектного кода в общее целое с расстановкой физических адресов. Они оба ничего никуда не впихивают. Об этом нужно четко знать, если вы читаете книжки, в которых что-то пишут. А вот "впихивать" - это задача оптимизатора. И эта задача распространяется на код, а не на данные. Тоже в книжках написано, которые стоит читать. __packed, кстати, относится только к структурам и объединениям, целиком, или к отдельным их составляющим. Для обычных переменных этот атрибут ничего не дает. Я так думаю. :) И, получается, aaarrr не прав. Думать Вам, естественно, никто не запрещает. Но вот, прежде чем писать, что кто-то не прав-желательно самому убедиться в этом. Одну страницу назад я спрашивал об упаковке данных, и когда aaarrr ответил, я не стал утверждать ничего. Пока не смогу сам лично убедиться, что бы не "сесть в лужу". Я убедился сам реально, что __packed применим и к базовым типам данным и действительно упаковывает переменные базовых типов до минимальных размеров, тоесть до логических размеров в байтах. И aaarrr прав, а Вы вот сейчас "сели в лужу", основываясь только на думании, а не на практике. Изменено 6 июня, 2012 пользователем TAutomatic Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба Я убедился сам реально, что __packed применим и к базовым типам данным и действительно упаковывает переменные базовых типов до минимальных размеров... Я проверил пример из сообщения №28 еще утром. Прежде, чем писать. Сейчас проверил еще раз. Добавьте к переменной var_b атрибут __packed, скомпилируйте, и удивите меня фрагментом из map файла, если переменная var_b окажется расположенной по невыровненному адресу. А потом поговорим о том, кто "убедился сам реально", а кто "сел в лужу". После, чем писать :) Кроме того, почитайте, что написано про __packed в первоисточнике - помощи по Keil. P.S. Цитату из книжки позже приведу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TAutomatic 0 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба Я проверил пример из сообщения №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 прав, и я ему свое спасибо уже сказал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба Проверил с тремя __packed. Так я не пробовал. var_a 0x20000000 Data 1 var_c 0x20000001 Data 1 var_b 0x20000002 Data 4 Да, упаковалось. Вы правы. Проверил и с двумя, одним. Тоже укладывается. Оказывается, я не обновлял map файл при просмотре, а Total Commander показывал мне старый. aaarrr прав! Я - посрамлен! :crying: Keil - обманщик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TAutomatic 0 6 июня, 2012 Опубликовано 6 июня, 2012 · Жалоба Проверил с тремя __packed. Так я не пробовал. var_a 0x20000000 Data 1 var_c 0x20000001 Data 1 var_b 0x20000002 Data 4 Да, упаковалось. Вы правы. Ну и слава Богу, разобрались. :rolleyes: Если кому поможет тоже эта информация - это чудненько, больше будет знатоков. Думаю, топик можно закрыть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 7 июня, 2012 Опубликовано 7 июня, 2012 · Жалоба Ребята, я вас умоляю, не делайте так в рабочем коде. Придёт после вас человек и не поймёт нифига, что вы там наоптимизировали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 июня, 2012 Опубликовано 7 июня, 2012 · Жалоба Герберд Шилдт. Полный справочник по 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TAutomatic 0 7 июня, 2012 Опубликовано 7 июня, 2012 · Жалоба Ребята, я вас умоляю, не делайте так в рабочем коде. Придёт после вас человек и не поймёт нифига, что вы там наоптимизировали. А при чем тут придет и не поймет :rolleyes: Я беру к себе на работу только тех, кто способен понимать и разобраться. Тогда и Вы ответьте на вопрос: зачем тогда столько "фишек" и примочек в компиляторе? Вы этим не пользуетесь? Я пользуюсь. И максимально, что бы был максимально эффективный код, или максимально эффективное решение задачи или еще что-то в этом роде, но максимально эффективное. Почему публика привратно в основном понимает эту суть. если я спросил насчет упаковки переменных, почему -т о в основном у публики сложилось сразу впечатление, что я возьму тупо все данные упакую в кирпич. И начались советы по поводу эффективности такого использования и т.д. и т.п. Ребята, я не собираюсь так делать :rolleyes: Во всяком случае ко всему подряд и без разбора "на всякий случай". Просто иногда гдето-то в определенном месте в связи с определенными условиями нужно применить такой метод. И не более. Речь не идет о како-то глобальности. Если Вы не пользуетесь всеми инструментами, которые вам дает средство разработки, Вы либо невысокой квалификации специалист, либо не можете предложить самое эффективное решение задачи, что собственно тоже говорит о квалификации. Все, что правильно понимается и правильно применяется- никак не отражается на рабочем коде в подавляющем большенстве случаев. И почти все так называемые "глюки" контроллеров или среды - это глюки того, кто не в полной мере этим владеет. Низкая квалификация. Герберд Шилдт. Полный справочник по C. (в электронном виде не имею на русском языке, в книжке на русском еще понятнее). Page 144 - 145 Все правильно, спасибо за цитату :rolleyes: Теперь попытаюсь Вам концептуально разъяснить в чем дело. Язык С был создан в эпоху микропроцессоров, у которых память была сегментирована. Это процессоры чуть до Intel286 и 386 и в том числе эти процессоры. Так вот, что бы получить доступ к исполнительному адресу, нужно было еще опереровать с сегментным регистром. Вполне вероятно, что два массива по 10 байт оказались бы на границе сегмента. Физически это последовательные адреса, но вот логические уже нет. И тогда последовательное обращение к 20 байтам на самом деле бы привело не к обращению к двум последовательным массивам, а в пределах одного секмента 64кБ. Давайте жить реалиями сегняшнего дня. В основном все уже имеют дело с микроконтроллерами с линейным адресным пространством. В пределах этого пространства компилятор не занимается перестановкой переменных и оптимизацией их размещения, если на то нет особых инструкций, указаний и т. д. Тоесть, компилятор оптимизирует код с обязательным требованием сохранения его идентичности по функционалу исходному коду и не занимается оптимизацией памяти данных Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться