У меня есть приложение, которое включает в себя коллекцию массивов, которые могут быть очень большие (индексы вплоть до максимального значения в int
), но которые ленивых - их содержание рассчитываются «на лету» и до настоящего времени не известны. Массивы также являются неизменяемыми - значение каждого элемента каждого массива является постоянным на протяжении всего срока службы программы. Массивы в том смысле, что часто лишь небольшое подмножество всех элементов массива либо запрошенной редких (массивы не содержат большие блоки нулей и не «разреженные» в этом смысле.)поточно-кэш для разреженных, ленивых, неизменных массивов
Подняв (и, возможно, вычисления в процессе) элемент массива может быть дорогостоящим, поэтому я хочу добавить слой кэширования. Кэш должен реализовать следующий интерфейс:
void point_cache_store (gpointer data, gsize idx, gdouble value);
gdouble point_cache_fetch (gpointer data, gsize idx);
где data
служит уникальной ручкой для каждого массива (там может быть много из них). point_cache_fetch()
должен вернуть value
аргумент, передаваемый point_cache_store()
с теми же data
и idx
аргументами, или указать промах кэша, возвращая особое значение DATUM_UNKNOWN_VALUE
(абонент никогда не будет называть point_cache_store
с DATUM_UNKNOWN_VALUE
).
Вопрос: Как я могу использовать point_cache_fetch()
и point_cache_store()
? (Они в настоящее время нет-оп окурки.)
Вопросы для рассмотрения:
- Реализация кэш должен быть потокобезопасным. Несколько потоков запускаются одновременно, и любой из них может вызывать
point_cache_store()
илиpoint_cache_fetch()
с любыми аргументамиdata
илиidx
. - Кэш действительно является кешем; это всегда нормально для
point_cache_fetch()
, чтобы вернутьDATUM_UNKNOWN_VALUE
, даже если он когда-то знал это значение. В этом случае вызывающий абонент просто выполнит обычный поиск. - Помните, что массивы неизменяемы - для заданных аргументов
data
иidx
вызывающий абонент всегда будет предоставлять тот же аргументvalue
.
Я понимаю, что есть много способов сделать это и что есть компромиссы. Однако для этого вопроса я буду оценивать ответы по одному очень конкретному критерию: улучшат ли производительность в одном конкретном эталоне в приложении, которое вдохновило вопрос. Если вы хотите, чтобы пройти лишнюю милю, и запустить тест самостоятельно, вот как это сделать:
git clone git://github.com/gbenison/starparse
git clone git://github.com/gbenison/burrow-owl.git -b point-cache-base
point_cache_fetch()
Функции и point_cache_store()
находятся в «нору/спектра/point_cache.c». Соответствующим эталоном является «контрольные показатели/b_cache».
В чем вопрос? –
Если кеш-кеш может забывать элементы, тогда кэш-интерфейс должен добавить способ освобождения элементов, возвращаемых из кеша. – sbridges
@sbridges Что там делать бесплатно? 'point_cache_fetch' просто возвращает' double'. – gcbenison