Получить время, потраченное процессом в пространстве ядра - PullRequest
0 голосов
/ 21 июня 2020

Меня интересует, как это сделать в Windows

Единственным найденным мной API, способным это сделать, был GetProcessTimes. Я возвращаю истину, заполняю структуру времени создания и времени выхода, но время ядра и время пользователя остаются равными нулю. Я пробовал спящий режим, вызывая API-интерфейсы, которые выполняются в режиме ядра, думая, что могу заставить его изменить, но оно остается равным нулю.

Я запускал его с псевдодескриптором (HANDLE)-1) aka GetCurrentProcess(), поэтому я попытался просто открыть дескриптор моего собственного процесса с помощью PROCESS_QUERY_INFORMATION, а также PROCESS_ALL_ACCESS, думая, что, возможно, API не интерпретирует псевдодескриптор правильно , но он все равно не работает.

Что делать?

Код для проверки (проверяю значение pKernelTime, а не только кастомное):

FILETIME pKernelTime{}, a{}, b{}, c{};
unsigned long time(0);
if (true == GetProcessTimes(reinterpret_cast<HANDLE>(-1), &a, &b, &pKernelTime,
    &c))
{
    time = (*(reinterpret_cast<unsigned long*>(&pKernelTime)
        ) / 10000000ul);
}

Код между проверками (файл 27мб) *

char* buff = new char[25000];
    DWORD read(0);
    for (int i = 0; i < 10; ++i)
    {
        HANDLE file = CreateFileA("a.dat", GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL, nullptr);
        ReadFile(file, (void*)buff, 25000, &read, nullptr);
        CloseHandle(file);
    }
    printf("%d\n", read);

1 Ответ

1 голос
/ 21 июня 2020

Я вижу три проблемы с вашим кодом. Во-первых, это:

time = (*(reinterpret_cast<unsigned long*>(&pKernelTime)
    ) / 10000000ul);

должно быть таким:

time = (*(reinterpret_cast<unsigned long long*>(&pKernelTime)
    ) / 10000000ull);

Затем также измените time на unsigned long long.

Во-вторых, time сокращено до целого числа секунд. Вероятно, это не то, что вам нужно - вам нужно что-то более детальное, чем это.

В-третьих, чтобы дать вашей машине реальную работу, измените это:

char* buff = new char[25000];
DWORD read(0);
for (int i = 0; i < 10; ++i)
{
    HANDLE file = CreateFileA("a.dat", GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, nullptr);
    ReadFile(file, (void*)buff, 25000, &read, nullptr);
    CloseHandle(file);
}

на это :

DWORD read(0);
for (int i = 0; i < 100; ++i)
{
    HANDLE file = CreateFileA ("a.dat", GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, nullptr);
    for (int j = 0; j < 25000; ++j)
    {
        BYTE ch;
        ReadFile(file, &ch, 1, &read, nullptr);
    }
    CloseHandle(file);
}

Потому что множество небольших чтений требует больше работы, чем несколько больших.

Эта комбинация изменений должна позволить вам действительно что-то измерить.

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