информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медЗа кого нас держат?Страшный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Microsoft предупредила о двух незакрытых... 
 Перевод Firefox на DNS over HTTPS 
 Microsoft закрыла серьёзную уязвимость,... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / theory
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Странно как-то получается 15.06.05 05:14  Число просмотров: 2617
Автор: KUV Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Допустим будем переность элемент на M вверх, тогда вдруг приключится так что шапка из верхних M+C элементов перестанет юзаться? На то чтоб удалить эти элементы может потребоваться много времени, а в частном случае они могут совсем там осесть.
К тому же при большом M перенос будет занимать больше времени, и тогда уж лучше использовать метод с вычислением потенциала элементов.
<theory>
Функция приоритета элемента в кэше 08.06.05 15:38  
Автор: KUV Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Имеется кэш фиксированного размера (по макс. кол-ву элементов в нем). Вцелом идея такая - если запрашиваемый элемент есть в кэше то выдается он, иначе приходится грузить его из базы/файла. Проверка его на наличие в кэше делается через обычное дерево поиска.
Предполагается что если объект пришлось грузить из базы он автоматом попадает в кэш, значит при этом какойто элемент придется выкинуть. Но как сделать выбор этого элемента оптимальным с точки зрения суммарного времени работы? Причем выбор этого элемента надо производить тоже быстро, оптимально если это можно будет реализовать в виде очереди с извращениями.
Если просто элементы хранить в очереди и при юзании переносить в начало, а удалять последний элемент, то есть предположение что это будет неоптимально. В случае когда объект юзается много, но неравномерно по времени (скачками) в этом случае он будет после каждого такого скачка удаляться из кэша, а потом грузиться снова при новом скачке...
На самом деле примерно так :-)... 15.06.05 12:22  
Автор: leo <Леонид Юрьев> Статус: Elderman
Отредактировано 15.06.05 14:27  Количество правок: 1
<"чистая" ссылка>
Построить оптимальный кэш невозможно, можно только не совсем плохой. При любой стратегии/тактики кэша можно найти способ, при котором от него не будет толку.

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

---

Далее, при поиске элементов, которые необходимо «выкинуть», правильнее искать оптимум f(x,y) ~= занимаемый_размер / ресуры_для_восстановления. Другими словами учитывать отношение освобождаемой памяти и средств, необходимых для повторной загрузки вытесняемого элемента.

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

---

Как уже говорилось, выбрасывание элементов по случайному закону часто не намного хуже (или вовсе не хуже) многих «навороченных» алгоритмов. Обычно еще одна небольшая эвристика улучшает ситуацию:
- используется генератор случайных чисел с неравномерным распределением. Например, вероятность генерации чисел-индексов увеличивается от минимума до максимума при «движении» от начала очереди (недавно использовавшихся элементов) к концу (старых элементов);
- элемент можно выкидывать не сразу, а когда он «выпал» несколько раз. Можно не выкидывать элементы, которые «жили» в кэше меньше определенного времени. Можно для разных «классов» элементов установить разное количество требуемых выпадений на ГСЧ;
- Можно менять этот порог срабатывания динамически и при желании построить кэш, который будет само-оптимизироваться под задачу на принципах генетических алгоритмов;

---

Неплохие результаты дает использование идей динамического кодирования по Наффману (Huffman) или LZW-сжатия. Каждому элементу (например строке в таблице БД) назначается уникальный ID. Пока элемент находится в кэше, codeword соответствующий его ID в схеме сжатия соответствует его позиции в кэше. Чем больше (длиннее) codeword, тем ближе элемент к концу очереди, и тем более он подходит в кандидаты для «вылета».
Это хорошо дополняется идеей «минимальной» жизни элемента и стохастической чисткой (выбросом по ГСЧ).

Но чтобы ранжирование на основе алгоритмов сжатия работало нормально, нужно использовать HANDLEs. HANDLE в данном случае управляющая структура, соответствующая каждому элементу кэша. Но "хендлов" в несколько раз (как минимум в два раза) больше чем живых элементов кэша. Это позволяет отслеживать обращение к элементам, которые уже были удалены из кэша, и учитывать это в дальнейшем. Другими словами кэш состоит из множества "хендлов", но не более половина из них соответствует присутствующим в ОЗУ элементам, остальные используются только для сбора статистики по кэш-промахам.

