От Mario79.
Описание работы системы кэширования для жестких дисков и частично затронута работа кода DMA в части связанной с кэшированием. Описание не затрагивает код файловых систем, так как в этом случае это не существенно.
Что было в Менуэт:
1.Одновременная работа только с одним разделом жесткого диска. Ни о каком копировании файла с раздела на раздел без дополнительных телодвижений со стороны пользователя не могло быть и речи. 2.Один единственный буфер кэширования на 1 Мб. При переключении на другой раздел жесткого диска (даже одного физического диска) происходило полное очищение кэша. 3.Исключительно PIO режим работы с жестким диском. 4.Буфер при записи на жесткий диск скидывается по 1 сектору.
Вывод скорость работы дисковой подсистемы существенно низкая, удобство использование на любителя, но если честно смотреть то весьма сомнительное удобство.
Как это прирастало в Колибри.
1.Изначально дисковая система была идентична Менует.
2.Поскольку было большое желание работать хотя бы с двумя разделами, а лучше со всеми без дополнительных телодвижений была введена модернизация имен жестких дисков, позволившая обращаться к более чем одному жесткого диска без дополнительных телодвижений с программой SETUP. В процессе экспериментов было выявлено, что определение параметров раздела при каждом обращении к дисковой подсистеме тормозит скорость работы. По этой причине эта часть кода была вынесена в отдельную процедуру которая вызывается при загрузке системы и определяет все наличествующие разделы на жестком диске, а затем сохраняет их в специальном буфере (просмотреть его можно функцией 18.11). Из этого буфера во время работы эти данные извлекаются и используются по мере обращения к определенным разделам.
3.Было внедрено использование режимов DMA и UltraDMA (максимального который установил BIOS при загрузке компьютера). 3.1 В ходе разработке кода выяснилось, что чтение по 1 сектору как и запись скашивают весь прирост скорости в DMA режиме. По этой причине с целью минимизации изменения существующего кода был введен предбуфер чтения DMA на 16 секторов жесткого диска (каждый физический сектор 512 байт). При запросе 1 сектора производится считывание не только 1 сектора а еще 15 последующих, поскольку считывание производится за один запрос к физическому устройству, то никаких дополнительных задержек это не вызывает. Поскольку обращения к жесткому диск по большей части последовательное (разумеется мы не рассматриваем очень сильную фрагментацию данных, это повод для запуска дефрагментатора), то прирост скорости по сравнению с посекторным считыванием колоссален. Если в предкэше нужного сектора не окажется то производится его считывание вместе с последующими 15, т. е. Кэш полностью обновляется. С одной стороны максимальный «штраф» может быть в 15 секторов, но в ходе поставленных опытов выяснилось что 16 секторов это оптимальная величина, считывание 32 сектора было медленней и «штраф» тоже был больше, с другой стороны при считывании 8 секторов наблюдался резкий провал производительности, который выравнивался только к 4, то это уже было заметное снижение производительности. По этим причинам 16 стало опорным значением. 3.2 Для ускорения записи был применен несколько иной подход. Поскольку кэшу же был и совершать дополнительные телодвижения задействуя процессор для сортировки нужной последовательности секторов, чтобы слить их единым блоком не лучший выход. По этой причине есть две процедуры записи для DMA — одна записывает по одному сектору, другая от 2 до 64 секторов за раз. Поскольку в кэше данные могут располагаться как последовательно так и вразнобой, то соответственно алгоритм кода если не находит последовательных секторов общим числом больше 1, т.е. 2 и более вплоть до 64, записывает по одному сектору. Как только найдено два последовательных сектора начинается подсчет последовательных секторов вплоть до 64 секторов. Когда последовательность оборвется или достигнет 64 — этот кусок сбрасывается за один заход DMA на жесткий диск. Затем процедуры повторяются вплоть до того как весь кэш (те из его секторов которые помечены для записи) не будет записан по месту назначения. Такой подход позволил поднять скорость записи без дополнительных затрат для центрального процессора.
4.Поскольку буфер был один на все устройства и разделы, то сначала возникла идея доработать код чтобы он не очищался если чтение или запись производятся на разные разделы одного физического устройства. Это было реализовано и некоторое время система функционировала в таком виде. Однако провал в скорости при копировании на разные физические устройства был очень сильным. По этой причине было введена система независимых кэшей — каждому физическому устройству по кэшу. Первоначально их было максимум 4 потом стало больше но об этом позже. Изначально планировалось динамическое выделение памяти при старте системы, но в ходе экспериментов выяснилось что при размере кэша боле 1 Мб перебор всех секторов в таком кэше занимает много времени и замедляет скорость доступа к жесткому диску. Проблему решил бы алгоритм «хеширования», но по некоторым (неважным в контексте этой статьи) причинам он так и не был реализован. По этому размер кэша был ограничен 1 Мб — это максимальное значение, минимальное значение каждого кэша это 128 Кб. Минимальное значение взято приблизительно и исключительно для работы на старых компьютерах с недостаточным количеством оперативной памяти (16, 12, 8 Мб). Разумеется при уменьшении размера буфера скорость работы с файловой подсистемой падает ,но это меньшее зло чем совсем не работать с ней. Дополнительная мера для повышения скорости работы — это сделать так чтобы служебные данные раздела и данные директорий - которые бывают нужны часто, а обновляются редко не выбивались из кэша новыми данными. Для этого планировалось разделить кэш на две неравны части — одну меньшую часть для служебных данных, другую большую часть для данных считываемых файлов. Также по некоторым причинам это было реализовано лишь для ATAPI устройств, поскольку для них требовалось только читающая часть кода, то написание кода было немного проще. После внедрения этого механизма — MP3 плеер перестал заикаться при непосредственном проигрывании CD и DVD дисков (раньше заикался потому что у него нету собственного кэша для файла, а сейчас система обеспечивает своевременную подачу порции данных), хотя ATAPI устройства до сих пор работают в PIO режиме. Реализация пакетного DMA режима для ATAPI устройств более сложная задача чем реализация DMA для жестких дисков. В ходе экспериментов с кэшами также выяснилось, что код работы с кэшем внедренный в Менуэт ,который лежал в основе системы кэширования содержал фатальную ошибку, из-за которой первые реализации кода в DMA режиме вызывали порчу данных на жестком диске. Область данных кэша содержавших указатели номеров содержащихся секторов была на 1 единицу больше чем сам размер кэша, пока кэш был стабилен по местоположению видимо затирались не особо важные данные, а когда он стал динамическим это вылезло большими проблемами. Впоследствии ситуация была разрешена и баг «как бы» сам исчез с внедрением отдельных кэшей для каждого физического устройства.
5.Система доступа через PIO режим по прежнему осталась посеторной, ее вышеописанное с DMA в плане ускорения работы не коснулось. В принципе можно доработать код аналогично DMA — для ATA контроллеров есть команды поддерживающие считывание за один запрос более 1 сектора, но судя по сравнению с работой Виндовс прирост по скорости будет максимум 10-30% и то только при последовательном чтении большого объема данных. Относительно этого делаем вывод что «овчинка выделки не стоит» потому что режимом PIO пользуются только в исключительных случаях, когда DMA режим не работает, а объем изменяемого кода весьма существенен.
6.В дальнейшая доработка производилась Diamond'ом. Была она связана с добавлением дополнительных буферов для видимых из БИОС, но не видимых пока в самой Колибри устройств. Для тех дисков которые уже обнаружены самой ОС кэш не дублируется, а используется совместно при обащении к HD и BD дискам. Подробнее думаю он сам может рассказать.
Возможность применения SATA и вообще новых дисков на сегодня ограничена 2 факторми:
1.Прерывания построены на старой модели, где их максимум 15 штук (1 используется для каскадирования, хотя реально никакого каскадирования нету, но это сделано для совместимости со старым железом). Новые контроллеры SATA любят садится на прерывания выше 20-го, либо не садятся вообще, а это PIO режим.
2.Отсутствует поддержка LBA48 - а это большой объем переделки кода. В принципе можно обойтись поддержкой 32-х битной адресации, но с современной скоростью развития жестких через 1-2 года это опять упрется в трубу. Дело в коде который в Колибри жестко завязан на максимум 32 бита, расширение до 64-х бит кода работы с ФС потребует большой переделки, по сути написать с нуля по крайней мере на 50-70% кода.
P.S. by Ghost продублировал в "Ядро - концепция работы"
|