|
|
  |
Странности при оптимизации |
|
|
|
Dec 24 2008, 23:00
|

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

|
Цитата(sergeeff @ Dec 25 2008, 01:09)  К примеру К "примеру" Вы уже говорили: Цитата сравнив ассемблерный листинг, генерируемый компилятором и дизассемблированный код. Так что замечания насчет оптимизации на уровне модуля тоже не совсем правомочны. А вот это: Цитата и это позволяет "отодвинуть" вопрос о встраивании функции или использовании обычного вызова на этап линковки. уже не имеет нималейшего отношения ни к обсуждаемой "проблеме", ни к Вашим предыдущим словам. Не говоря уже о том, что это вполне бесполезный трюк, ибо не позволяет произвести сквозную оптимизацию "склееенного" кода, а только грошовую экономию вызова. Любой компилятор сделает СВОЮ работу по inline несораизмеримо лучше, при этом КОМПИЛЯТОР должен предавительно изменить calling conversion для тех функций которые предполагается потом возможно склеить.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 25 2008, 07:17
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(sergeeff @ Dec 25 2008, 04:16)  Я не являюсь разрабочиком компиляторов и линкеров. Я являюсь Цитата Все вышесказанное привел только для иллюстрации того, что на сегодняшний день не только компилятор, но и линкер совместно оптимизируют генерируемый код. Это не совсем точное высказывание  Код может оптимизироваться на этапе линковки, но занимается этим не линкер, а все таки компилятор. И тот 'код', который оптимизируется, на самом делен не код, а промежуточное представление компилятора. Цитата Это может кому-то нравится, а кому-то нет. Вне зависимости от того, нравится это или нет, оптимизациями занимается компилятор, когда бы он не запускался Пример: Hi-TECH PICC-18 Pro. Результатом независимой компиляции модуля (.c) является файл (.p1) с промежуточным представлением С'ной программы. На этапе сборки (линковки) они ВМЕСТЕ обрабатываются компилятором, который и генерит выходной код. Другой пример: Intel C компилятор. Опция -ipo (или -fast) переводит компилятор в режим компиляции всей программы. При этом, компиляция собственно модулей (.c) производит .obj файлы, в которых НЕТ кода, зато есть секции с промежуточным представлением программы. На этапе линковки снова вызывается компилятор, который читает все это из .obj файлов и генерирует код (в виде одного .obj файла, на этот раз с кодом) который уже и отправляется линкеру. Что касается опции 'MSVC++ 7.0 /ltcg' то сдается мне, что это не опция линкера, а опция ВСЕГО проекта, и подавать ее надо везде. Реализация (скорее всего) будет очень похожа на реализацию в Intel компиляторе Единственная известная мне 'оптимизация' именно ЛИНКЕРА - это выкидывание неиспользуемых кодов и данных из исполняемого файла. Но у меня язык не повернется назвать это 'оптимизацией'
Сообщение отредактировал XVR - Dec 25 2008, 07:19
|
|
|
|
|
Dec 25 2008, 13:17
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(defunct @ Dec 24 2008, 20:09)  #pragma optimize = none Спасибо. Это как раз и было нужно. А опять включить ? Или можно поменять степень оптимизации на ходу?
|
|
|
|
|
Dec 25 2008, 13:36
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(Сергей Борщ @ Dec 25 2008, 16:24)  Вы двигаетесь в неправильном направлении. Правильно написанная программа должна работать при любом уровне оптимизации. Согласен. Но в данном случае вы неправы. Бывают разные ситуации. Я, например в данном случае пытаюсь добиться результатов после дилетанта-программиста. Возможности переписать ВСЮ прогу просто нет, отключаю оптимизацию=прога не влазит в кристалл. Программист в прерываниях использует почти все модули и я исправляю ошибки доступа, что бы основная прога не вешалась. Так что в данном случае мой вопрос правилен. Лично я пишу, правильно разбивая ресурсы/переменные и лично у меня проблем с оптимизацией не было. Просто исправлять за кем-то - неблагодарное и трудное занятие. Но необходимое (в моём случае)
|
|
|
|
|
Dec 25 2008, 21:19
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Ещё вопросик: Например, компилятор HiTech предупреждает при: Код while(1) { .... } while(1) { .... } типа warning: infinity loop, а вот ИАР не предупреждает, а молча делает...  Но это лирика... У меня (в данном случае ИАР) ругается на переменные, когда я их обзываю volatile на то, что он не может просчитать их значение, т.к. не проинициализированы. А инитить я их не хочу, т.к. эти переменные лежат в озу и должны быть валидны и просле ресета (я их инициализю отдельно, считая их CRC или анализируя флаг сброса по питанию) Вот тут и грабли... (Опять повторю, прогу полностью переписать не cмогу(высшая математика), исправляю за самоучками  )
|
|
|
|
|
Dec 25 2008, 22:14
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(rezident @ Dec 26 2008, 00:38)  DenisIV, а такой вариант объявления Код __no_init volatile unsigned a, b, c; не проходит? У меня IAR только "варнингами" ругается, но ошибок не выдает. Проходит,ошибок нет, вот по этому и спрашиваю, как обойти... Варнинги достали (>100)  Мож #pragma optimize =none ? Ток я не знаю, как потом включить и будут ли варнинги дальше? А у меня варнинг-указание на засаду в проге. Игнорировать и отключать не хочется... Потом можно 3 дня глюк ловить... И не поймать...
|
|
|
|
|
Dec 25 2008, 22:26
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(DenisIV @ Dec 25 2008, 23:19)  типа 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 Цитата(DenisIV @ Dec 25 2008, 23:19)  У меня (в данном случае ИАР) ругается на переменные, когда я их обзываю 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-переменных может привести к неожиданным для вас результатам. Поэтому для разрешения неоднозначности надо разделить чтения точками последовательности, т.е. ";" или оператором "запятая", введя временную переменную как я сделал в примере выше. Но это лишь гадание.Если бы вы представили минимальный необходимый для воспроизведения ситуации код - вы бы получили более точный и быстрый ответ. Цитата(DenisIV @ Dec 26 2008, 00:14)  Варнинги достали (>100)  Поэтому бороться надо с их причиной, а не следствием.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 25 2008, 22:50
|

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

|
Цитата(Сергей Борщ @ Dec 26 2008, 01:26)  Это не лирика, это где-то у вас преднамеренно отключены предупреждения (Project->Options->C/C++ compiler->Diagnostics) Угу, и у тебя тоже  не все включено, ибо еще, если мне не изменяет склероз, должено быть что-то типа Еxpression is constant. Цитата(DenisIV @ Dec 26 2008, 00:19)  while(1) { .... } Вобще-то сие однозначно со всех точек зрения пишется так: Код for(;; ) { .... }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|