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

Твердыня модульных языков
Текущее время: 20 июн 2025, 08:51

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




Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу Пред.  1, 2, 3
Автор Сообщение
СообщениеДобавлено: 27 июн 2014, 11:56 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Появилась идея сверхоптимизации в Оберон-программах. Создаётся, отлаживается и обкатывается высокоуровневый Оберон-вариант алгоритма, он же остаётся кроссплатформенным. А уж потом оптимизируем его по самое небалуйся, переписывая на ассемблер, притом, разумеется, только в самых критичных местах, как и положено.
Код: "OBERON"
  1. MODULE Labirint;
  2. IMPORT Asm;
  3.  
  4. CONST
  5. Assembler = TRUE; Oberon = ~Assembler;
  6.  
  7. FieldWidth = 16;
  8. FieldHeight = 16;
  9. FieldSize = FieldWidth * FieldHeight;
  10.  
  11. TYPE
  12. Coords = SHORTINT; (* Coordinates in labirinth *)
  13. Cell = CHAR; (* An object of labirinth *)
  14.  
  15. VAR
  16. field: ARRAY FieldSize OF Cell;
  17.  
  18. PROCEDURE SetCell (x, y: Coords; cell: Cell);
  19. BEGIN
  20. IF Oberon THEN
  21. field[((y DIV 2) * FieldWidth) + x DIV 2] := cell;
  22. ELSE
  23. Asm.Code("LD A, 5(IX)"); (* y *)
  24. Asm.Code("RLA "); (* y DIV 2 *)
  25. Asm.Code("LD L, A ");
  26. Asm.Code("LD H, #0 ");
  27. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 2 *)
  28. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 4 *)
  29. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 8 *)
  30. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 16 *)
  31. Asm.Code("LD A, 4(IX)"); (* x *)
  32. Asm.Code("RLA "); (* x DIV 2 *)
  33. Asm.Code("ADD A, L ");
  34. Asm.Code("LD L, A "); (* + Low byte *)
  35. Asm.Code("LD A, H ");
  36. Asm.Code("ADC #0 "); (* + CarryFlag *)
  37. Asm.Code("LD H, A ");
  38. Asm.Code("LD DE, #_Labirint_field");
  39. Asm.Code("ADD HL, DE "); (* field[(y DIV 2) * 16 + x DIV 2] *)
  40. Asm.Code("LD A, 6(IX)"); (* cell *)
  41. Asm.Code("LD (HL), A ");
  42. END;
  43. END SetCell;
  44.  
  45. PROCEDURE GetCell (x, y: Coords): Cell;
  46. BEGIN
  47. IF Oberon THEN
  48. RETURN field[((y DIV 2) * FieldWidth) + x DIV 2]
  49. ELSE
  50. Asm.Code("LD A, 5(IX)"); (* y *)
  51. Asm.Code("RLA "); (* y DIV 2 *)
  52. Asm.Code("LD L, A ");
  53. Asm.Code("LD H, #0 ");
  54. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 2 *)
  55. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 4 *)
  56. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 8 *)
  57. Asm.Code("ADD HL, HL "); (* (y DIV 2) * 16 *)
  58. Asm.Code("LD A, 4(IX)"); (* x *)
  59. Asm.Code("RLA "); (* x DIV 2 *)
  60. Asm.Code("ADD A, L ");
  61. Asm.Code("LD L, A "); (* + Low byte *)
  62. Asm.Code("LD A, H ");
  63. Asm.Code("ADC #0 "); (* + CarryFlag *)
  64. Asm.Code("LD H, A ");
  65. Asm.Code("LD DE, #_Labirint_field");
  66. Asm.Code("ADD HL, DE "); (* field[(y DIV 2) * 16 + x DIV 2] *)
  67. Asm.Code("LD L, (HL) ");
  68. END;
  69. END GetCell;
  70.  
  71. END Labirint.
Ветка "IF Oberon THEN .. ELSE .. END" — это аналог сишных #ifdef'ов, и код неактивной ветки в целевой бинарник не попадает.

Такой код компилируется и собирается благодаря предложенному Reobne модулю Asm. :)


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 27 июн 2014, 16:41 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Продублирую сюда свою идею из FOR-темы:
Цитата:
Мы нашли довольно неплохие команды ассемблера, но как поместить их в конечный код? Модифицировать Ofront, чтобы генерировал ассемблерные вставки вместо операторов Си? Можно, но тогда теряется кроссплатформенность. Более гибким мне представляется следующий подход: Ofront транслирует цикл FOR в некие псевдооперации (repeat_for(id) … until_for_Z(id)), которые являются макросами Си. Для дальнейшей трансляции подключается библиотека макросов, зависящая от целевой платформы. В этой библиотеке макросы переводятся в последовательность команд ассемблера , либо в простые операторы С, подходящие всем платформам (например repeat_for(id) - > “do{”, until_for_Z(id) - >”}while (id != 0)”).
Понятно, что такой механизм эффективных макроподстановок можно применить не только для реализации цикла FOR.
и далее
Цитата:
Конечно, хорошо, когда есть глобальные оптимизации на уровне самого компилятора. Но в С-исходнике может не хватать некоторой информации. Например не видно, что этот do while (id=0); является реализацией цикла FOR и поэтому id после завершения цикла можно испортить или использовать в своих целях.
Если мы применим макросы, то такая информация будет. Исходник на Си превратится в прогу на неком "псевдоСи" (или лучше назвать "макроСи"?), операторы которого несут дополнительную информацию и могут быть оптимизированы более качественно. Т.е. появляется дополнительный уровень: Оберон -> макроСи -> Си -> Ассемблер. И "макро" могут транслироваться сразу на уровень Ассемблера, если для них придуманы эффективные ассемблерные команды.А если еще не придумали, то этот "макро" легко превращается обратно в Си.


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

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


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

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


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

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