---

Если теоретизировать далее, и постараться сделать максимально оптимальный, или само-оптимизирующийся кэш, то нужно строить модель на основе скрытых Марковских процессов.

Можно сделать и попроще:

Вероятность повторного обращения к элементу можно представить как периодическую функцию от времени. Большие периоды (низкие частоты) нас мало интересуют, поэтому можно ограничиться рассмотрениям ограниченного периода. Время дискретизировать до «разов» обращения к данным через кэш.

Если используя «хендлы» собирать достаточно статистики, то можно опроксимировать эту функцию полиномом, или разложить в ряд (Фурье здесь видимо лучше чем Хартли, потому что важно фаза). Можно подумать и над wavelet преобразованием со своей материнской функцией (обратимость вроде-бы не нужна).

Как вариант, можно представить всё в виде Марковского процесса. При этом дополнительной характеристикой каждого состояния будет вероятность повторного обращения к элементу в течение какого-то определенного времени. В идеале это должен быть ряд Фурье/Хартли посчитанный по статистике.

Короче, фантазировать можно очень долго. Но самое главное «правило» в начале поста все равно останется в силе…
Ссылка 14.06.05 16:04  
Автор: whiletrue <Роман> Статус: Elderman
<"чистая" ссылка>
Правда это про виртуальную память в ОС, но очень близко к твоему случаю

http://cs.mipt.ru/docs/courses/osstud/10/ch10.htm
Интересная тема, есть куча мыслей. 11.06.05 16:13  
Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
<"чистая" ссылка>
Я так понимаю, что обсуждение будет затрагивать файловый кэш и как его разновидность кэш информации в базе данных.
Задача правильной работы грамотного кэша заключается в том, чтоб минимизировать случаи непопадания в кеш. То есть, чтоб с бОльшей вероятностью запрашиваемый элемент был удовлетворен из кэша при его объеме, меньше чем область кэшируемых данных. Здесь нужно понять то, что ни одна из стратегий не будет гарантировать абсолютную эффективность его работы при различных методах доступа к данным. В принципе неплохой реализацией было бы внесение нового элемента в кэш тех данных, которые скоро в последствии будут затребованы вновь, причем количество обращений к ним будет больше, чем к самому редко использующемуся элементу. При этом из кэша удаляется тот элемент, который в последствии будет наименее востребован. В предположении того, что сложно заранее определить какие данные в последствии будут наиболее часто запрошены и какие элементы кэша будут наиболее редко использоваться, сформулировать самый оптимальный алгоритм кэширования невозможно, но можно придумать что-то наиболее приемлемое.
Глядя на настройки работы файлового кэша в сетевой операционной системе Новэль, мне представился очень интересный алгоритм, который, вероятно, там реализован. Суть его в следующем: Каждому элементу таблицы кэша отводится структура данных, главным элементом в ней является признак активности использования этого элемента. Это значение увеличивается по мере удовлетворения запроса к данным из этого элемента кэша. Периодически происходит процесс уменьшения признаков активности использования для всех элементов. При доступе к очередным данным, при условии что они не были найдены в кэше, ищется элемент с наименьшим признаком активности. Если это значение ниже порогового, то он заменяется новыми данными и ему выставляется начальное, отличное от нуля, но небольшое значение признак активности. Таким образом наиболее долго будут находиться в кэше данные, к которым было наибольшее число обращений, поскольку на очередную востребованность у них вероятность будет наиболее высока – раз уж к ним так часто обращались, то вероятно еще много раз обратятся. Однако даже и они все равно когда-нибудь удалятся из кэша, если к ним долгое время не будет обращений. Данные же, которые очень мало были востребованы, просуществуют в кэше совсем небольшое время.
В этом методе может быть очень много параметров, которыми можно адаптировать кэш к конкретной задаче. Например начальное значение активности может быть выше всего двух – трех наименьших элементов, чтоб дать возможность этой области данных «доказать» свое право присутствия в кэше. Метод периодического понижения активности может быть как логарифмический, так и экспоненциальный. То есть в зависимости от значения признака активности он будет быстрее или медленнее уменьшаться. А так же предельное его значение и скорость роста в зависимости от значения, периодичность уменьшения значений признаков. Причем эти параметры можно изменять динамически. То есть кэш будет подстраиваться под данный метод обращения к данным.
Предположим, что в процессе работы было очень много обращений к небольшой области данных так, что она «осела» в кэши. Потом произошло последовательное обращение к большому объему данных. При этом будут (или даже не будут) обновляться только два- три элемента кэша, а относительный приоритет других элементов останется высоким, хотя абсолютные значения признаков уменьшатся.
При начальном последовательном обращении элементы будут заполнены первыми запрошенными данными и в процессе последовательного обращения будут (или не будут в зависимости от начального значения признака) заменяться очередными данными.
Можно отдельно вести небольшую таблицу статистики обращений без кэширования самих данных с тем, чтоб уже в кэш попадали «достойные того кандидаты».
Естественно, можно придумать такой метод обращения к данным, при котором этот алгоритм будет проигрывать другим по эффективности.

