|
Как отключить оптимизацию switch() ? |
|
|
|
Jan 29 2012, 07:40
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Перепробовал все прагмы типа #pragma optimize=high/medium/low size/balanced/speed no_cse no_unroll no_tbaa no_inline no_code_motion Всё равно switch() оптимизирует и тратит из-за этого DPL,DPH & B в прерывании MCS-51. Мне надо чтобы switch из четырёх элементов сделался как через if () ... Ну неужели придётся делать ручками через if
Эскизы прикрепленных изображений
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 28)
|
Jan 29 2012, 08:03
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(GetSmart @ Jan 29 2012, 11:40)  Мне надо чтобы switch из четырёх элементов сделался как через if () ... Тогда и пишите 4 ифа вместо свича  . Во всех реализациях языков программирования (с которыми я встречалась) switch - это выбор из списка адресов, каковыми могут быть либо адреса безусловных переходов, либо адреса подпрограмм. Поэтому и реализация его такова, что где-то такой список составляется, а конкретные реализации различается между собой лишь способом вычисления смещения от начала списка с последующим переходом на этот адрес. Впервые слышу, чтобы switch оптимизировали путем замены на батарею if-ов. Если какие-то компиляторы на это способны, то хотелось бы услышать их названия.
|
|
|
|
|
Jan 29 2012, 10:15
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Нда. Переделал на if-ы. Стало на 11 байт короче самого оптимизированного варианта со свичём. Плюс в 2 раза меньше стека юзает 5 vs 10 байт. Оптимизаторы, рационализаторы  При этом в каждом if-е перечитывает переменную заново, хотя мог бы в акке держать и XOR-ить от варианта к варианту. IAR 7.60, оптимизация high/size. Ну а чего он читая битовую переменную (__bit || __bdata || sfr bit) анализирует её через флаг C, а не сразу в JB bit,label тоже вопрос к гениальным разработчикам.
Сообщение отредактировал GetSmart - Jan 29 2012, 11:48
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 29 2012, 11:55
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Xenia @ Jan 29 2012, 11:03)  Впервые слышу, чтобы switch оптимизировали путем замены на батарею if-ов. Если какие-то компиляторы на это способны, то хотелось бы услышать их названия. Я Вас умоляю... для MCS-51 команда CJNE <reg>, #immediate, offset как раз для этого случая. Может, кейл не понимайт, что выражение под свитчем не int, a char ? Цитата(GetSmart @ Jan 29 2012, 13:15)  Ну а чего он читая битовую переменную (__bit || __bdata || sfr bit) анализирует её через флаг C, а не сразу в JB bit,label тоже вопрос к гениальным разработчикам. Ну да, ну да  А выражение куда девать? И что там с lazy evaluation, если sfr bit у нас volatile? Я думаю, курить их хелп-не перекурить. Или избегать стрёмных ситуаций.
|
|
|
|
|
Jan 29 2012, 12:00
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(_Pasha @ Jan 29 2012, 16:55)  Может, кейл не понимайт, что выражение под свитчем не int, a char ? Какой Кейл? Подфорум об ИАРе. И не выражение, а переменная u08. Нету там promotion. Цитата(_Pasha @ Jan 29 2012, 16:55)  Ну да, ну да  А выражение куда девать? И что там с lazy evaluation, если sfr bit у нас volatile? Я думаю, курить их хелп-не перекурить. Или избегать стрёмных ситуаций. Вот и волатил и неволатил делает одинаково. (Upd. с неволатилом ещё не проверил, оказалось везде был волатил) lazy evaluation не знаю, куда притянуть. Я наткнулся на таких и подобных командах Код if (SCON0_bit.TI0) { SCON_bit.TI0 = 0; // хорошо хоть в этой команде не сдурил и сделал её битовой в одну команду // а был бы умным, поставил вообще jbc bit,label
Сообщение отредактировал GetSmart - Jan 29 2012, 16:41
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 30 2012, 01:48
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(arttab @ Jan 30 2012, 06:09)  iar #pragma optimize=none Делает по-прежнему. Начинаю думать, что в 7.60 это единственный вариант кодирования свичей. Надо бы на 8-ой проверить. На картинке вторая часть того, во что ИАР превращает свич из 4-ёх вариантов. Тихий ужас. Цитата(Xenia @ Jan 30 2012, 01:21)  ...куда пускают только своих. Вы же его не видите потому, что вы не наш!  Ага. Кто не с нами, тот против нас. Так и запишем в протокол. А ведь до НГ я её видел. СОПУ испугались что ли.
Сообщение отредактировал GetSmart - Jan 30 2012, 05:01
Эскизы прикрепленных изображений
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 30 2012, 13:47
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(scifi @ Jan 30 2012, 18:05)  Ну не знаю... Опускаться до таких извращений, чтобы выжать пару байт из кода? ЯВУ не для этого придуманы. Если так сильно надо оптимизировать в этом месте, то следует использовать ассемблер. А если оптимизировать на самом деле не нужно, но очень хочется, то это проблема уже из области психологии. А по делу? А конструктивно? А то ведь дойдёт до того, что и квалификаторы static, __data, __bit, __bdata, __code и ещё туча других будут приравнены к извращениям. Я могу и на асме писать, но не хочу, т.к. править что-то в нём долго. Однако я имею право (и компиляторы дают возможность) управлять оптимизацией на усмотрение программиста. Вот и возник простой вопрос без всякого психоанализа - какой кнопкой отключить оптимизацию свича. Нельзя, так нельзя. Спрашивал у знающих людей. И вообще, настоящий профи знает инструмент с которым работает до малейшего винтика. Будь то компилятор или даже ЯВУ типа С++. Ну а программер мелкого пошиба будет искать любые отмазки и всё делать тяп-ляп. Так что давайте определяться.
Сообщение отредактировал GetSmart - Jan 30 2012, 14:28
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 30 2012, 14:40
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(GetSmart @ Jan 30 2012, 05:48)  Делает по-прежнему. За что Вы так компилятор не любите? (это я про volatile в switch) имхо, вполне естественное решение: Код tmp = uartData.rxPhase; switch(tmp) {} А если ещё упростить жисть компилятору, то Код /* вместо tmp = uartData.rxPhase; switch(tmp) { case A: case B: case C: ... } */ tmp = uartData.rxPhase ^ A; if(!tmp) {} else if(!(tmp ^= A ^ B)) {} else if(!(tmp ^= B ^ C)) {} ... (в зависимости от компилятора и архитектуры контроллера) может оказаться короче.
|
|
|
|
|
Jan 30 2012, 15:01
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(xemul @ Jan 30 2012, 19:40)  За что Вы так компилятор не любите? (это я про volatile в switch) Ай лов дис компилер  Там не было volatile (uartData.rxPhase - обычная переменная) И при этом она постоянно перечитывалась. Ранее я упоминал волатил касательно работы с битовыми переменными. Цитата(xemul @ Jan 30 2012, 19:40)  А если ещё упростить жисть компилятору, то ... Код tmp = uartData.rxPhase ^ A; if(!tmp) {} else if(!(tmp ^= A ^ B)) {} else if(!(tmp ^= B ^ C)) {} ... (в зависимости от компилятора) может оказаться короче. В зависимости от... Ну Вы же понимаете, когда есть множественный выбор по одной переменной/выражении, то именно для этого придуман свич. Да и с ним грациозней код смотрится  Ну а до 8051 я сидел на EWARM, который свичи гораздо более навороченные делал через compare-branch. И я до сих пор не понимаю изврата, с которым столкнулся. Upd. То, что Вы "сотворили" имхо уже изврат. То есть для ЯВУ некрасиво и менее понятно, чем простые сравнения переменной с тремя-четырьмя константами. Такой экономии мне не надо. Пусть 5 тактов будет лишних. Я за красоту кода и полное и бесприкословное подчинение компилятора  Но из-за ущербности свича (а он там с полсотни тактов растранжирит и это в прерывании) я всё-таки заменю их на 3 if-а и парочку goto. Остальное в исходнике должно быть красиво. Ваш код должен уметь делать сам компилятор. Это почти элементарно. Но он неумёха в области 8051. А вот в ARM-е он на порядок круче генерит. Там ему большой респект.
Сообщение отредактировал GetSmart - Jan 30 2012, 15:24
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Feb 10 2012, 07:27
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Ужжасс. 7.60.1 ещё и глючный. По адресу 072C надо сдвигать на оригинальное значение bit, а сдвигается на bit-8 (ACC). V1:V0 - что сдвигать, R0 - адрес V1:V0.
Эскизы прикрепленных изображений
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Feb 11 2012, 00:40
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Xenia @ Jan 29 2012, 13:03)  Впервые слышу, чтобы switch оптимизировали путем замены на батарею if-ов. Если какие-то компиляторы на это способны, то хотелось бы услышать их названия. Привожу название: ИАР 8.10.4. Картинка нумбер уан. Причём ни один свич в моей проге больше не делается через то заднее место как раньше. На картинке нумбер ту исправлен глюк с искажением аккумулятора при сравнении. Но в целом этот кусок стал заметно хуже предыдущего. Вобщем уровень компиляции ещё очень далек от уровня АРМ-овой версии ИАРа. Грубо говоря в 2 раза компактней можно писать на асме. А в АРМовом грубо раза в 1.2.
Сообщение отредактировал GetSmart - Feb 11 2012, 09:10
Эскизы прикрепленных изображений
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Feb 11 2012, 07:26
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(GetSmart @ Feb 11 2012, 07:29)  А 8.10.4 тоже какие-то приколисты писали. Вобщем видны некоторые улучшения оптимизации. А у вас какая оптимизация включена? По скорости или по размеру? Кстати, версия 8.10.4 уже не последняя - вчера вышла 8.11.1. Вот только испытывать ее боюсь из-за новой системы лицензирования. Теперь инсталлятор раздают свободно ( тута) и он даже пытается что-то инсталлировать, но чтобы компилить стало, надо регистрировать по интернету. Есть предупреждение, что новая и старая система лицензирования несовместимы на одном компе (ОСе?), вот и трушу проверять, опасаясь, что старые лицензии (на другие платформы) у меня слетят. Впрочем, ожидать заметных подвижек в качестве компиляции от новой версии не приходится, т.к., судя по описанию, смена способа лицензирования - единственное, чем она отличается от своей предшественницы. Сама же тенденция улучшать качество кода с ростом номера версии довольно хорошо прослеживается. Да и со временем ошибки тоже пользователями выявляются и производителем исправляются. Вот только Startup-код постоянно растет... Но если за собой знаешь ту болезнь, что постоянно лазишь в код, генерируемый компилятором, и переживаешь по всякому поводу (типа "я написала бы лучше"), то лучше на ассемблере так и оставаться, а на С не переходить - целее нервы будут  . Со мной тоже такое было, но со временем прошло.
|
|
|
|
|
Feb 11 2012, 08:06
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Оптимизация у меня максимальная по размеру. Причём галку "Common subexpression elimination" даже выключил, без неё ещё компактней. Смотреть код это такая же болезнь как смотреться в зеркало. Вы, как представительница женского пола, не болеете?  Перестать смотреть не желаете? Залазя на новый компилятор просто нужно смотреть код. Это привычка старого профессионала. Лет 5 сидел на EWARM 4.20 и смотрел код тщательно первые несколько месяцев. Потом уже узнаёшь его как свои 5 пальцев  Кроме того, это помогает быстро искать ошибки в скомпиленном коде. Кто бы ещё быстренько подсказал - какой компилер лучше генерит код ИАР 8.10 или какой-нить последний Кейл или ещё какой.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Feb 11 2012, 08:21
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(GetSmart @ Feb 11 2012, 12:06)  Кто бы ещё быстренько подсказал - какой компилер лучше генерит код ИАР 8.10 или какой-нить последний Кейл или ещё какой. Этот вопрос широко рассматривался вот в этой теме - " Какой компилятор выбрать IAR или Keil?, а может GCC?", но с тех пор много воды утекло (появились новые версии компиляторов). Было бы целесообразно реанимировать ту тему (в смысле продолжить), а то в теме про switch этот вопрос вряд ли найдет широкий отклик. Цитата(GetSmart @ Feb 11 2012, 12:06)  Лет 5 сидел на EWARM 4.20 и смотрел код тщательно первые несколько месяцев. Потом уже узнаёшь его как свои 5 пальцев  Кроме того, это помогает быстро искать ошибки в скомпиленном коде. Вот вы бы этим лично и занялись, как лицо заинтересованное и квалифицированное. Тем более что с IAR вы до конца разобрались. Сравнить, на мой взгляд, стоит только с Keil и GCC, остальные не конкуренты.
|
|
|
|
|
Mar 5 2012, 20:27
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 4-03-09
Из: Богота, Колумбия
Пользователь №: 45 676

|
Цитата(arttab @ Jan 30 2012, 04:09)  iar #pragma optimize=none А как назад вернуть как было? Эта гадина мне вачдог оптимизирует: WDTCSR = (1 << WDCE) | (1<<WDE); WDTCSR = (1 << WDE) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0);
|
|
|
|
|
Mar 5 2012, 22:56
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Dikoy @ Mar 5 2012, 22:27)  А как назад вернуть как было? Эта гадина мне вачдог оптимизирует: WDTCSR = (1 << WDCE) | (1<<WDE); WDTCSR = (1 << WDE) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0); Цитата Use this pragma directive to decrease the optimization level, or to turn off some specific optimizations. This pragma directive only affects the function that follows immediately after the directive. Разве надо возвращать? Какой у вас уровень оптимизации установлен?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|