Важная информация

User Tag List

Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 15

Тема: OVERLAYS! оверлеи линковщики своп

  1. #1
    Guru Аватар для bigral
    Регистрация
    12.07.2006
    Адрес
    г. Киев, Украина
    Сообщений
    2,147
    Спасибо Благодарностей отдано 
    25
    Спасибо Благодарностей получено 
    95
    Поблагодарили
    82 сообщений
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    Smile OVERLAYS! оверлеи линковщики своп

    Всем имеющим хоть какой-то практический опыт "обхода" ограничений накладываемых адресуемым пространством просьба высказать свои мысли, опыт, наработки, советы, впечатления в этой теме.

    Для тех кто "в танке" - суть проблемы тут http://en.wikipedia.org/wiki/Overlay_%28programming%29

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    Veteran
    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,053
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    47
    Поблагодарили
    31 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Я в 1996г создавал программу управления программатором ПЗУ. Имея 256К ОЗУ на ZX, приходилось работать с двумя буферами образа ПЗУ по 64Кб каждый, применяя страничную адресацию.

    Буфера были размещены по границам страниц. Были подпрограммы чтения и записи байта в буфер по 16-битному адресу внутри буфера. Работали они очень медленно, ведь для чтения или записи каждого байта приходилось вычислять адрес, переключать страницы, а потом переключать их назад. В результате скорость работы программатора определялась не скоростью работы микросхем ПЗУ или самого программатора, а скоростью доступа в буфер. Одним словом, тормозно было.

    Особенно большие тормоза наблюдались при чтении и записи содержимого буферов на диск. Ведь если подготовка данных занимает слишком большое время - то головка проскакивает над нужным сектором, и приходится ждать следующего оборота диска. Поэтому для целей чтения и записи на диск пришлось сделать блочный доступ к буферам в памяти. То есть с дискеты считывалось несколько секторов (как правило, дорожка целиком) в промежуточный буфер, после чего из промежуточного буфера данные уже помещались в основной, тоже побайтно. Тоже тормоза, но чуть меньше.

    Тем не менее, благодаря тому, что я не вылизывал эти частные моменты, программа "Omniprog" управления программатором была создана в рекордно короткие сроки и имела множество полезных функций и красивый интерфейс пользователя. А тормоза - дело относительное. Несмотря на неэффективный доступ к памяти, Omniprog работал быстрее, чем другие доступные на то время программаторы, в том числе те, которые работали на PC.

    Если бы я все это дело разрабатывал сейчас - то сразу реализовал бы блочный доступ к основным буферам, т.е. извлекал оттуда или помещал туда сразу блоки, а не отдельные байты. Думаю, в этом случае основные тормоза были бы побеждены.

    Но блочный доступ реализовать сложнее, чем побайтный. Например, для пересылки блока произвольной длины с произвольного виртуального адреса нужно учитывать ситуации, когда этот блок переходит через границу страницы. Также блочный доступ сложнее использовать в подпрограммах высокого уровня. Например, функция поиска строки в буфере тривиально реализуется в случае побайтного доступа. А в случае блочного - нужно разбить весь процесс на отдельные блоки и как-то отрабатывать переходы через их границы.
    Последний раз редактировалось Barmaley_m; 27.05.2014 в 16:36.

  4. #3
    Master
    Регистрация
    27.01.2005
    Сообщений
    888
    Спасибо Благодарностей отдано 
    25
    Спасибо Благодарностей получено 
    163
    Поблагодарили
    131 сообщений
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    ИМХО.

    Нужен манагер памяти, который умеет:

    1. Создавать многостраничную кучу.
    2. malloc() free() - выделение и освобождение памяти в куче.

    3. memcpy() - копировать блок (без перекрытия)
    4. memmove() - копировать блок (с перекрытием)
    5. LongJump() - межстраничный переход
    6. LongCall() - межстраничный вызов.

    ... Функции поиска и копирования массивов

    Все адреса (указатели) - виртуальные, в формате 32 бита.
    Так их проще на стеке сохранять. В незначащих битах можно хранить доп.информацию.

    Для тех спеков, что умеют любую страницу в любое окно - реализация довольно проста.

    Скажем:
    0-3FFF - ПЗУ (может замещаться озу при копировании из страницы в страницу)
    4000 - 7FFF - озу, где расположен менеджер памяти и другие неудаляемые вещи.
    8000 - BFFF - 1я страница программы-библиотеки-оверлея-данных
    С000 - FFFF - 2я страница данных (скажем, экран)

    Таким образом, максимальный объём одного программного модуля 16К. Весьма немало.

  5. #4
    Guru Аватар для Vadim
    Регистрация
    24.07.2008
    Адрес
    г. Курган
    Сообщений
    2,062
    Спасибо Благодарностей отдано 
    10
    Спасибо Благодарностей получено 
    17
    Поблагодарили
    17 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Barmaley_m Посмотреть сообщение
    Работали они очень медленно, ведь для чтения или записи каждого байта приходилось вычислять адрес, переключать страницы, а потом переключать их назад.
    А почему бы не работать с 16К блоками? Или хотя бы 256 байт, явно быстрее было бы

    Скрытый текст

    Profi 5.06 1024K 12Mhz (кварц на 24), палитра, COM-порт, часы, hdd, covox, программатор
    ZX-Spectrum +3, ZX-Spectrum +2B, ZX-Spectrum +2, ZX Spectrum 48, ZX Spectrum 48+
    ZX Evolution Rev B.
    Color 48 + Beta Disk Interface +FDD+YM2149F
    Орель-08БК
    Pentagon-48 (недоссобранный кем-то)
    Pentagon-128 (полуубитый)
    Кворум-128 (в ремонте)
    Магик-05 (в ремонте)
    Robotron 1715
    Корвет ПК8020 и ПК8010
    Amstrad CPC 464
    Amstrad CPC 6128
    [свернуть]

  6. #5
    Veteran
    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,053
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    47
    Поблагодарили
    31 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Vadim Посмотреть сообщение
    А почему бы не работать с 16К блоками? Или хотя бы 256 байт, явно быстрее было бы
    Разумеется, быстрее. Но представь себе, стоит задача: найти по адресам 24F7-48A2 строку "abcde". Если использовать непосредственный доступ к памяти или подпрограмму чтения байта по логическому адресу - то такой поиск пишется легко. А если блоками - то это надо отрабатывать кучу граничных условий, размер программы разрастается, и ее становится трудно отлаживать.

    В остальных ситуациях все было точно так же. Нужно было что-то делать с участком буфера ПЗУ по каким-то логическим адресам. Например, считать из микросхемы, прошить в микросхему, считать с диска, записать на диск и т.д.

    Даже имея сегодняшний опыт, на ассемблере писать все эти процедуры с блочным доступом было бы значительно сложнее, в том числе с точки зрения отладки, чем с побайтовым. И заняло бы дольше времени. Как минимум день бы лишний на это ушел. А программа писалась в сжатые строки, на одном дыхании. Поэтому на оптимизацию доступа времени не нашлось. Зато все отлично работало и без глюков.

    Я вовсе не говорю, что побайтовый доступ - хорошая идея. Наоборот, очевидно, что она обречена на медленность. Но зато код пишется легко. А блочный доступ конечно быстрее.

  7. #6
    Veteran Аватар для Hacker VBI
    Регистрация
    05.03.2013
    Адрес
    г. Канев, Украина
    Сообщений
    1,596
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    2 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    SfS, в tsconf имеем маппинг рам в 0, 4000, 8000, с000.
    Для таких прикладных задач особо удобно.
    Да,экран отдельно, в страницах
    Последний раз редактировалось Hacker VBI; 30.05.2014 в 23:32.

  8. #7
    Veteran
    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,053
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    47
    Поблагодарили
    31 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Вот что реально помогло бы - это выработать паттерны программирования для написания блочно-ориентированных алгоритмов.

    Эта проблема до сих пор не решена для всех и каждого. По-хорошему, следовало бы преподавать такие паттерны в институтах, чтобы студенты сразу знали, как это делается. А то сейчас, с ростом памяти компьютеров, все обленились и даже при обработке аудио-, видео- и прочих больших файлов норовят загружать весь файл в память, чтобы удобнее было с ним работать.

    А вот я уже давно выработал следующий паттерн для блочной обработки потоков:

    Код:
    #define BUFFER_SIZE 1024
    void process_file_in_blocks(FILE* input_file, long file_size)
    {
        long bytes_remain = file_size;
        int bytes_proc;
        while(bytes_remain)
        {
            if(bytes_remain > BUFFER_SIZE)
                bytes_proc = BUFFER_SIZE;
            else
                bytes_proc = bytes_remain;
            process_block(input_file,bytes_proc);
            bytes_remain -= bytes_proc;
        }
    }
    Выглядит вроде просто, но если у вас такого еще нет - пользуйтесь на здоровье!

  9. #8
    Guru
    Регистрация
    03.01.2006
    Адрес
    Рязань
    Сообщений
    2,935
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    1
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от SfS Посмотреть сообщение
    Для тех спеков, что умеют любую страницу в любое окно - реализация довольно проста.

    Скажем:
    0-3FFF - ПЗУ (может замещаться озу при копировании из страницы в страницу)
    4000 - 7FFF - озу, где расположен менеджер памяти и другие неудаляемые вещи.
    8000 - BFFF - 1я страница программы-библиотеки-оверлея-данных
    С000 - FFFF - 2я страница данных (скажем, экран)
    К сожалению, для полного разделения сегментов 4 окон ATM (и т.п.) мало. Там лучшее решение такое:
    0000-3FFF - керналь системы и стек (непереключаемый для данной задачи)
    4000-7FFF - сегмент кода (переключаемый)
    8000-BFFF - сегмент данных (непереключаемый для данной задачи), там же (или в нулевом окне) подпрограммы far-вызовов
    C000-FFFF - окно работы с большими данными (в т.ч. с экраном) (переключаемое)

    Код может быть расшарен между экземплярами одной задачи.

    То есть даже нет места, чтобы сделать отдельный защищённый от записи непереключаемый сегмент кода для far-вызовов и защищённый от записи керналь (впрочем, можно специальной доработкой перехватывать команды RST и сразу переключать страницы или без керналя вручную делать NMI через порт, как на ZX Evo baseconf).

  10. #9
    Veteran
    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,053
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    47
    Поблагодарили
    31 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Я думаю, что установка фиксированных сегментов кода или данных накладывает неоправданные ограничения на приложения. Все-таки некоторые программы имеют большой код и маленькие данные, или наоборот.

    Из удачных решений архитектуры ОС я могу отметить ASC CP/M. Там все, что можно (в том числе экран), было вынесено за пределы адресного пространства. Это дало 62K TPA, в которых могли размещаться пользовательские программы. В этих же 62k размещалось ядро CP/M (BDOS и CCP), но в CP/M приложениям разрешается затирать и то, и другое. По завершении приложения просто происходит перезагрузка обоих этих компонентов. Приложение, затершее BDOS, не может больше пользоваться функциями BDOS (файловая система), но при этом BIOS остается доступным (низкоуровневый ввод-вывод).

    Если бы разрабатывал ось, я бы вынес ее ядро и экран за пределы адресного пространства приложений. Для доступа к расширенной памяти ввел бы в ядро функции блочного чтения и записи в "невидимое" ОЗУ по виртуальным адресам. Также, возможно, системный ввод-вывод не в адресное пространство приложения, а по виртуальным адресам в расширенную память. Чтобы лишний раз данные не гонять туда-сюда. Доступ к экрану тоже осуществлялся бы через ядро. Хотя это ограничило бы применимость такой оси. Демки и игры на ней делать не имело бы смысла.

  11. #10
    Guru Аватар для jerri
    Регистрация
    01.03.2005
    Адрес
    Samara
    Сообщений
    4,746
    Спасибо Благодарностей отдано 
    256
    Спасибо Благодарностей получено 
    265
    Поблагодарили
    199 сообщений
    Mentioned
    12 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Barmaley_m, а где можно пощупать ASC CP/M?
    С уважением,
    Jerri / Red Triangle.

Страница 1 из 2 12 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

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