Если это нужно для курсовой/дипломной работы, то далее можно не читать, а с посетителями форума хотелось бы, пользуясь случаем, обсудить смысл собственной реализации кэширования.
Я лично считаю, что не только не стоит заниматься кэшированием, но и в буфферизации совершенно нет никакого смысла.
А именно, для обработки большого файла данных можно каждый раз лазить в файл, поскольку реализация кэширования в операционке заведомо лучше, чем реализуешь сам. Что нужно и так будет удовлетворено без обращения к накопителю. Единственный минус – накладные расходы на обращение к системе.
Можно поступить наоборот, сразу прочитать в оперативку весь файл и делать с ним что хочешь. Если оперативки не хватает, то операционка сама воспользуется накопителем для свопа и, причем, наилучшим образом, а сама програмка будет проще, меньше и быстрее написана. Хочется повысить быстродействие при увеличившемся объеме данных – просто добавь модуль оперативной памяти, скорость работы будет расти то тех пор, пока оперативки не будет достаточно.
А вот мои мысли 11.06.05 23:49  
Автор: KUV Статус: Незарегистрированный пользователь
Отредактировано 11.06.05 23:53  Количество правок: 1
<"чистая" ссылка>
Во-первых это нужно не для курсовой работы а для программы, которую можно даже будет обозвать "разработкой"=)

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

Что касается предложенного варианта кэширования - меня терзают сомнения относительно его эффективности, особенно при большом кэше. Если у нас кэш размером N элементов, то процесс уменьшения показателей будет занимать O(N), а это может быть существенно (еще надо учитывать что будут выполняться действия типа взятия логарифмов). Я предложу другой вариант, более быстрый в этом плане.
Сами элементы хранятся в бинарном дереве, так что искать/удалять элемент мы можем за O(logN). Также создадим очередь из элементов кэша, с ней операции будут занимать O(1). При обращении к элементу будем делать следующее:
1) если элемент найден в кэше, то переносим его в голову очереди
2) если элемент не найден, то удаляем элемент из хвоста очереди, грузим запрошенный и помещаем его в голову очереди

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

Жду критики...=)
Касаемо очереди и бинарного дерева. 14.06.05 10:58  
Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
<"чистая" ссылка>
Касаемо очереди и бинарного дерева.

> Сами элементы хранятся в бинарном дереве, так что
> искать/удалять элемент мы можем за O(logN). Также создадим
> очередь из элементов кэша, с ней операции будут занимать
> O(1). При обращении к элементу будем делать следующее:
> 1) если элемент найден в кэше, то переносим его в голову
> очереди

Сразу в голову? Может просто продвируть по очереди на несколько элементов?

> 2) если элемент не найден, то удаляем элемент из хвоста
> очереди, грузим запрошенный и помещаем его в голову очереди

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

