В два раза больше сбоев страниц при чтении из большого ошибочного массива вместо простого хранения? - PullRequest
0 голосов
/ 05 сентября 2018

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

 ptr[i+4096] = 'A'

Я получил 25,722 сбоев страниц с помощью инструмента «Перф», чего я и ожидал, но если я использую

tmp = ptr[i+4096]

вместо этого ошибки страниц удвоились до 51,322 Я не как это объяснить. Ниже приведен полный код. Спасибо!

void do_something() {
    int i;
    char* ptr;
    char tmp;
    ptr = malloc(100*1024*1024);
    int j = 0;
    int k = 0;

    for (i = 0; i < 100*1024*1024; i+=4096) {

       //ptr[i+4096] = 'A' ;
       tmp = ptr[i+4096];

       for (j = 0 ; j < 4096; j++)
           ptr[i+j] = (char) (i & 0xff); // pagefault
    }
    free(ptr);
}

int main(int argc, char* argv[]) {
    do_something();
    return 0;
}

Информация о машине: Архитектура: x86_64 Операционные режимы процессора: 32-разрядный, 64-разрядный Порядок байтов: Little Endian ЦП: 40 Он-лайн список процессоров: 0-39 Резьба (ы) на ядро: 2 Сердечник (и) на сокет: 10 Разъем (ы): 2 NUMA узел (ы): 2 Идентификатор поставщика: GenuineIntel Семейство процессоров: 6 Модель: 63 Название модели: Intel (R) Xeon (R) CPU E5-2687W v3 @ 3,10 ГГц Степпинг: 2 МГц процессора: 3096,188 BogoMIPS: 6197,81 Виртуализация: VT-x L1d кеш: 32K L1i кеш: 32K Кэш-память второго уровня: 256 КБ Кэш-память третьего уровня: 25600 КБ NUMA node0 ЦП: 0-9,20-29 NUMA node1 ЦП: 10-19,30-39

3.10.0-514.32.3.el7.x86_64 # 1

1 Ответ

0 голосов
/ 06 сентября 2018

malloc() часто удовлетворяет запросы памяти, запрашивая у ОС новые страницы, например, через mmap. Такие страницы обычно распределяются лениво: фактическая страница не выделяется до первого доступа .

То, что происходит затем, зависит от типа первого доступа: когда вы выполняете чтение сначала, Linux отобразит на общей доступной только для чтения COW страницу нулей, чтобы удовлетворить ее, а затем, если вы позже Вы пишете, что требуется вторая ошибка, чтобы выделить частную страницу для записи.

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

Обратите внимание, что выше приведено описание того, как недавно выделенные страницы работают в Linux - когда вы используете malloc, существует другой уровень: malloc обычно будет пытаться удовлетворить запросы блоков, освобожденных ранее процессом, а не постоянно запрашивать новая память. В случае повторного использования памяти, она, как правило, уже будет выгружена, и вышеописанное не будет применяться. Конечно, для вашего первоначального большого выделения в 1024 МБ, где нет памяти для повторного использования, так что вы можете быть уверены, что распределитель получает его из ОС.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...