Неисправности страниц и программирование в .Net - PullRequest
4 голосов
/ 15 сентября 2011

Я читаю книгу об операционных системах, и она дает несколько примеров на C, которые я в основном понимаю.Пример, который я сейчас рассматриваю, показывает два почти идентичных фрагмента кода, которые будут выполняться в фиктивной системе ...

int i, j;
int [128] [128] data;

for (j = 0; j < 128; j++)
    for (i = 0; i < 128; i++)
        data [i] [j] = 0;

И второй фрагмент кода

int i, j;
int [128] [128] data;

for (i = 0; i < 128; i++)
    for (j = 0; j < 128; j++)
        data [i] [j] = 0;

Вкл.В этой конкретной системе первый раздел кода приведет к ошибкам в 16 тыс. страниц, а второй - только к 128.

Мои извинения, если это глупый вопрос, но в моем опыте с .NET я всегдабыли в основном не знают о памяти.Я просто создаю переменную, и она «где-то», но я не знаю, где и мне все равно.

Мой вопрос: как бы .NET сравнился с этими примерами C в этой вымышленной системе (страницыразмером 128 слов, каждая строка массива занимает одну полную страницу. В первом примере мы устанавливаем одно целое на странице 1, затем одно целое на странице 2 и т. д. .... в то время как второй пример устанавливает все целые числа на странице 1затем все целые на стр. 2 и т. д.)

Кроме того, хотя я думаю, что понимаю, почему код генерирует разные уровни подкачки, есть ли что-то значимое, что я могу с этим сделать?Разве размер страницы не зависит от операционной системы?Является ли это общим правилом доступа к памяти в массиве как можно более непрерывно?

Ответы [ 3 ]

7 голосов
/ 15 сентября 2011

Вымышленные операционные системы могут быть полезны для демонстрации принципов, но ни одна из известных мне операционных систем на самом деле не работает таким образом.Вы можете получить только 16K ошибок страницы, если страница сразу же становится неотображенной после использования.Хотя это технически возможно, но машина должна находиться под большой нагрузкой, отчаянно не имея ОЗУ для поддержки множества запущенных процессов.В этот момент вы просто больше не заботитесь о перфорации, машина все равно замедлится.Технический термин для этого - « thrashing ».

В этом коде происходит нечто гораздо более важное, чего вы не упомянули.Кэш ЦП уровня 1 играет важную роль в том, как быстро вы можете получить доступ к элементам массива.Строка кэша (обычно 64 байта) заполняется из памяти при первом доступе.Доступ к следующему элементу по следующему адресу памяти очень дешев, данные уже находятся в кеше.Доступ к массиву с изменением внешнего индекса в первую очередь очень дорог, он требует другого заполнения строки кэша, что в худшем случае может занять сотни циклов.При значительном риске удаления существующей строки кэша, которая также содержит данные массива, кэш 1-го уровня не очень велик.Чтобы получить это право, нужно знать, как среда выполнения упорядочивает элементы массива в памяти.

2 голосов
/ 15 сентября 2011

Ваши два образца идентичны, но, вероятно, вы хотите:

int i, j;
int [128] [128] data;

for (i = 0; i < 128; i++)
    for (j = 0; j < 128; j++)
        data [i] [j] = 0;  // <--- i,j

И второй фрагмент кода

int i, j;
int [128] [128] data;

for (i = 0; i < 128; i++)
    for (j = 0; j < 128; j++)
        data [j] [i] = 0;   // <--- j,i

Таким образом, при условии, что размер страницы 128 * sizeof (int):

  • в одном случае вы последовательно выполняете итерацию по массиву.В этом случае наихудшим количеством ошибок страниц является размер массива в страницах = 1.

  • , в другом случае вы переходите на новую страницу на каждой итерации, поэтому вв худшем случае у вас может быть ошибка страницы на каждой итерации цикла.

Ситуация точно такая же в .NET.

0 голосов
/ 15 сентября 2011

Количество сбоев страниц, которые вы получите, будет зависеть от количества страниц, к которым вы обращаетесь, которых нет в памяти.

Скорее всего, страницы в стеке будут в памяти, если только это не первый раз, когда стекиспользовался до этой степени.

Предполагая, что размер вашей страницы равен 4 КБ, как и во многих системах, и ни одна из страниц не находится в памяти, вы получите доступ к 128 * 128 * 4 байта или 64 КБ, которые16 страниц.Примечание: возможно, что эта структура будет на 17 страницах, если она не начинается на границе страницы, и в этом случае первая страница будет в памяти.

Пока вы обращаетесь к каждой странице, онане имеет значения, как вы к ним обращаетесь или в каком порядке.


Возможно, вы говорите об ошибках кэша, и порядок доступа к данным может иметь значение.В этом случае лучше всего обращаться к данным постепенно по последнему индексу.т.е. для a[i][j] вы хотите, чтобы внутренний цикл использовал j Однако, если ваш кэш достаточно большой, это может не иметь значения.Он может сильно отличаться для действительно больших структур, которые не вписываются в более быстрые кэши.

...