#c #memory-management #virtual-memory #page-fault
#c #управление памятью #виртуальная память #ошибка страницы
Вопрос:
Я пытаюсь понять подкачку виртуальной памяти. У меня есть следующий фрагмент кода, который представляет первый шаг в процессе. Здесь search_tbl
вызывается из основной программы для каждого логического адреса, чтобы проверить, есть ли в таблице страниц запись, которая сопоставляет предоставленный логический адрес с местоположением в физической памяти. vfn
— номер виртуального фрейма.
ОТРЕДАКТИРОВАНО: Имеет ли эта реализация какой-либо смысл? Или я иду по неправильному пути?
Любая помощь / предложение были бы высоко оценены. Спасибо.
uint vfn_bits;//virtual frame number
static tbl_entry **tbl;
uint page_bits = log_2(pagesize);
vfn_bits = addr_space_bits - page_bits;
tbl = calloc(pow_2(vfn_bits), sizeof (tbl_entry*));
tbl_entry *search_tbl(uint vfn) {
uint index = vfn;
if (tbl[index] == NULL) {
/* Initial miss */
tbl[index] = create_tbl_entry(vfn);
}
return tbl[index];
}
tbl_entry *create_tbl_entry(uint vfn) {
tbl_entry *te;
te = (tbl_entry*) (malloc(sizeof (tbl_entry)));
te->vfn = vfn;
te->pfn = -1;
te->valid = FALSE;
te->modified = FALSE;
te->reference = 0;
return te;
}
Комментарии:
1. Из вашего вызова calloc и функции tbl_search это выглядит так, как вы, вероятно, имели в виду
static tbl_entry **tbl;
? В противном случае вы хотите,sizeof(tbl_entry)
чтобы вызов calloc и поиск были совершенно разными.2. @Chris Спасибо, Крис. Вы правы. Я изменил вызов calloc на
sizeof(tbl_entry)
. Если бы я использовал ‘tbl_entry ** tbl’, как бы отличался поиск — и имело бы больше смысла делать последнее?3. @Chris Я отредактировал код и обновил свой вопрос. Любая помощь будет высоко оценена.
Ответ №1:
Единственная реальная проблема, которую я вижу в этом, заключается в том, что search_tbl()
тип возвращаемого значения tbl_entry*
, но на самом деле он возвращает tbl_entry
. Хотя, если подумать, это может быть серьезной проблемой, если таблица страниц действительно представляет собой массив указателей на записи таблицы страниц. Также, если sizeof(tbl_entry) > sizeof(tbl_entry*)
вы не выделяете достаточно места для таблицы.
Другая проблема может быть getbits()
. Обычной практикой является нумерация битов n-разрядного целого типа с 0 в качестве младшего значащего бита и n — 1 в качестве старшего значащего бита. Если это имеет место для getbits()
API, вы вычисляете индекс на основе неправильной части адреса.
Редактировать
Вышесказанное было верно для исходной версии кода в вопросе, который был отредактирован.
Что касается вопроса getbits в комментарии, если используется следующее (при условии, что 32-разрядные адреса)
uint32_t getbits(uint32_t x, unsigned int p, unsigned int n)
{
return (x >> (p 1-n)) amp; ~(~0 << n);
}
Это предполагает, что наиболее значащий бит — это бит с наибольшим номером, т. е. бит 31 является старшим битом. Итак, если вы предполагаете размер страницы 4096 байт, номер кадра адреса может быть получен следующим образом:
vfn = getbits(x, 31, 20); // 31 is the top bit, number of bits is 32 - log2(4096)
Комментарии:
1. Спасибо за указания, Джереми. Код наконец-то скомпилирован! getbits() просто получает n битов из позиции p с помощью этого кода
(x >> (p 1-n)) amp; ~(~0 << n)
. И я преобразую логический адресvaddr
в номер виртуальной страницы, используя это:getbits(vaddr, addr_space_bits-1, (addr_space_bits - page_bits))
2. @moejoe: Добавлено немного о
getbits()
3. Джереми, это именно то, что у меня есть
uint vfn = getbits(vaddr, addr_space_bits - 1, vfn_bits)
— на следующем шаге я пытаюсь выяснить, как я могу использовать эту настройку для обработки ошибок LRU. Я полагаю, что это будет связанный списокtbl_entry
, который я должен использовать. Возможно, использование перехода от указателя к указателю окупится здесь. Есть какие-либо комментарии по настройке таблицы страниц на данный момент? Я также расскажу, как я планирую добавлять и удалять страницы из физической памяти. Спасибо вам за вашу помощь до сих пор 🙂4. @moejoe: Удачи с этим. LRU сложно реализовать без аппаратной поддержки. Ознакомьтесь с этой страницей Википедии для получения дополнительной информации об алгоритмах подкачки: en.wikipedia.org/wiki/Page_replacement_algorithm