Saturday, September 28, 2013

Файлы не нужны

Файлы не нужны.

(По крайней мере на несменных носителях).

Сколько себя помню, в компьютерах были файлы.
Мы храним в файлах всё — документы, программы, настройки, временные данные...

Что есть файл?
  • Массив байт.
  • Имя, по которому его можно найти и открыть.
  • Атрибуты доступа, чтобы его не открыл/не изменил кто попало.
  • Средства совместного доступа (или ограничения одновременного доступа).

Чего в файле нет?
  • Нет внутренней структуры. Файл — массив (последовательность) байт, чья интерпретация — полностью на совести открывшей его программы.
  • Нет строго заданного типа. Программы должны догадываться о типе данных по окончанию имени или по первым байтам данных.
  • Нет гарантии целостности. Любая программа может неправильно прочитать обработать и записать любой файл. Поэтому открыв собственный только что записанный файл, программа должна быть готова увидеть там мусор.
  • Нет высокоуроневого интерфейса к данным в файле. Например, если файл содержит презентацию, в нем нет доступа к слайдам и элементам оформления — только байты и байты.
  • Структуры файла неудобны для прямого обращения со стороны процессора. В худшем случае файл доступен приложению как байтовый поток, в лучшем — кусок файла маппится на адресное пространство, причем его редко удается маппить на одни и те же адреса. Да и форматы файла редко совпадают с режимами выравнивания, разрядностью, порядком байт и структурами данных целевой машины. Поэтому всякий раз при открытии файла, его содержимое должно конвертироваться во внутреннее представление, а при записи — конвертироваться обратно.

Файлы можно заменить объектами, которые хранятся в персистентной памяти.



Представьте себе компьютер, в котором нет отдельной «оперативной памяти» и отдельных «дисков».
  • В единственном общем большом адресном пространстве постоянно «загружены» все «приложения» и все «документы», которые есть на компьютере.
  • Приложения — это в сущности сегменты машинного кода, которые передают друг другу управление jump/call инструкциями.
  • Документы — это объекты, ссылающиеся друг на друга указателями.
  • Документы хранят указатели на машинный код, а машинный код оперирует указателями на документы.
  • Документы могут храниться в других документах.
  • Могут существовать такие виды документов как «папки», «органайзеры», «wiki-сайты», хранящие разнородные документы и позволяющие делать навигацию среди них на манер системы каталогов.
  • Приложения не работают изолированно. Каждое приложение становится плагином, добавляющим в систему новые типы документов и новые действия над документами.
Операционная система будет иметь оболочку, которая показывает:
  1. текущий документ и
  2. элементы навигации
    1. по последним посещенным документам,
    2. по закладкам
    3. поиск документа по параметра
    4. переход к корневому документу комьютера
  3. Элементы управления, позволяющие редактировать текущий открытый документ.
  4. Панельки для уведомлений.
Сегодня работая с компьютером человек выполняет множество действий с файлами:
  1. находит в проводнике файл с программой (или выбирает в меню ссылку на программу, что равносильно),
  2. в интерфейсе программы выбирает команду открытия файла,
  3. в открывающемся окне проводника выбирает файл с документом (или создает новый),
  4. редактирует документ,
  5. в процессе работы регулярно сохраняет документ в файл,
  6. Закрывает приложение или переключается на другое приложение.
Изо всех этих действий действительно полезными являются только пункты 3 — выбор документа для работы и 4 — полезная работа. Все остальное — оверхед, создаваемый файлами.

Как тот же человек мог бы работать с компьютером если бы вместо файлов были объекты в персистентной памяти:
  1. В системной оболочке выбирается и открывается документ.
  1. Оболочка показывает открытый документ и элементы управления для его редактирования.

Как реализовать эту классную идею

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

В каждом современном процессоре есть MMU.
  • Создаем виртуальную память размером с объем всех несменных носителей (HDD/SSD).
  • Делаем, чтобы линейный адрес в этой памяти жестко маппился на конкретный сектор конкретного винчестера.
  • Берем всю оперативную память и используем ее для кеширования обращений к этому адресному пространству.
  • Перед выключением питания такую память придется «запарковать» - сбросить все измененные страницы на диск. 

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

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

По-простому принцип транзактной виртуальной памяти можно описать так:
Каждой странице адресного пространства соответствуют два сектора на диске.
  • Один из них содержит данные до начала транзакции,
  • А другой используется для сброса из памяти изменений, которые накапливаются до коммита.
В страничных таблицах и каталогах у каждой страницы есть специальное однобитное поле, указывающее, какой из двух секторов содержит актуальные данные. Это поле + битовая карта секторов, измененных данной транзакцией, - все, что нужно для работы алгоритма.

При первом обращении к странице (определяется по биту в битовой карте) ее данные читаются из сектора, относящегося к предыдущей транзакции. При сбросе страницы на диск — данные записываются в сектор текущей транзакции.
Последующие обращения к странице извлекают данные из сектора текущей транзакции.

Коммит транзакции — это:
  1. сброс на диск находящихся в оперативной памяти измененных страниц.
  2. очистка битовой карты
  3. запись на диск корневого страничного каталога.
Естественно могут существовать и другие способы обеспечения целостности памяти.
Введение большей ассоциативности может кардинально снизить оверхед по дисковой памяти (за счет более частых приостановок на коммит транзкции.

Следующий большой вопрос — как распределять эту память.
Тут возможно множество вариантов.
Нужен алгоритм распределения хипа:
  • рассчитанный на мелкие объекты фиксированного размера,
  • рассчитанный на большое количество аллокаций,
  • рассчитанный на огромное адресное пространство,
  • обеспечивающий локальность структур данных (было бы глупо при аллокации или освобождении памяти изменять байты в десятках мест по всему адресному пространству)
Такие алгоритмы есть, достаточно выбрать подходящий.

И естественно, программы, исполняющиеся в таком окружении, должны писаться на управляемом языке с жестким контролем типов и запретом unsafe.

Также естественно, что в такой памяти, где большая часть адресного пространства вытеснена на медленные дисковые устройства, использовать сборщик мусора — чистое безумие.
Управление временем жизни объектов и ссылочной целостностью должны другие мезанизмы. Например master-weak-shared ссылки.

Вопрос безопасности:
Могут создаваться «песочницы» для запуска менее доверенных приложений.
  • Пакет устанавливается в песочницу
  • Ему передается интерфейсы с ограниченными возможностями.
  • Снаружи такой пакет выгладит как доверенный код.
  • Внутри него исполняется менее доверенный код.
Могут создаваться домены, ссылки между которыми предаются декорированными, с тем, чтобы декораторы проверяли права доступа.

Язык программирования и механизм управления временем жизни объектов отдельная большая тема, выходящая за пределы этой статьи.

Как обеспечить плавный вход в мейнстрим новой парадигмы работы с компьютером:
  • пишем для BSD/Windows/Linux приложение, которое
  • Маппит в регион адресного пространство по фиксированному адресу файл (дисковое устройство)
  • Создает в этом регионе хип.
  • При первом запуске заполняет этот хип начальными пакетами и выполняет их компиляцию и установку.
  • В каждой операционной системе появится приложение - интегрированная среда:
  • одинаково выглядящая и одинаково работающая,
  • расширяемая плагинами написанными на одно и том же языке,
  • в которой будут единообразно и бесшовно просматриваться и редактироваться документы разных типов:
  • офисные документы
  • издательские системы и мультимедия
  • игры (это тоже документы)
  • CAD
  • и т.д.
  • Со временем эта интегрированная среда обрастет достаточным количеством плагинов, и ее станут ставить в автозапуск при старте ОС.
  • Пройдет еще немного времени и можно будет превратить ее в отдельную операционную систему.

Резюме:

Можно кардинально изменить принцип работы приложений в компьютере:
  • Внутри компьютера нет файлов, а есть объекты,  хранящиеся в персистентной памяти, прямо доступной процессору. Объекты ссылаются друг на друга указателями.
  • Код всех приложений, хранится в той же памяти.
  • Документы не нужно «сохранять» в файлы или «закрывать» после работы.
  • Высокоуровневый прикладной язык позволяет писать прикладные пакеты, описывающие типы документов и методы работы с ними.
  • Внутри компьютера нет отдельных приложений. "Приложение" - это плагин, расширяющий операционную систему. При установки "приложения", оно компилируется в машинный код и размещается в этой общей персистентной памяти.
  • «Приложениям» доступны все интерфейсы других установленных пакетов и все документы, ссылки на которые они могут получить.

    • Система, обеспечивающее этот принцип работы не сложнее, а значительно проще современных операционных систем.
    Программирование приложений в этот системе также значительно проще чем в традиционных системах:
    • не нужно читать и записывать файлы,
    • не нужно поддерживать жизненный цикл приложений
    • упрощается взаимодействие между приложениями — методы объектов чужих приложений ничем не отличаются от собственных.
    Переход на новую систему можно сделать постепенным, реализовав эту ОС вначале как приложение в существующих операционных системах.

    Остаются открытыми вопросы
    • аллокатор
    • менеджемент времени жизни объектов
    • язык
    • безопасность
    Про них — в следующий раз.

    2 comments:

    1. Жаль, что следующего раза не случилось, однако идея отказаться от файлов в пользу персистентных объектов неспешно пилится Дмитрием Завалишиным (dz) c 90х годов. последние пару лет что-то ничего не слышно, но лет 5-8 назад он взялся всерьёз за это, набросал прототип, решил кучу интереснейших вопросов (в том числе он решил(!) проблему с GC) его персистентность с самого начала затачивалась на то, что электричество могут отключить в любой момент. В сети есть куча презентаций, видео докладов, статьи на вики, и конечно же что-то типа FAQ на http://dz.ru/solutions/phantom/

      ReplyDelete
    2. Спасибо, ознакомлюсь.
      Я пилю эту идею с 1992 года: где-то валяется авторское свидетельство на "устройство памяти, сочетающей свойства оперативной и долговременной". кажется от 1995 года.
      Есть ассемблерная реализация гипервизора для 386, есть управляемый язык. Но они мне не нравятся, а переписывать пока времени нет.
      GC там не нужен от слова совсем, я придумал для этого SpbLTM [https://code.google.com/p/spb-ltm/]
      Будет время, опишу все это подробнее.
      Еще раз спасибо за ссылку на единомышленника.

      ReplyDelete