|
Проблема с условием, m = m+I|P == I ? m : 0; |
|
|
|
 |
Ответов
|
Aug 20 2018, 10:29
|

Участник

Группа: Участник
Сообщений: 23
Регистрация: 20-05-11
Пользователь №: 65 166

|
Цитата(segment @ Aug 20 2018, 11:55)  Воу. Если не секрет, то что это за проект такой? Это не секрет, это шахматная программа micro-Max. Весь код помещается на одном листе А4, притом, что программа знает даже такое правило, как "взятие пешки на проходе". Мне этот алгоритм очень понравился, я когда-то с друзьями в турнир играл, четырех обыграл, а эта програмка меня взувает (сделал шахматный калькулятор на ATmega48). Тут верно заметили, что код писал математик. Спасибо за советы.
Сообщение отредактировал ave! - Aug 20 2018, 10:42
|
|
|
|
|
Aug 20 2018, 11:31
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ave! @ Aug 20 2018, 13:29)  Тут верно заметили, что код писал математик. Код писал извращенец человек, цель которого была совсем не оптимальность и не решение практической задачи, а цель - вычурность кода. Ибо: вместо t += p<5 простой программист использует if, а более продвинутый заменит на что-то типа: t -= (int)(p - 5) >> 31;
|
|
|
|
|
Aug 22 2018, 13:55
|

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