> Т.е. я думаю чем больше нагрузка на всю систему, тем более
> адекватно кэш должен выбирать элементы для хранения. Имхо
> это неплохо.

Теоретически N больше, чем logN, но при разумнонебольшом количестве элементов в кэше, время, затрачиваемое на поиск, будет слишком мало по сравнению с самой обработкой данных.
Продвижение по очереди будет соизмеримо с десятком - сотней просмотров целочисленных элементов массива.

> Жду критики...=)

Это не критика, а плюрализм.
Странно как-то получается 15.06.05 05:14  
Автор: KUV Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Допустим будем переность элемент на M вверх, тогда вдруг приключится так что шапка из верхних M+C элементов перестанет юзаться? На то чтоб удалить эти элементы может потребоваться много времени, а в частном случае они могут совсем там осесть.
К тому же при большом M перенос будет занимать больше времени, и тогда уж лучше использовать метод с вычислением потенциала элементов.
Вероятность есть, но любой элемент "доползет" до самого... 15.06.05 09:29  
Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
<"чистая" ссылка>
> Допустим будем переность элемент на M вверх, тогда вдруг
> приключится так что шапка из верхних M+C элементов
> перестанет юзаться? На то чтоб удалить эти элементы может
> потребоваться много времени, а в частном случае они могут
> совсем там осесть.

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

> К тому же при большом M перенос будет занимать больше
> времени, и тогда уж лучше использовать метод с вычислением
> потенциала элементов.

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

Интересно как работает кэш проца, поскольку в нем многие хитрости не реализовать (нецелесообразно)? Да и поиск в нем осуществляется всего за один такт.
Файловый кеш ОС позволит достичь того же, просто немного... 13.06.05 14:16  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Благодяры кэшу я хочу достигнуть
> такого эффекта - в памяти хранятся только те элементы
> которые сейчас используются, это должно очень сильно
> ускорить всю программу.

Файловый кеш ОС позволит достичь того же, просто немного переформулированного результата: в памяти хранятся только те СТРАНИЦЫ, под которыми находятся элементы, которые сейчас используются

> Что касается предложенного варианта кэширования - меня
> терзают сомнения относительно его эффективности, особенно
> при большом кэше. Если у нас кэш размером N элементов, то
> процесс уменьшения показателей будет занимать O(N), а это

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

> может быть существенно (еще надо учитывать что будут
> выполняться действия типа взятия логарифмов). Я предложу

Никакого взятия логарифмов. Все что можно затолкать в таблицы - нужно туда затолкать. ПРИМЕРНОЕ (а другое нам и не нужно) вычисление логарифма можно выполнить за несколько тактов.

> другой вариант, более быстрый в этом плане.
> Сами элементы хранятся в бинарном дереве, так что
> искать/удалять элемент мы можем за O(logN). Также создадим
> очередь из элементов кэша, с ней операции будут занимать
> O(1). При обращении к элементу будем делать следующее:
> 1) если элемент найден в кэше, то переносим его в голову
> очереди
> 2) если элемент не найден, то удаляем элемент из хвоста
> очереди, грузим запрошенный и помещаем его в голову очереди
>
> Единственный минус этого способа - если элемент запрошен
> много раз, а потом забыт, то он вылетит из очереди очень
> быстро. Но при равномерном обращении наиболее
> востребованные элементы будут находиться ближе к голове
> очереди.

Этот вариант ты уже описал в корневом посте. Если говорить об эффективности, то метод с увеличением и уменьшением количества обращений универсальнее и будет давать нормальные результаты в бОльшем числе случаев. Метод с самосортирующимся списком проще и довольно эффективен для большинства РЕАЛЬНЫХ случаев.

> Т.е. я думаю чем больше нагрузка на всю систему, тем более
> адекватно кэш должен выбирать элементы для хранения. Имхо
> это неплохо.

