Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 28 мар 2024, 12:41

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ Сообщений: 63 ]  На страницу Пред.  1 ... 3, 4, 5, 6, 7  След.
Автор Сообщение
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 26 июл 2019, 17:54 
Не в сети

Сообщения: 35
Comdiv писал(а):
Есть простейшая реализация кучи как стека - лучше, чем ничего. Но если на всех целевых микроконтроллерах памяти всегда мало, то без освобождения только лучше.

Так и сделано

Comdiv писал(а):
Цитата:
- Системные флаги (пока не нужно)
Что это?

[ccall], [noalign], ... -- такое же расширение, как и DISPOSE, WCHAR.

Comdiv писал(а):
Необходимость использовать SYSTEM без возможности задействовать более удобные способы лезть в систему способствует выработке предметного слоя абстракции при наличии минимального понимания у разработчика.


По поводу SYSTEM.
Нижние 512 байт адресного пространства (0H-01FFH) занимают регистры специальных функций и регистры 8- и 16-битной периферии.
Сейчас, обращение к ним осуществляется через SYSTEM.GET/SYSTEM.PUT. Это просто, универсально, но выглядит некрасиво.
Возможные решения:

- использовать переменную-указатель
Код: "OBERON"
  1.  
  2. CONST
  3. REDLED = 1;
  4. GREENLED = 40H;
  5.  
  6. WDT = (120H - 100H) DIV 2;
  7. P1DIR = 22H - 10H;
  8.  
  9. VAR
  10. p8: POINTER TO RECORD r: ARRAY 240 OF BYTE END;
  11. p16: POINTER TO RECORD r: ARRAY 128 OF INTEGER END;
  12.  
  13. BEGIN
  14. SYSTEM.PUT16(SYSTEM.ADR(p8), 10H); (* 8-битные устройства находятся в адресах 10H .. 0FFH *)
  15. SYSTEM.PUT16(SYSTEM.ADR(p16), 100H); (* 16-битные устройства находятся в адресах 100H .. 1FFH *)
  16.  
  17. p16.r[WDT] := 5A80H; (* отключить сторожевой таймер *)
  18. p8.r[P1DIR] := REDLED + GREENLED;

недостатки: длинная запись, т. к. нет указателей на массивы; обращение к устройствам по индексу в массиве, а не по адресу; кроме того, компилятор будет вставлять ненужную проверку на NIL (но это можно отключить).

- сделать возможным указать адрес переменной при объявлении
Код: "OBERON"
  1. CONST
  2. REDLED = 1;
  3. GREENLED = 40H;
  4.  
  5. aWDT = 120H;
  6. aP1DIR = 22H;
  7.  
  8. VAR
  9. WDT [aWDT]: INTEGER;
  10. P1DIR [aP1DIR]: BYTE;
  11.  
  12. BEGIN
  13. WDT := 5A80H; (* отключить сторожевой таймер *)
  14. P1DIR := REDLED + GREENLED;
  15.  


Второй вариант выглядит лучше и должен быть эффективнее и компактнее.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 26 июл 2019, 23:09 
Не в сети

Сообщения: 146
Тут, на мой взгляд, можно совершить ту же ошибку, что широко распространена во многих платформах-языках.
Есть абстракция языка программирования - переменные. Есть память как аппаратное устройство - часть компьютера. Переменные языка, в основном, отображаются на это устройство, поэтому когда возникает необходимость работы с памятью именно как с устройством, возникает соблазн работать с ним через всю ту же языковую абстркацию, расширив её дополнительными понятиями, наподобие volatile, absolute address, и других. Но ошибка заключается в ошибочном выборе представления, из-за чего вид кода не соответствует тому, что он делает. Если с памятью нужно работать как с устройством, то и использовать лучше абстракцию языка, больше соответствующее устройству - процедуры. Например
Код: "OBERON"
выглядит лучше в виде чего-то такого
Код: "OBERON"
  1. Device.Watchdog(FALSE);

а этот код
Код: "OBERON"
  1. P1DIR := REDLED + GREENLED
так
Код: "OBERON"
  1. Device.TurnLed({REDLED, GREENLED})


Если нужен обобщённый механизм, то всё равно лучше использовать процедуры
Код: "OBERON"
  1. Device.PutInt(WDT, 5A80H);
  2. Device.PutByte(P1DIR, REDLED + GREENLED);
И пусть всё будет эффективно за счёт псевдомодульности или иных, менее хардкодных способов оптимизации


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 27 июл 2019, 06:52 
Не в сети

Сообщения: 35
Понятное дело, чем меньше ресурсы системы, тем ближе средства разработки к железу.
Тут уж не до абстракций -- такты и байты сэкономить бы.
Но вообще, это надо как следует продумать, а пока обкатать то, что есть.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 27 июл 2019, 12:33 
Не в сети

Сообщения: 146
akron1 писал(а):
Тут уж не до абстракций -- такты и байты сэкономить бы.
Абстракции же не обязаны отнимать дополнительные ресурсы во время исполнения программы.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 12 авг 2019, 16:43 
Не в сети

Сообщения: 35
Я переписал RTL (MSP430) в машинных кодах и встроил его в компилятор, так, чтобы в прошивку добавлялись только те процедуры RTL, которые используются. Это позволило снизить минимально допустимый размер ПЗУ до 2048 байт, а также значительно увеличило производительность для некоторых операций. В процессе переписывания, выяснилось, что рукописный машинный код получается в 2-3 раза меньше и в 2-4 раза быстрее. Впрочем, я ожидал получить результат еще хуже. Компилятор всё же написан не для хорошей кодогенерации, а для быстрого добавления бэк-эндов. Кое-что в кодогенерации еще можно улучшить, ну а пока, если я ничего не забыл, для простых экспериментов уже подходит.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 12 авг 2019, 20:01 
Не в сети
Аватара пользователя

