|
|
  |
ASM: приказали долго жить?, Сколько еще продержится |
|
|
|
Jun 27 2006, 18:05
|
Частый гость
 
Группа: Новичок
Сообщений: 173
Регистрация: 3-09-04
Из: Moscow
Пользователь №: 595

|
Цитата(spf @ Jun 27 2006, 10:10)  Цитата(CD_Eater @ Jun 27 2006, 02:30)  Трёх указателей всегда хватало. Вспомнилось, в загрузщике по UART от Fujitsu кода на 800 байт написанном на асме изпользуется аж 6 (шесть) указателей. Хотя код как сами понимаете простейший. Да, пятью указателями там явно не обойтись
|
|
|
|
|
Jun 27 2006, 18:42
|
Частый гость
 
Группа: Новичок
Сообщений: 173
Регистрация: 3-09-04
Из: Moscow
Пользователь №: 595

|
Цитата(spf @ Jun 27 2006, 07:47)  Цитата По поводу стека - при правильном распределении регистров использование стека минимально. Опишите методику правильного распределения, причем безотносительно конкретного проца. Сомневаюсь, что оптимизацию кода, выполняемую вручную, можно описать простым алгоритмом. К тому же это зависит от опыта программиста. Лично мне доставляет неописуемое удовольствие процесс "утаптывания" программы, с целью получить сэкономленные байты и такты. Когда кажется, что всё уже минимизировано дальше некуда, приходит очередная хитрая идея, как изменить подход или алгоритм. Не понимаю тех, кто придерживается коммерческого подхода - побольше килобайт кода на скорую руку. Программирование превращается из искусства в ремесло. Сорри, отвлёкся. Если бы "правильное" распределение регистров (а также много чего ещё "правильного") можно было бы описать алгоритмически, это бы давно уже вставили в компиляторы. Но компиляторы используют обобщённые методы оптимизации, дающие средний результат на типичных задачах. А когда к каждой задаче подходишь индивидуально, с одной стороны есть семантика исходной задачи, с другой - особенности аппаратуры, и твоя задача - прокинуть наиболее элегантный мостик между этими берегами. Мне именно это и нравится в программировании - заставляет шевелить извилинами. Сорри, опять отвлёкся. Короче, обобщённого "правильного" распределения не существует, т.к. оптимизация существенно использует как особенности задачи, так и железа. А универсальность всегда получается в ущерб оптимальности. Цитата Цитата Может, Вам ещё вложенные стековые кадры с инструкциями enter/leave хочется в 8-битном МК ?  Есть и такое, например у всей линейки МК от Fujitsu, начиная с 8-ми битников. Не проверял, но сомневаюсь, что в МК засунут инструкцию, выполняющуюся сотни тактов. Для справки: у интеловской x86 инструкции enter есть параметр level, который может изменяться от 0 до 31. Именно об этой вложенности я и говорю. А Вы, вероятно, только про случай level=0. Если ошибаюсь - поправьте. Цитата Чаще необходима реентерабильность, которая без полноценногог стека нереализуема. Эта самая вещь позволяет экономить память и не ломать голову по ручному распределению памяти - экономия времени/нервов и крохотных ресурсов RAM МК. Почему сразу стек ? Удобнее каждому экземпляру давать структуру, в которой будут все локальности (а также входные параметры), а функциям передавать единственный параметр - адрес этой структуры. Располагая эти структуры в глобальной памяти, можно ограничивать одновременную количество экземпляров, которые сможет обработать МК. (Экземпляр - это ветвь и т.п.). А стек оставьте исключительно для push/pop, call/ret
|
|
|
|
|
Jun 28 2006, 01:06
|

Странник
   
Группа: Свой
Сообщений: 766
Регистрация: 29-08-05
Из: Екатеринбург
Пользователь №: 8 051

|
Цитата(CD_Eater @ Jun 28 2006, 00:42)  Лично мне доставляет неописуемое удовольствие процесс "утаптывания" программы, с целью получить сэкономленные байты и такты. Когда кажется, что всё уже минимизировано дальше некуда, приходит очередная хитрая идея, как изменить подход или алгоритм. Не понимаю тех, кто придерживается коммерческого подхода - побольше килобайт кода на скорую руку. То есть интересен сам процесс, а не результат  . Коммерческий подход - получить результат меньшей кровью и за меньшее время. Цитата Цитата Цитата Может, Вам ещё вложенные стековые кадры с инструкциями enter/leave хочется в 8-битном МК ?  Есть и такое, например у всей линейки МК от Fujitsu, начиная с 8-ми битников. Не проверял, но сомневаюсь, что в МК засунут инструкцию, выполняющуюся сотни тактов. Для справки: у интеловской x86 инструкции enter есть параметр level, который может изменяться от 0 до 31. Именно об этой вложенности я и говорю. А Вы, вероятно, только про случай level=0. Если ошибаюсь - поправьте. Может быть о разном говорим хотя названия похожи, асма на x86 под рукой нет. Для справки по МК от Fujitsu: ENTER #N - Function entry processing (где N - объем резервируемой памяти) LEAVE - Function exit processing Первая резервирует память в стеке для локальных переменных, вторая освобождает. При этом определенный регистр получает значение адреса начала локальных переменных в стеке, через этот регистр выполняются все операции с локальными переменными. Цитата Цитата Чаще необходима реентерабильность, которая без полноценногог стека нереализуема. Эта самая вещь позволяет экономить память и не ломать голову по ручному распределению памяти - экономия времени/нервов и крохотных ресурсов RAM МК. Почему сразу стек ? Удобнее каждому экземпляру давать структуру, в которой будут все локальности (а также входные параметры), а функциям передавать единственный параметр - адрес этой структуры. Располагая эти структуры в глобальной памяти, можно ограничивать одновременную количество экземпляров, которые сможет обработать МК. (Экземпляр - это ветвь и т.п.). А стек оставьте исключительно для push/pop, call/ret Зашибись, еще осталось определить union этих структур для каждого уровня вложенности вызовов функций и экономия памяти будет на уровне... про оптимизацию кода и говорить нечего. Титанический труд, сложность сопровождения, т.п. и т.д. и ни какой практической выгоды данного метода. А если OS потребуется запустить то там вообще туши свет, этож придется для каждой задачи объявлять отдельные экземпляры структуры и везде таскать указатели на них. Что-то я не пойму в чем удобство?! Написал считалку стека для MB9X, достаточно много анализировал расход памяти (стека в том числе) при разных подходах ее распределения. Пришел к выводу что ручное/статическое распределения памяти не дает экономии, часто даже проигрывает варианту с локальными переменными. Не думаю что для других процессоров ситуация будет иная.
--------------------
"Как много есть на свете вещей, которые мне не нужны!" Сократ
|
|
|
|
|
Jun 28 2006, 02:34
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Цитата Но компиляторы используют обобщённые методы оптимизации, дающие средний результат на типичных задачах. Вы не любите котов? Вы просто не умеете их готовить  Сам долго исповедывал взгляды сходные вашим....Пока жизнь не заставила хорошенько покопаться в Сишных листингах. Итак, чем же код генерируемый компилятором отличается от написанного ручками? 1.Стартапом 2.Вызовами/завершениями функций. Циклы, ветвления, присваивания итп. это и есть тривиальные задачи, котроые мало-мальски нормальный компилятор сгенерит также, как и самый искушенный программист. Стартап освобождает от совершенно рутинной и тривиальной задачи начальной инициализации памяти.Если у вас на этот счет свои соображения - никто не запрещает вам подключать собственный стартап или вообще обходиться без такового. Наиболее больной вопрос - вызовы функций и передача аргументов. Да, нужно это или нет, компилятор приведет все вызовы к стандартному виду. Это дает вполне очевидное преимущество - не задумываться о порядке вызова функций - аргументы передаются гарантировано, гарантировано сохраняется контекст. Расплата за это - несколько больший расход стека и снижение быстродействия. Однако, если вы более-менее хорошо знаете свой компилятор, это не есть проблема - вы четко знаете, сколько аргументов передастся через регистры, сколько раз вызовется push/pop. Дальше все в ваших руках - минимизация передаваемых аргументов, минимизация локальных переменных, привязка переменных к регистрам, inline -функции.Если вы правильно описали задачу - С быстро сгенерит вам работоспособный код, избавив от рутины и ошибок связанных с ней. Если время позволяет ее вылизывать - вы можете сделать это не хуже , чем на ассемблере. Если нет, можете оставить все как есть. Меньшее количество текста и недоступные явно метки и распределение памяти сильно облегчит модификцию кода методом copy/paste. Вместе с тем они не будут представлять из себя черный ящик - на физические адреса вы сможете посмотреть в любой момент. P.S.Здесь длинный спор между мной и dxp на тему оптимизации у gcc и IAR. Приводится ассемблерный код, можете ознакомится. http://electronix.ru/forum/index.php?showtopic=12284&st=75Интересным является два подхода к оптимизации - прямолинейный у gcc и с вывертами у IAR. Так что, и компилятор можно подыскать по вкусу.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jun 28 2006, 03:09
|
Знающий
   