Адекватным является как раз выбор не только по тому, как давно элемент был в последний раз затребован, но и по тому, насколько часто вообще этот элемент был нужен.
Статью с оценкой разных методов не подскажите?... 13.06.05 16:20  
Автор: KUV Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Не подскажу. Я "на глаз" говорил 13.06.05 17:42  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
А не "на глаз" нужно, как уже посоветовали, проводить анализировать динамику обращений к базе в рабочем режиме.
Это "в идеале", и к тому же этот метод выбора наилучшей... 14.06.05 11:13  
Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
<"чистая" ссылка>
> А не "на глаз" нужно, как уже посоветовали, проводить
> анализировать динамику обращений к базе в рабочем режиме.

Это "в идеале", и к тому же этот метод выбора наилучшей стратегии будет наилучшим образом применим только к тестовой задаче выборки данных.
Это, конечно, хорошо, если метод выборки данных постоянен, не меняется со временем и заранее известен.
К тому же, сглашусь, что любая стратегия кэширования повысит быстродействие на порядок и бороться за дополнительные проценты уже не имеет смысла.
Можно и просто смаппировать файл в память, насколько я помню... 11.06.05 18:26  
Автор: ony Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> Я лично считаю, что не только не стоит заниматься
> кэшированием, но и в буфферизации совершенно нет никакого
> смысла.
> А именно, для обработки большого файла данных можно каждый
> раз лазить в файл, поскольку реализация кэширования в
> операционке заведомо лучше, чем реализуешь сам. Что нужно и
> так будет удовлетворено без обращения к накопителю.
> Единственный минус – накладные расходы на обращение к
> системе.
> Можно поступить наоборот, сразу прочитать в оперативку весь
> файл и делать с ним что хочешь. Если оперативки не хватает,
> то операционка сама воспользуется накопителем для свопа и,
> причем, наилучшим образом, а сама програмка будет проще,
> меньше и быстрее написана. Хочется повысить быстродействие
> при увеличившемся объеме данных – просто добавь модуль
> оперативной памяти, скорость работы будет расти то тех пор,
> пока оперативки не будет достаточно.
Можно и просто смаппировать файл в память, насколько я помню сейчас и в винде такое есть.
А вот насчет того что система лучше скэширует - недумаю.
Тебе лучше знать специфику данных и вид обращения к ним, а система будет глупо работать как с огромным массивом, что заведомо теряет очень многое, что могло бы с оптимизировать кэш.
Пример: система со страничной организаций VM, ты обращаешся к записи которая могла бы вместится на одной странице, но так вышло, что граница страниц перерезает ее пополам и когда ты обращаешся к ней, то в памяти держится гараздо больше мусора, чем если бы запись была выровнена на границу страницы (BerkleyDB следит за этим внимательно).
Касательно баз данных - тоже самое. Ситуация с паралельными апдэйтами тяжело переносится. Например у тебя подсчет траффика по хостерам, каждый запрос к вебу добавляет еще чиселку к одной сумме по определенному домену (апач к примеру, работая несколькими процессами, может привести к паралельным апдэйтам. А вот если подставить прослойку между базой и событиями, которая будет аккумулировать данные и через время сливать в базу, то производительность такой системы возрастет заметно.
С одной стороны все верно, с другой стороны есть чему... 11.06.05 18:52  
Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
<"чистая" ссылка>
С одной стороны все верно, с другой стороны есть чему возразить.

> Можно и просто смаппировать файл в память, насколько я
> помню сейчас и в винде такое есть.

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

> А вот насчет того что система лучше скэширует - недумаю.

Реализацию кэша в ОС писали далеко не дураки и потратили они на это уйму времени не даром. Это можно принимать только на веру. К тому же не надо тратить время на написание кода, программа будет "легче", не будет лишних ошибок, не к чему дублировать код ради мнимого выигрыша в производительности.

> Тебе лучше знать специфику данных и вид обращения к ним, а
> система будет глупо работать как с огромным массивом, что
> заведомо теряет очень многое, что могло бы с оптимизировать
> кэш.

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

> Пример: система со страничной организаций VM, ты обращаешся
> к записи которая могла бы вместится на одной странице, но
> так вышло, что граница страниц перерезает ее пополам и
> когда ты обращаешся к ней, то в памяти держится гараздо
> больше мусора, чем если бы запись была выровнена на границу
> страницы (BerkleyDB следит за этим внимательно).
> Касательно баз данных - тоже самое. Ситуация с паралельными
> апдэйтами тяжело переносится. Например у тебя подсчет
> траффика по хостерам, каждый запрос к вебу добавляет еще
> чиселку к одной сумме по определенному домену (апач к
> примеру, работая несколькими процессами, может привести к
> паралельным апдэйтам. А вот если подставить прослойку между
> базой и событиями, которая будет аккумулировать данные и
> через время сливать в базу, то производительность такой
> системы возрастет заметно.

Это и есть кэш ОС.
Можно попытаться победить несколькими способами... 08.06.05 17:17  
Автор: HandleX <Александр Майборода> Статус: The Elderman
Отредактировано 08.06.05 17:22  Количество правок: 3
<"чистая" ссылка>
Возьмём, к примеру реализацию виртуальной памяти в современных осях.

В *BSD-системах отцы-разработчики решили неопределённость побить другой неопределённостью — выкидывается случайный элемент, используя какой-нить простенький ГПСЧ.

В виндах другой подход — ведётся счётчик MRU для каждого элемента, и по-возможности выкидывается элемент, который «засиделся» в кэше слишком долго без обращений к нему... Но тут меня гнетут смутные сомнения, что если слишком долго, то есть вероятность, что скоро его используют ;-)

А вообще, надо постараться всё-таки проанализировать динамику обращений к вашей базе, и постараться сделать наиболее эффективный вариант работы кэша. Когда полный хаос -- то метод №1. Когда есть последовательные выборки, то метод №2. А может даже делать предвыборки... И прочая, и прочая...
Хорошей практикой будет потом погонять на реальных задачах все мыслимые методы, и выбрать оптимальный.

Успехов.
Кажись виндовый подход лучше 10.06.05 02:11  
Автор: whiletrue <Роман> Статус: Elderman
Отредактировано 10.06.05 02:15  Количество правок: 1
<"чистая" ссылка>
> Возьмём, к примеру реализацию виртуальной памяти в
> современных осях.
>
> В *BSD-системах отцы-разработчики решили неопределённость
> побить другой неопределённостью — выкидывается случайный
> элемент, используя какой-нить простенький ГПСЧ.

Не понятно, чем это лучше выкидывания FIFO? "Нужный" элемент будетгарантированносидеть в кэше время N, а если случайно выкидывать - то его выкинут с вероятностью 1/N. А сохранить "нужный" элемент важнее выкидывания ненужных, наподобие этого:

На уроке в 5-ом классе учительница проводит урок "анти-боже", и на последних минутах говорит:
-В знак того, что бога нет давайте покажем ему дулю.
И весь касс показавыет дулю, а Мойша, сидя на задней парте, ничего не показывает.
Учительница спрашивает Мойшу:
-Мойша. а ты почему ничего не показываешь.
-А зачем богу нужна моя дуля, если его всё равно нет, а если он есть, то зачем мне с ним ссориться.

(типа, если и так нет определенности - давайте покажем ей дулю в виде другой непределенности - Зачем?)

> В виндах другой подход — ведётся счётчик MRU для каждого
> элемента, и по-возможности выкидывается элемент, который
> «засиделся» в кэше слишком долго без обращений к нему... Но
> тут меня гнетут смутные сомнения, что если слишком долго,
> то есть вероятность, что скоро его используют ;-)