Сообщения: 67
Откуда: Equestria
Почему бы не маркировать используемые процедуры? Все равно используется IL, а не прямая генерация, можно без проблем дропать неиспользуемое.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 12 авг 2019, 21:33 
Не в сети

Сообщения: 35
SovietPony писал(а):
Почему бы не маркировать используемые процедуры? Все равно используется IL, а не прямая генерация, можно без проблем дропать неиспользуемое.

Для пользовательских процедур так и сделано. Фронт-энд, перед передачей промежуточного кода в бэк-энд, удаляет неиспользуемые процедуры. Но для RTL все намного сложнее. Фронт-энд знает только имена процедур, но не знает об их назначении. Например, если фронт-энд встречает операцию целочисленного умножения, то он генерирует команду MUL промежуточного кода. Бэк-энд, встречая команду MUL, если это x86, транслирует ее в машинную команду imul, а если это MSP430 - в вызов процедуры RTL._mul. Таким образом, фронт-энд не знает, какая операция потребует вызов RTL-процедуры (и не должен знать). Бэк-энд получает линейный список команд промежуточного кода и не имеет информации об использовании процедур (RTL-процедура может вызвать другую RTL-процедуру или вспомогательную). Поэтому модуль RTL всегда добавляется в результирующий файл полностью. Фронт-энд считает, что все процедуры RTL._* используются. Для больших машин, удалять неиспользуемые части RTL не нужно: размер RTL для x86(64) < 10 кб. А для контроллеров лучше встроить RTL в бэк-энд и, тем самым, сэкономить байты и такты без усложнения компилятора. Сложно, разве что, программировать в маш. кодах, но для MSP430 это оказалось сравнительно просто.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 21 янв 2020, 09:56 
Не в сети

Сообщения: 35
Сделал бэк-энд для микроконтроллеров STM32 Cortex-M3. Пока качество машинного кода оставляет желать лучшего (сравнение с компилятором Александра Ширяева показало 70-90% производительности), но вроде всё работает. Хотя компилятор предназначен для архитектуры ARMv7, он пока производит очень старый машинный код (thumb-1) и кроме одной команды совместим с ARMv4T. Размер пустой программы тоже немаленький - 12 кб, хотя флэш-памяти в этих микроконтроллерах обычно довольно много и нет причин сильно экономить. В дальнейшем, переход от thumb-1 к thumb-2, а также частичное переписывание RTL в маш. кодах позволит несколько улучшить эффективность и уменьшить размер прошивки.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 04 фев 2020, 12:09 
Не в сети

Сообщения: 146
akron1 писал(а):
Пока качество машинного кода оставляет желать лучшего (сравнение с компилятором Александра Ширяева показало 70-90% производительности)
Не подскажете, почему так? Ведь компилятор Ширяева максимально прямой с минимумом преобразований


Последний раз редактировалось Comdiv 04 фев 2020, 17:17, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 04 фев 2020, 16:12 
Не в сети

Сообщения: 35
Ну, во-первых, набор инструкций thumb-1 менее эффективный, чем thumb-2. Сейчас компилятор уже транслирует в thumb-2, не везде где можно, но там, где это наиболее важно. Благодаря этому, эффективность кода теперь 80-100% от компилятора Ширяева. Размер пустой программы уменьшен до 7400 байт.

Во-вторых - плохая трансляция логических операций OR/&.
SovietPony писал(а):
Я делал под них 16-битный варинт оберона-07 дедовским способом, правда на пол-пути застрял на логических & и OR, забил, а потом похоже пролюбил последнюю версию исходников когда разобрался как делать правильно. А если бы делал деревом, то было бы труднее запутаться.

Я хоть и не запутался, но сделал это через одно место... Кодогенератор сохраняет значение логического выражения в регистре, затем сравнивает значение регистра с нулем и выполняет условный переход, вместо того, чтобы сразу генерить условный переход. И так во всех бэк-эндах. Я пока не придумал, как это исправить без переписывания значительной части. С другой стороны, "хорошая" трансляция логических выражений позволит выиграть лишь 10-20% производительности, и только для некоторых задач.

Есть еще некоторые существенные отличия в кодогенерации от компилятора Ширяева:
- компилятор Ширяева генерит специальные машинные инструкции для вещественной арифметики, мой - эмулирует вещественную арифметику, т. к. в ядрах Cortex-M3 нет FPU, а компилятор сейчас тестируется именно на Cortex-M3. Эмуляция пока очень неэффективная (здесь надо будет переписать в машинных кодах). В дальнейшем, можно также сделать поддержку вещественных инструкций, чтобы получить более эффективный код для микроконтроллеров с FPU (Cortex-M4F).
- компилятор Ширяева генерит только короткие команды переходов. Если расстояние перехода слишком большое - программа не компилируется. Мой - генерит длинные либо короткие переходы в зависимости от расстояния, а также поддерживает инструкцию cbz/cbnz. Это несколько сглаживает недостатки трансляции OR/&.

Ну а вообще... Я сейчас испытываю определенное разочарование и в Обероне и в своем компиляторе. Добавление очередного кодогенератора превратилось в рутину, творческий процесс почти отсутствует. Игрушечные языки и компиляторы мне надоели. Нужен или более серьезный язык, или оптимизирующий компилятор...


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 63 ]  На страницу Пред.  1 ... 3, 4, 5, 6, 7  След.

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club