defunct 0 24 декабря, 2008 Опубликовано 24 декабря, 2008 · Жалоба А есть ли возможность указать компилятору в данном конкретном примере какой-нибудь командой #cmdxxx НЕ ОПТИМИЗИРОВАТЬ например именно строчку где a=2; ? #pragma optimize = none Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 24 декабря, 2008 Опубликовано 24 декабря, 2008 · Жалоба Я уже раньше отмечал, что современные компиляторы занимаются оптимизацией совместно с линкером. Об этом и Александреску в своих книгах пишет. Про "оптимизирующий" код линкер это достойно назаборной письменности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 24 декабря, 2008 Опубликовано 24 декабря, 2008 · Жалоба Про "оптимизирующий" код линкер это достойно назаборной письменности. К примеру, начиная с MSVC++ 7.0 линкер имеет опцию /ltcg - "link time code generation" и это позволяет "отодвинуть" вопрос о встраивании функции или использовании обычного вызова на этап линковки. Про это достаточно подробно Г.Саттер "Новые сложные задачи на С++", Вильямс, 2005 стр.164-174. Нечто подобное поддерживает компилятор от HP. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 24 декабря, 2008 Опубликовано 24 декабря, 2008 · Жалоба К примеру К "примеру" Вы уже говорили: сравнив ассемблерный листинг, генерируемый компилятором и дизассемблированный код. Так что замечания насчет оптимизации на уровне модуля тоже не совсем правомочны. А вот это: и это позволяет "отодвинуть" вопрос о встраивании функции или использовании обычного вызова на этап линковки. уже не имеет нималейшего отношения ни к обсуждаемой "проблеме", ни к Вашим предыдущим словам. Не говоря уже о том, что это вполне бесполезный трюк, ибо не позволяет произвести сквозную оптимизацию "склееенного" кода, а только грошовую экономию вызова. Любой компилятор сделает СВОЮ работу по inline несораизмеримо лучше, при этом КОМПИЛЯТОР должен предавительно изменить calling conversion для тех функций которые предполагается потом возможно склеить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Я не являюсь разрабочиком компиляторов и линкеров. Все вышесказанное привел только для иллюстрации того, что на сегодняшний день не только компилятор, но и линкер совместно оптимизируют генерируемый код. Это может кому-то нравится, а кому-то нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 25 декабря, 2008 Опубликовано 25 декабря, 2008 (изменено) · Жалоба Я не являюсь разрабочиком компиляторов и линкеров. Я являюсь :) Все вышесказанное привел только для иллюстрации того, что на сегодняшний день не только компилятор, но и линкер совместно оптимизируют генерируемый код.Это не совсем точное высказывание :( Код может оптимизироваться на этапе линковки, но занимается этим не линкер, а все таки компилятор. И тот 'код', который оптимизируется, на самом делен не код, а промежуточное представление компилятора. Это может кому-то нравится, а кому-то нет.Вне зависимости от того, нравится это или нет, оптимизациями занимается компилятор, когда бы он не запускался :1111493779: Пример: Hi-TECH PICC-18 Pro. Результатом независимой компиляции модуля (.c) является файл (.p1) с промежуточным представлением С'ной программы. На этапе сборки (линковки) они ВМЕСТЕ обрабатываются компилятором, который и генерит выходной код. Другой пример: Intel C компилятор. Опция -ipo (или -fast) переводит компилятор в режим компиляции всей программы. При этом, компиляция собственно модулей (.c) производит .obj файлы, в которых НЕТ кода, зато есть секции с промежуточным представлением программы. На этапе линковки снова вызывается компилятор, который читает все это из .obj файлов и генерирует код (в виде одного .obj файла, на этот раз с кодом) который уже и отправляется линкеру. Что касается опции 'MSVC++ 7.0 /ltcg' то сдается мне, что это не опция линкера, а опция ВСЕГО проекта, и подавать ее надо везде. Реализация (скорее всего) будет очень похожа на реализацию в Intel компиляторе Единственная известная мне 'оптимизация' именно ЛИНКЕРА - это выкидывание неиспользуемых кодов и данных из исполняемого файла. Но у меня язык не повернется назвать это 'оптимизацией' :( Изменено 25 декабря, 2008 пользователем XVR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Вне зависимости от того, нравится это или нет, оптимизациями занимается компилятор, когда бы он не запускался :1111493779:Не во всех компиляторах. В avr-gcc вызов линкера с опцией --relax приводит к замене пар call/ret на jmp, а jmp (там, где длина перехода позволяет) - на rjmp. Это вполне себе оптимизация и занимается ей именно линкер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба #pragma optimize = none Спасибо. Это как раз и было нужно. А опять включить ? Или можно поменять степень оптимизации на ходу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Спасибо. Это как раз и было нужно. А опять включить ? Или можно поменять степень оптимизации на ходу? Вы двигаетесь в неправильном направлении. Правильно написанная программа должна работать при любом уровне оптимизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Вы двигаетесь в неправильном направлении. Правильно написанная программа должна работать при любом уровне оптимизации. Согласен. Но в данном случае вы неправы. Бывают разные ситуации. Я, например в данном случае пытаюсь добиться результатов после дилетанта-программиста. Возможности переписать ВСЮ прогу просто нет, отключаю оптимизацию=прога не влазит в кристалл. Программист в прерываниях использует почти все модули и я исправляю ошибки доступа, что бы основная прога не вешалась. Так что в данном случае мой вопрос правилен. Лично я пишу, правильно разбивая ресурсы/переменные и лично у меня проблем с оптимизацией не было. Просто исправлять за кем-то - неблагодарное и трудное занятие. Но необходимое (в моём случае) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Ещё вопросик: Например, компилятор HiTech предупреждает при: while(1) { .... } while(1) { .... } типа warning: infinity loop, а вот ИАР не предупреждает, а молча делает... :) Но это лирика... У меня (в данном случае ИАР) ругается на переменные, когда я их обзываю volatile на то, что он не может просчитать их значение, т.к. не проинициализированы. А инитить я их не хочу, т.к. эти переменные лежат в озу и должны быть валидны и просле ресета (я их инициализю отдельно, считая их CRC или анализируя флаг сброса по питанию) Вот тут и грабли... (Опять повторю, прогу полностью переписать не cмогу(высшая математика), исправляю за самоучками :( ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба DenisIV, а такой вариант объявления __no_init volatile unsigned a, b, c; не проходит? У меня IAR только "варнингами" ругается, но ошибок не выдает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба DenisIV, а такой вариант объявления __no_init volatile unsigned a, b, c; не проходит? У меня IAR только "варнингами" ругается, но ошибок не выдает. Проходит,ошибок нет, вот по этому и спрашиваю, как обойти... Варнинги достали (>100) :( Мож #pragma optimize =none ? Ток я не знаю, как потом включить и будут ли варнинги дальше? А у меня варнинг-указание на засаду в проге. Игнорировать и отключать не хочется... Потом можно 3 дня глюк ловить... И не поймать... :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба типа warning: infinity loop, а вот ИАР не предупреждает, а молча делает... :) Но это лирика... Это не лирика, это где-то у вас преднамеренно отключены предупреждения (Project->Options->C/C++ compiler->Diagnostics):void Test() { while(1) { __no_operation();} while(1) { __no_operation();} } Warning[Pe128]: loop is not reachable from preceding code D:\****\loader.cpp 75 У меня (в данном случае ИАР) ругается на переменные, когда я их обзываю volatile на то, что он не может просчитать их значение, т.к. не проинициализированы.Давайте так: Есть непонятка, выкладываете код, выкладываете полный текст предупреждения на языке оригинала, будем смотреть.volatile int a; volatile int b; volatile int c; void Test() { int Tmp = a; b = Tmp; Tmp = b; c = Tmp; } Done. 0 error(s), 0 warning(s) \ In segment DATA_Z, align 4, align-sorted 72 volatile int a; \ a: \ 00000000 DS8 4 73 volatile int b; \ `b`: \ 00000004 DS8 4 74 volatile int c; \ c: \ 00000008 DS8 4 \ In segment CODE, align 4, keep-with-next 75 void Test() 76 { 77 int Tmp = a; \ ??Test: \ 00000000 0248 LDR R0,??Test_1 ;; a \ 00000002 0168 LDR R1,[R0, #+0] 78 b = Tmp; \ 00000004 4160 STR R1,[R0, #+0x4] 79 Tmp = b; \ 00000006 4168 LDR R1,[R0, #+0x4] 80 c = Tmp; \ 00000008 8160 STR R1,[R0, #+0x8] 81 } \ 0000000A 7047 BX LR ;; return \ ??Test_1: \ 0000000C ........ DC32 a Как видите, никакой ругани, делает все, как просилось. Я могу предположить, что ругань выглядит так: Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement D:\*****\loader.cpp 77Но она означает вовсе не "не может проинициализировать", а "не определен порядок обращения к volatile-переменным". И вызывает его примерно такой код:int a; volatile int b; volatile int c; void Test() { a = b + c; } И это предупреждение совершенно справедливо: стандарт позволяет компилятору изменять порядок вычисления подвыражений. А поскольку одно из свойств volatile-переменных состоит в том, что чтение может изменять ее значение (а таким свойством обладают многие sfr-регистры), то изменение порядка чтения двух volatile-переменных может привести к неожиданным для вас результатам. Поэтому для разрешения неоднозначности надо разделить чтения точками последовательности, т.е. ";" или оператором "запятая", введя временную переменную как я сделал в примере выше. Но это лишь гадание.Если бы вы представили минимальный необходимый для воспроизведения ситуации код - вы бы получили более точный и быстрый ответ. Варнинги достали (>100) :(Поэтому бороться надо с их причиной, а не следствием. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Это не лирика, это где-то у вас преднамеренно отключены предупреждения (Project->Options->C/C++ compiler->Diagnostics) Угу, и у тебя тоже :) не все включено, ибо еще, если мне не изменяет склероз, должено быть что-то типа Еxpression is constant. while(1) { .... } Вобще-то сие однозначно со всех точек зрения пишется так: for(;; ) { .... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться