|
|
  |
Сопоставление проектов С и АСМ, Немного цифр |
|
|
|
Feb 18 2008, 07:58
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Для меня лично есть одно НО: вот я использую мультипоточное программирование на асме, стек-фреймы и прочее - так проще и читабельнее выглядят программы. Диспетчеризация кооперативная. При переходе от потока к потоку в свопинге участвуют только содержимое PC и SP. Все крутится на минимальном наборе регистров, потому что большая их часть задействована в прерываниях, в которых тоже свопинга мало. И под такую Homebrew - ось я заточить "С" не смогу никак. Вот вчера запустил ногодрыгалку на меге 640 по теме, которой я к Вам в личку напрашивался. Из 15 возможных ШИМ используются все с частотой до 10кГц. Из 16 АЦП используются все. + Дисплей 7 сегментный + клава + 2 модбаса + 1 RS232. И рад бы я это на "С" написать, потому как времени на это немного, но прикинул, что с учетом неперенесенных наработок и определенной критической массы Time-critical sections, да еще и трудностей с мультипотоком, писанины будет раза в 3 больше.
А тут же параллельно силовая поделка на: пульт на меге 8 (+модбас) контроллер: мега48+PIC18f2431 общаются по I2C (+модбас) Здесь без "С" вообще никуда.
А по качеству кода у меня и к Winavr претензий нет. И что самое приятное - чем тупее/тривиальнее/читабельнее код, тем лучше оптимизация.
|
|
|
|
|
Feb 18 2008, 08:32
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Это все не показатель. Если код на С заточить например под IARовский компилер и использовать его фичи: #pragma inline=forced __z __z_x и т.д. посмотреть как компилятся определенные конструкции у меня например есть макросы работы с кольцевым буфером в 256 байт выравненым, которые компилятся в Код LDS ZL, Head LDI ZH, HIGH(Buf) LD r??, Z+ STS Head, ZL
или если несколько байт надо вытащить
LDS ZL, Head LDI ZH, HIGH(Buf) LD r??, Z+ LDI ZH, HIGH(Buf) LD r??, Z+ STS Head, ZL использовать временные перменные Код { uint8_t tmp; if (tmp = TIFR1 & (1<<OCF1A)) { TIFR = tmp; .... } } можно получить код не хуже чем на асме! зато с большими функциями в которых используется много указателей и вычислений гемора не будет (IAR прекрасно пересылает указатели movw ZL:ZH, .....)
|
|
|
|
|
Feb 18 2008, 18:33
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(SasaVitebsk @ Feb 18 2008, 18:45)  Switec-овский алгоритм осилил за час Извиняюсь за оффтоп, но что такое "Switec-овский алгоритм"?
|
|
|
|
|
Feb 18 2008, 23:25
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
ИМХО. Написать С код соизмеримый с асмом можно, но требует таких же трудозатрат. А вот интеретно, использовали ли Вы такие приёмы? Код unsigned char a; a = delay_key; //токмо для "оптимизации". Иар почему-то все переменные считает как volatile. if (KEY_ON()) { if ( a != 255 ) delay_key = a+1; } else if (a) delay_key = a-1
|
|
|
|
|
Feb 19 2008, 06:50
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата А вот интеретно, использовали ли Вы такие приёмы? Дык это совершенно правильный код для помогания компилятору. В общем случае структура любой функции для камня с большим количеством регистров должна стремиться к такому виду: Код foo() { regvar1=memvar1; regvar2=memvar2; .... regvarn=memvarn; .... собственно вычисления .... memvar1=regvar1; memvar2=regvar2; ... memvarn=regvarn; } Другое дело, что сам компилятор должен стремиться к этому. Но не грех и помогать ручками. Конечно, пример вырожденный, но, я думаю, мысль мою описывает правильно...
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Feb 19 2008, 06:54
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(_Pasha @ Feb 18 2008, 11:58)  Для меня лично есть одно НО: вот я использую мультипоточное программирование на асме, стек-фреймы и прочее - так проще и читабельнее выглядят программы. ... А что такое стек-фреймы? Меня первый же безусловный переход вводит в ступор, а второй - в ярость. Это я так, нисколько не собираясь споров затевать.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Feb 19 2008, 07:59
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Dog Pawlowa @ Feb 19 2008, 09:54)  А что такое стек-фреймы? Меня первый же безусловный переход вводит в ступор, а второй - в ярость. Это я так, нисколько не собираясь споров затевать. Ну, я сразу все не напишу. Модель вкратце, остальное по уточняющим вопросам. Код .dseg Entry_Point: .byte 2 Save_SP: .byte 2 Local_SP: .byte 2 Local_Stack: .byte my_Stack_Size
Var1: .byte 1 ;.............................. VarN: .byte 2
.set Local_Var_Org = Var1 Это по данным. Предположим, у нас уже Y адресует начало этого блока данных Тогда пролог процедуры: Код ld zL,Y+ ld zh,Y+; load entry point in r0,spl in r1,sph st Y+,r0; store stack pointer st Y+,r1
ld r0,Y+ ld r1,Y+ cli out spL,r0 out sph,r1 sei ; at this line Y points to LOCAL DATA ijmp; resume procedure execution Эпилог соответственно восстанавливает все обратно Очень полезный макрос Код .macro leave; <new_entry_point_addr> ldi zL,low(@0) ldi zh,high(@0) jmp Epilogue .endm Итого в нашу пользу: 1. Имеем реентерабельные процедуры. Могу выложить пример, где 4 одинаковых процесса крутятся таким образом, выдают инфу каждый на свой индикатор (7-сегм), обрабатывают энкодер как орган управления (правда, плохонько, но претензий нет, я и не работаю над собой) 2. Читабельность зашкаливает Вместо приснопамятных переменных State мы переопределяем точку входа в процедуру. Что-нить проверили, кое-какое условие, затем просто пишем leave addr вместо rjmp Код Label1: call Test_Some_Conditions; breq Label2; leave Label1; exits here, but next entry point will be Label1 Label2:; continue program execution 3. Если глубина локального стека позволяет, можно вызывать другие подпрограммы, и если в них использовать leave, все еще интереснее. Т.е. с точки зрения программиста нормальная логика выполнения программ не нарушается. 4. Локальные данные адресуются с помощью yL:yH, намертво закрепленных за указателем Продолжать ?
|
|
|
|
|
Feb 19 2008, 10:42
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(_Pasha @ Feb 19 2008, 11:59)  Продолжать ? Нет, спасибо. Интересно, конечно, но я уже перешел на 'C' и возвращаться не имеет смысла. Однажды видел проект (система продажи билетов на ЖД эпохи начала перестройки), в котором использование макросов и условной компиляции поражало воображение, но для этого нужна свежая молодая голова. Too late
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Feb 19 2008, 10:57
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Dog Pawlowa @ Feb 19 2008, 13:42)  для этого нужна свежая молодая голова. Too late  Извиняюсь, не могу смолчать. 1. У меня голова уже точно не молодая и не свежая - сын в институте... 2. У атмелов-то правильных макросредств только недавно появилось  3. Немножко все-таки продолжу про минусы того,чего написал выше. Главный минус - это как детский вопрос : "Можно ли прикрутить туда 1-wire ?"
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|