|
QUOTE (Arlleex @ Aug 22 2018, 15:33)  А еще результат выражения != 0 не обязательно есть 1. Обязательно есть. QUOTE (Arlleex @ Aug 22 2018, 15:33)  Поэтому тот, кто писал t += p<5, явно чудак  Тот, кто писал этот код, очень хорошо знал Стандарт языка. В отличие от вас. QUOTE 6.5.8 Relational operators 6 Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.89) The result has type int. 6.5.9 Equality operators The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.90) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Aug 25 2018, 07:08
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(Сергей Борщ @ Aug 22 2018, 16:55)  Обязательно есть. Тот, кто писал этот код, очень хорошо знал Стандарт языка. В отличие от вас. Вон оно как? Стандартов не читал, да, признаю. Но вот будет ли так в дальнейшем - не совсем ясно, поэтому так писать лично я бы не стал. Ведь компиляторы все новее и новее, а оптимизация все хитрее. Никто не знает, во что это выльется в будущем.
|
|
|
|
|
Aug 25 2018, 07:21
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Arlleex @ Aug 25 2018, 10:08)  Но вот будет ли так в дальнейшем - не совсем ясно, поэтому так писать лично я бы не стал. Ведь компиляторы все новее и новее, а оптимизация все хитрее. Никто не знает, во что это выльется в будущем. Я тоже выше об этом писал. Понятно что сейчас это работает. Но такой подход и стиль считаю плохим. char тоже раньше всегда был знаковым, а сейчас может быть и беззнаковым, в зависимости от установок компилятора. Всё потому, что в появились некоторые CPU, в которых чтение/запись беззнаковых char короче чем знаковых, и во многих случаях, когда знаковость не важна, лучше использовать такие операции чтения/записи. Так и с этим - если CPU позволяет более эффективно работать с типами bool со значениями 0/-1, а не 0/1, то лучше так и делать, разрешив спец.опцией компилятора. Хотя конечно это гораздо менее часто встречающаяся потребность чем char, значит не очень важная.
|
|
|
|
|
Aug 25 2018, 07:39
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(jcxz @ Aug 25 2018, 10:21)  Я тоже выше об этом писал. Понятно что сейчас это работает. Но такой подход и стиль считаю плохим. char тоже раньше всегда был знаковым, а сейчас может быть и беззнаковым, в зависимости от установок компилятора. Про CPU с различными подходами в копировании char не знал, спасибо. Интересно конечно, как это может так быть - ведь копируются 8 бит все равно... А вот размышления вслух, можно сказать. Допустим есть условие if(x != y) или просто выражение z = (x != y). Переменные целые. Я бы на месте компилятора сделал что-то наподобие z = x - y или z = x ^ y. И если z равно 0, то это значило, что x == y. А если не равно 0, то, соответственно, x != y. Вот типичный случай, когда не нужны были бы лишние телодвижения по установке значения 1 в переменную вместо прямого присваивания результата вычитания. Меньше инструкций ведь по факту. И таких примеров оптимизаций, ИМХО, можно как-то еще придумать. Опять же, просто исходя из логики рассуждаю
Сообщение отредактировал Arlleex - Aug 25 2018, 07:42
|
|
|
|
|
Aug 25 2018, 09:23
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(jcxz @ Aug 25 2018, 10:59)  Загляните как-нить в листинг Cortex-M3/4 кода и сравните команды LDRB и LDRSB например. Поймёте почему. Для этого имхо и ввели дополнительный чекбокс в IAR "signed/unsigned char". Сходу не получилось заставить компилятор сгенерировать LDRSB... Использую armcc в составе Keil. Оптимизация 0. Галка "Plain Char is Signed" сброшена. Код Код volatile signed char a = 10; volatile signed char b = 20; volatile signed char c;
int main(void) { c = a - b; while(1); } формирует следующий листинг Код 0x080002E0 4805 LDR r0,[pc,#20] 0x080002E2 7800 LDRB r0,[r0,#0x00]; загрузили a 0x080002E4 4905 LDR r1,[pc,#20] 0x080002E6 7809 LDRB r1,[r1,#0x00]; загрузили b 0x080002E8 1A40 SUBS r0,r0,r1 ; вычли 0x080002EA B240 SXTB r0,r0 ; ИМХО, лишнее, т.к. SUBS работает 32-битными числами 0x080002EC 4904 LDR r1,[pc,#16] 0x080002EE 7008 STRB r0,[r1,#0x00]; загружаем результат в переменную c В случае, если переменные объявить без спецификатора signed (то есть с unsigned) то листинг тот же самый, но без SXTB С оптимизацией -O3 для signed/unsigned листинг одинаковый: Код 0x0800028C 4803 LDR r0,[pc,#12] 0x0800028E 7801 LDRB r1,[r0,#0x00] 0x08000290 7842 LDRB r2,[r0,#0x01] 0x08000292 1A89 SUBS r1,r1,r2 0x08000294 7081 STRB r1,[r0,#0x02]
Сообщение отредактировал Arlleex - Aug 25 2018, 09:33
|
|
|
|
|
Aug 25 2018, 09:59
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Arlleex @ Aug 25 2018, 12:23)  Сходу не получилось заставить компилятор сгенерировать LDRSB... Использую armcc в составе Keil. Оптимизация 0. Галка "Plain Char is Signed" сброшена. Всего лишь оптимизация умного компилятора Вы сами подумайте: раз Вы результат обратно сокращаете до 8 бит, то зачем тогда старшие биты вычислять? А если их вычислять не нужно, то можно ограничиться командами LDRB как более "дешёвыми". Тест Ваш построен некорректно. Для корректности теста сделайте int volatile c. Тогда, думаю, увидите LDRSB. Ну и для теста можно одно из a или b сделать отрицательным. Цитата(Arlleex @ Aug 25 2018, 12:23)  0x080002EA B240 SXTB r0,r0 ; ИМХО, лишнее, т.к. SUBS работает 32-битными числами Хоть это и лишнее, но это был намёк компилятора, что он заметил достаточность использования 8-бит для результата и поэтому не стал заморачиваться с правильным расширением входных аргументов.  PS: Код теста не совсем корректный, так как должен вызвать warning "undefined behavior".
|
|
|
|
|
Aug 25 2018, 10:24
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(jcxz @ Aug 25 2018, 12:59)  Тест Ваш построен некорректно. Для корректности теста сделайте int volatile c. Тогда, думаю, увидите LDRSB. Точно! И вправду LDRB заменились на LDRSB... Просто с расширением знака. Все четко по описанию команды загрузки с расширением знака Единственное, что отмечу. Разницы в количестве тактов выполнения не заметно... То есть по факту выполняются они одинаково по времени, только лишь представление числа в памяти нужным образом расширяется или нет, вот и вся разница, вроде как. Цитата(jcxz @ Aug 25 2018, 12:59)  PS: Код теста не совсем корректный, так как должен вызвать warning "undefined behavior". Из-за int перед main() и отсутствия возвращаемого результата? Тогда не неопределенное поведение, а что-то типа "недостижимый участок кода" и "отсутствие возвращаемого значения в функции, которая возвращает int"... Но Keil не паникует, кстати...
|
|
|
|
|
Aug 25 2018, 12:24
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Arlleex @ Aug 25 2018, 13:24)  Единственное, что отмечу. Разницы в количестве тактов выполнения не заметно... То есть по факту выполняются они одинаково по времени, только лишь представление числа в памяти нужным образом расширяется или нет, вот и вся разница, вроде как. Конечно разницы в тактах нет при условии наличия команды в кеше/конвеере CPU. Но в реальном МК команду ещё нужно выбрать из памяти, а ширина шины к памяти программ не бесконечна, как и скорость последней. Так что по времени выполнения - Вы не правы. Цитата(Arlleex @ Aug 25 2018, 13:24)  Из-за int перед main() и отсутствия возвращаемого результата? Нет. Из-за того, что в одном выражении используются две volatile-переменные. Порядок чтения которых внутри выражения неопределён. А volatile подразумевает строгость в порядке доступа. Цитата(Arlleex @ Aug 25 2018, 13:24)  Но Keil не паникует, кстати...  А зря. IAR реагирует на подобные выражения: "undefined behavior".
|
|
|
|
|
Aug 25 2018, 13:23
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(jcxz @ Aug 25 2018, 15:24)  Конечно разницы в тактах нет при условии наличия команды в кеше/конвеере CPU. Но в реальном МК команду ещё нужно выбрать из памяти, а ширина шины к памяти программ не бесконечна, как и скорость последней. Так что по времени выполнения - Вы не правы. Открыл TRM на Cortex-M3. Вижу, что CPI на LDRB и на LDRSB одинаковы и составляют 2 такта. Одинакова и их синтаксическая запись. Существуют как 16-битные, так и 32-битные версии обеих команд. При всех прочих равных условиях время выполнения LDRB и LDRSB одинаково. То, что команду нужно выбрать из памяти - это понятно. Но LDRB нужно выбрать точно так же, как и LDRSB в одном и том же коде. Ничем не отличается. Другое дело, если мы говорим о том, что загружать значение как оно есть и лишь потом программно еще расширять знак. Там да, несколько команд нужно: тот же LDRB + расширение знака, если требуется. Цитата(jcxz @ Aug 25 2018, 15:24)  Нет. Из-за того, что в одном выражении используются две volatile-переменные. Порядок чтения которых внутри выражения неопределён. А volatile подразумевает строгость в порядке доступа. Да, в упор не увидел очевидное... Жаль Keil не ругнулся никак даже при установке "All Warnings" в настройках компилятора
Сообщение отредактировал Arlleex - Aug 25 2018, 13:24
|
|
|
|
|
Aug 25 2018, 13:49
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Arlleex @ Aug 25 2018, 16:23)  Открыл TRM на Cortex-M3. Вижу, что CPI на LDRB и на LDRSB одинаковы и составляют 2 такта. Одинакова и их синтаксическая запись. Существуют как 16-битные, так и 32-битные версии обеих команд. При всех прочих равных условиях время выполнения LDRB и LDRSB одинаково. А Вы когда-нибудь пробовали заглядывать в листинг? И сколько вы там видели LDRB разной длины и сколько LDRSB? Формы-то может и есть, тут вопрос в количестве.... Попробуйте в .asm-файле ввести 2 такие команды и скомпилить: Код LDRB R0, [R0, #0] LDRSB R0, [R0, #0] А потом попробуйте поизменять регистры от R0 до R7 и посмотреть что получается. А теперь загляните в листинги и увидите, что большинство обращений к памяти как раз подобные формы команд: косвенная с константным смещением.
|
|
|
|
Сообщений в этой теме
ave! Проблема с условием Aug 20 2018, 08:18 aaarrr Цитата(ave! @ Aug 20 2018, 11:18) Под... Aug 20 2018, 08:45    jcxz Цитата(Arlleex @ Aug 22 2018, 15:33) А ещ... Aug 22 2018, 13:02               Arlleex Цитата(jcxz @ Aug 25 2018, 16:49) А Вы ко... Aug 25 2018, 14:15 ViKo Дык, обфускация. Aug 20 2018, 08:57 aaarrr Цитата(ViKo @ Aug 20 2018, 11:57) Дык, об... Aug 20 2018, 09:05 segment Да, да, она или дизассемблировано. Просто я однажд... Aug 20 2018, 09:00 Сергей Борщ QUOTE (ave! @ Aug 20 2018, 11:18) m =... Aug 20 2018, 09:01 Непомнящий Евгений Цитата(Сергей Борщ @ Aug 20 2018, 12:01) ... Aug 20 2018, 10:18  Сергей Борщ QUOTE (Непомнящий Евгений @ Aug 20 2018, 13... Aug 20 2018, 11:25   Непомнящий Евгений Цитата(Сергей Борщ @ Aug 20 2018, 14:25) ... Aug 20 2018, 12:35 ave! Цитата(Сергей Борщ @ Aug 20 2018, 12:01) ... Aug 20 2018, 11:36  jcxz Цитата(ave! @ Aug 20 2018, 14:36) Исп... Aug 20 2018, 11:47   _pv Цитата(jcxz @ Aug 20 2018, 18:47) Поэтому... Aug 20 2018, 12:16   ave! Приоритет операций C++ - это я себе в тему на заме... Aug 20 2018, 12:20    jcxz Цитата(ave! @ Aug 20 2018, 15:20) jcx... Aug 20 2018, 12:23     ave! Цитата(jcxz @ Aug 20 2018, 15:23) Мне каж... Aug 20 2018, 13:05      jcxz Цитата(ave! @ Aug 20 2018, 16:05) Сти... Aug 20 2018, 13:24       Сергей Борщ QUOTE (jcxz @ Aug 20 2018, 16:24) Возможн... Aug 20 2018, 13:28        jcxz Цитата(Сергей Борщ @ Aug 20 2018, 16:28) ... Aug 20 2018, 13:30 jcxz Цитата(ave! @ Aug 20 2018, 11:18) if ... Aug 20 2018, 11:17 yes ну дык (по описанию micro-Max) задача стояла миним... Aug 20 2018, 14:28 jcxz Цитата(yes @ Aug 20 2018, 17:28) ну дык (... Aug 20 2018, 16:12 ViKo Поскольку было объяснение, что писалось на конкурс... Aug 25 2018, 07:41 Obam Во времена настали: раздел про AVR, а тут про приг... Aug 25 2018, 19:46 jcxz Цитата(Obam @ Aug 25 2018, 22:46) Во врем... Aug 25 2018, 19:58 Obam Ну, на фоне 6502 и z80 вполне себе... Aug 27 2018, 15:33
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|