Почему фиктивный цикл потребляет время ядра? - PullRequest
2 голосов
/ 19 сентября 2019

Я написал эту простую, бесполезную программу:

#include <iostream>
using namespace std;
#define TABSIZE 256*1024*1024

int main(){
    volatile int *tab = new int[TABSIZE];

    cerr << "start" << endl;
    for(int i=0;i<TABSIZE;i+=1)
        tab[i] *= i;
    cerr << "stop" << endl;

    delete []tab;
    return 0;
}

После компиляции (с O2) и запуска с time ./a.out Я был очень удивлен результатами:

real    0m1,660s
user    0m0,462s
sys     0m1,177s

Очевидно, что большую часть времени проводят в пространстве ядра, хотя основной цикл не имеет никакого отношения к системным вызовам.Я вижу строку start сразу после запуска программы, поэтому new не занимает много времени.Понятно, что stop появляется незадолго до конца.

Итак, вопрос в том, почему столько времени тратится в пространстве ядра?Я использую GCC 7.4 в Linux 4.15.

1 Ответ

5 голосов
/ 19 сентября 2019
volatile int *tab = new int[TABSIZE];

Этот оператор выделяет 1 ГБ ОЗУ.Эта сумма отмечена в таблице страниц процесса как использованная, но на самом деле не инициализирована и не предоставлена ​​(страницы помечены как «не присутствующие»).

tab[i] *= i

На этом этапе первый доступ кновая страница (обычно 4 КБ) приводит к отказу страницы, который обрабатывается ядром, которое затем инициализирует диапазон памяти нулями и помечает страницу как имеющуюся.Затем, до следующей страницы, доступы происходят без ошибок страницы.

Это управление памятью является причиной использования ЦП ядра.

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