Это, вроде как, принцип локальности:

Свойство локальности присуще природе. Пространственная локальность - соседние объекты характеризуются похожими свойствами (если в данной местности хорошая погода, то вероятнее всего, что в близкой окрестности также хорошая погода). Временная локальность - если в 15:00 была хорошая погода, то, вероятно, что и в 14:30 и в 15:30 также наблюдалась хорошая погода. Свойство локальности (скорее эмпирическое) присуще и работе ОС. Фактически свойство локальности объяснимо, если учесть, как пишутся программы и организованы данные, то есть обычно в течение какого-то отрезка времени ограниченный фрагмент кода работает с ограниченным набором данных.
Политика кэширования — тема ещё та... 10.06.05 12:06  
Автор: HandleX <Александр Майборода> Статус: The Elderman
Отредактировано 10.06.05 12:11  Количество правок: 2
<"чистая" ссылка>
> На уроке в 5-ом классе учительница проводит урок
> "анти-боже", и на последних минутах говорит:
> -В знак того, что бога нет давайте покажем ему дулю.
> И весь касс показавыет дулю, а Мойша, сидя на задней парте,
> ничего не показывает.
> Учительница спрашивает Мойшу:
> -Мойша. а ты почему ничего не показываешь.
> -А зачем богу нужна моя дуля, если его всё равно нет, а
> если он есть, то зачем мне с ним ссориться.
Хорошая байка, надо запомнить... ;-)