Группа: Участник
Сообщений: 598
Регистрация: 22-08-05
Пользователь №: 7 861

|
Цитата(SpiritDance @ Jun 27 2006, 14:28)  Честно говоря о форте знаю только то что он есть. И знаю что он уже довольно долгое время после своего появления остается экзотическим языком, так что за его универсальность я бы не поручился. Однако, повторюсь, с языком не знаком. Данный ответ был мной предугадан  Жаль, знание возможностей данного языка не было бы лишним. Экзотичность языка, прежде всего, связана с его малой известностью( если не сказать почти 0-й) среди российских разработчиков аппаратуры и непониманием его идеалогии.
|
|
|
|
|
Jun 28 2006, 12:58
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(dxp @ Jun 26 2006, 16:59)  Если бы у AVR было 8 регистровых пар - аппаратных указателей типа Z, если бы на уровне этих регистровых пар поддерживалась арифметика, если бы AVR имел нормальный указатель стека, если бы AVR имел доступ в память в один такт, если бы он вообще был 16-разрядным, а еще лучше - 32-разрядным... и еще много-много всяких если. Со всем уважением к Вам. Не надо никаких если, давайте просто оценим, что же показывает ваш тест! 8 битный AVR - 11+тыс. тактов. 16-битный MSP - 5+ тыс. тактов. Только с учетом того, что рабочая частота AVR в два раза выше чем MSP, то 8-ми разрядный AVR по суммарной производительности практически равен производительности 16-ти разрядного MSP. Теперь об аппаратном умножителе. Судя по всему аппаратный умножитель AVR не применялся, следовательно для чистоты сравнения надо брать результат для MSP без аппаратного умножителя. Как Вы говорите, без аппаратного умножителя MSP справляется с задачей в 1.5 раза дольше, т.е. 7.5+ тыс. тактов. AVR - 11+ (~12) тыс. тактов Теперь давайте учтем соотношение частот AVR-16Mhz, MSP-8Mhz. Сведем все к MSPшным тактам. Один такт AVR равен 8/16 = 1/2 такта MSP. Домножаем 12 тыс на 1/2 12 * 1/2 = 6тыс. MSPшных тактов. И получаем, что AVR справляется с задачей за 6 тыс MSPшных тактов, а MSP за 7.5 тыс. тактов. LOL, так получается AVR еще и "сделал" MSP на 25%. Цитата Однако текущий факт, что MSP430 быстрее (в тактах), код у него меньше, ассемблер приятнее. Это первое. Если РОНы "шире" - неизбежно операции с плавающей точкой потребуют меньше тактов для исполнения. Поэтому все законно и ожидаемо на 16-bit РОНах FP операции выполняются быстрее, чем на 8 битных. И более того, я сказал бы, что результаты этого теста больше в пользу AVR, т.к. имея в два раза меньшую разрядность, наблюдается замедлениние в два раза (практически линейная зависимость, что вполне естественно). Цитата Во-вторых, это не тест, а, как было указано, кусок из реальной программы. А привел я его потому, что сделать это было просто - остальные куски аналогичные собрать было бы сложно, да и не понятно посторонним, что они делают. Об условностях и ограничениях этого примера я представление имею, о чем и говорил. Я из вашего теста могу построить следующий вывод: На одинаковых тактовых частотах AVR проигрывает MSP приблизительно в два раза (в большинстве задач - меньше чем в два раза). В реальных задачах AVR работает быстрее чем MSP430 за счет более высокой тактовой частоты ядра, поэтому добавив еще и факт, что AVR дешевле MSP - целесообразнее применять именно AVR. Цитата И кстати, 32-разрядный Blackfin что-то не опережает MSP430 в 4 (!) раза. А уж у него-то все в наличие - и шины, и регистры, и все остальное. Вы хотите сказать, что Bf будет 1.25+ тыс тактов выполнять код из Вашего теста?
|
|
|
|
|
Jun 29 2006, 05:24
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(defunct @ Jun 28 2006, 19:58)  Не надо никаких если, давайте просто оценим, что же показывает ваш тест! Да что вы все прицепились к этому тесту?!  Я сразу сказал и повторил, что это, во-первых, не тест как таковой, во-вторых, он не характеризует картину в полной мере - тут плавучка, а значит тут доминируют два фактора: 1) реализация библиотек, где определены подпрограммы операций с плавающей точкой; 2) эффективность ядра, т.к. операции в ядре доминируют над операциями с памятью. У MSP430, как и у любого фон Неймана, работа с памятью - слабое место. А вот ядро у него хорошее - регистровый файл, каждая операция в регистрах за один такт. Никакой 8-битных процессор тут не поспорит. Вот и все. И давайте уже оставим этот фрагмент кода. На деле, как уже неоднократно сказал, MSP430 быстрее почти везде. При равных тактовых, ессно, т.к. сравнивается эффективность ядра. Цитата(defunct @ Jun 28 2006, 19:58)  8 битный AVR - 11+тыс. тактов. 16-битный MSP - 5+ тыс. тактов. Только с учетом того, что рабочая частота AVR в два раза выше чем MSP, то 8-ми разрядный AVR [...] И получаем, что AVR справляется с задачей за 6 тыс MSPшных тактов, а MSP за 7.5 тыс. тактов. LOL, так получается AVR еще и "сделал" MSP на 25%. Какую-то Вы тут софистику устроили. Зачем это? В реальных проектах MSP430 быстрее почти везде. Не в два раза, конечно, но процентов на 10-20. Это неоднократно установленный мной факт. Хотите поисследовать - пожалуйста, все в Ваших силах. Начать можете с того примера, который я уже предлагал, там почти одинаковый код. Очень хорошо видна реализация в обоих случаях. Упора на 16-битность данных там нет. Цитата(defunct @ Jun 28 2006, 19:58)  Я из вашего теста могу построить следующий вывод: На одинаковых тактовых частотах AVR проигрывает MSP приблизительно в два раза (в большинстве задач - меньше чем в два раза). В реальных задачах AVR работает быстрее чем MSP430 за счет более высокой тактовой частоты ядра, поэтому добавив еще и факт, что AVR дешевле MSP - целесообразнее применять именно AVR. Вы еще забыли про потребление. Вот тот полином у меня вычислялся в проце, работающем на 5 МГц - хватало, - при этом весь МК побреблял около 2.4 мА при питании от 3 В. Дивайс батарейный. Найдите-ка мне такой AVR? В реальных задачах надо не максимальную скорость - тут главное, чтоб успевал с некоторым запасом. А вот потребление частенько требуется как можно меньше. Вот у меня МК посчитал результат, отправил его на вывод, и на боковую (в Idle). А из Idle он просыпается за 6 мкс. Таким образом, почти все неактивное время он спит, переход ко сну и обратно почти ничего не занимает. Эффективность максимальная. Насчет того, дешевле ли AVR - это еще вопрос! AVR не предлагает полноценной замены MSP430 почти во всем: он медленее, он больше потребляет, у него почти во всем хуже периферия, у него нет такой удобной и гибкой системы распределения тактовых частот. Кроме того, у MSP430 на борту встроенный отладчик, который требует копеечного адаптера, в отличие от AVR, которому нужен недешевый JTAG-ICE, работающий к тому же нестабильнее и медленнее. Возможности отладчика в MSP430 новых моделей несравенно богаче - до 8 аппаратных брейкоинтов, не только на код, но и на данные, всякие условные брейкпоинты и т.д. Преимущества AVR я уже перечислял выше - возможность 5 В питания, если кому актуально (мне,например, никогда это не было актуально - наоборот, от 5 В только лишнее энергопотребление), возможность внешней аппаратной шины у некоторых МК (опять же это только пара чипов, да и на MSP430 можно программно это организовать, написав класс-шлюз, чтобы работа со стороны программы была прозначной по отношению к этой шине), наличие EEPROM (здесь удобство AVR неоспоримо, но с MSP430 большого головняка не вышло - тоже написал класс, который манагит запись данных в блоки флеши попеременно, пользоваться этим просто и безопасно. С EEPROM'ом, кстати, тоже для надежности надо дополнительный код писать, с резервированием значений и проверкой при записи/чтении, т.ч. оно где-то одно к одному и выходит). Это практически все. На деле существуют ситуации, когда AVR выгоднее и без этих оговорок - когда требования проекта удовлетворяются возможностями МК. Например, если хватает меги8, то и замечательно, ничего больше не нужно, даже если есть и более замечательные МК. Фактически же главным фактором является даже не возможности МК, а владение конкретным разработчиком тем или иным МК. Если человеку, работающему с AVR что-то в нем не хватает, он в большинстве случаев поставит недостающую часть снаружи (вплоть до применения второго МК), но не будет переходить на MSP430. Это психология и инертность мышления. А также требования по времени к выполнению работы на фоне внутренней увереннности в результате. По этой причине до сих пор жив 51-й (конечно, есть тут и другая причина - поддержка старых разработок, но старые разработки требуют старых МК, на оригинальном 12-тактовом ядре, а вот все новые, с новой периферией и новыми возможностями - это исключительно психология). Цитата(defunct @ Jun 28 2006, 19:58)  Цитата И кстати, 32-разрядный Blackfin что-то не опережает MSP430 в 4 (!) раза. А уж у него-то все в наличие - и шины, и регистры, и все остальное. Вы хотите сказать, что Bf будет 1.25+ тыс тактов выполнять код из Вашего теста? Что Вас удивляет? У него нет аппаратной поддержки плавающей точки.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jun 29 2006, 05:32
|
Знающий
   
Группа: Участник
Сообщений: 598
Регистрация: 22-08-05
Пользователь №: 7 861

|
Ссылка на интересную статью и ресурс для роботостроителей. ( в проекте используется ATMEGA128 ) http://rema.44.ru/about/persons/dobrinin/P.S. Не ассемблер, но тоже интересный подход. Не знаю, в какой топик лучше поместить.?
|
|
|
|
|
Jun 29 2006, 05:55
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(upc2 @ Jun 29 2006, 12:32)  Прощай асм. Интересно, как, например, Вы будете делать сохранение констакста при переключении задач ОС без асма? Таких примеров еще можно найти. Поэтому давайте различать асм, как основной инструмент для написания программ, и как вспомогательный. Как основной он уже умер (за исключением отдельных случаев типа DSP, но и там тенденция однозначная). Как вспомогательный инструмент он жив и будет жив до тех пор, пока живы процессоры.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jun 29 2006, 06:28
|
Местный
  
Группа: Свой
Сообщений: 200
Регистрация: 10-04-06
Из: Украина,Запорожье
Пользователь №: 15 979

|
Цитата(Harbour @ Jun 20 2006, 08:25)  Сильно на C разгонишься когда памяти 512 байт. Дык если с умом писать то разгонишся очень сильно Было у меня куча проектов достаточно сложных и объемных и в 512байт влезал аж бегом.Асм нужен для того чтобы тока критические секции писать.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|