> Свойство локальности присуще природе. Пространственная
> локальность - соседние объекты характеризуются похожими
> свойствами (если в данной местности хорошая погода, то
> вероятнее всего, что в близкой окрестности также хорошая
> погода). Временная локальность - если в 15:00 была хорошая
> погода, то, вероятно, что и в 14:30 и в 15:30 также
> наблюдалась хорошая погода. Свойство локальности (скорее
> эмпирическое) присуще и работе ОС. Фактически свойство
> локальности объяснимо, если учесть, как пишутся программы и
> организованы данные, то есть обычно в течение какого-то
> отрезка времени ограниченный фрагмент кода работает с
> ограниченным набором данных.
На сервере работает 1000 пользователей... Свойство локальности себя будет проявлять очень слабо. Также на нагруженных файл-серверах не рекомендуют делать дефрагментацию файлов, ибо эффект чисто эстетический.
Присоединяюсь к предыдущему автору - проанализировать... 09.06.05 20:48  
Автор: Searcher Статус: Незарегистрированный пользователь
Отредактировано 09.06.05 21:09  Количество правок: 2
<"чистая" ссылка>
Присоединяюсь к предыдущему автору - проанализировать (построить модель работы базы) и попробовать разные варианты.
Для анализа можно попробовать записать работу базы за некоторый промежуток времени (минуту, час день), например,
"Взят элемент 1 из кеша,
Взят элемент 143343 из файла,
взят элемент 5 из файла,
Взят элемент 143343 из кеша,
..." и т.д.
Или короче
"1к 143343ф 5ф 144343к" будет видна эффективность кеша
Приняв чтение из кеша за х попугаев (лучше замерит), из файла за у попугаев анализируя поток получаем время. Меням алгоритм и имитируем тот-же поток. Пересчитываем время и т.д.
Минус подхода - жесткая привязка к выборке (назавтра поток может быть совсем другим), плюс - "повторяемость" (при проверке одного алгоритма 100 запросов, при проверке другого 10000, а так им предоставляются "абсолютно" одинаковые условия). Чем более "характерная" запись получится тем лучше результат.

Как один из вариантов организации кеша могу предложить кеш второго уровня куда таки попадают элементы, вылетая из первого, но остаются там, если счетчик их использования на хорошем уровне.
Также новый элемент можно добавлять не в конец очереди, а в ее середину, чтобы не дать ему шанс сразу же оттуда вылететь.
Счетчик использований элемента имеет смысл, т.к. тогда будет сразу видна эффективность нахождения данного элемента в кэше (чем больше чтений из кеша - тем больше выигрыш).
Можно также вести счетчик использований самого кеша, чтобы его значение, уменьшенное в дцать раз, использовать как "порог эффективности" - если у элемента счетчик использования меньше порога - он кандидат на удаление. Вновь добавляемому элементу присваивается значение порога (эквивалент помещения в середину очереди = дает шанс задержаться элементу). Такое увеличение порога выкинет элементы, которые некоторое время использовались довольно интенсивно, а затем перестали использоваться. В то же время для элемента, который выкидывается из кеша, разница между его текущим значением счетчика, и значением счетчика при добавлении (просили навороты ? :) ) покажет время нахождения элемента в кеше и покажет его шансы на попадание во второй кеш.
1






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2020 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach