LINUX.ORG.RU

А как измерить загрузку процессора для выбранного участка кода ?


0

0

допустим есть функция. очень хочется знать насколько сильно она грузит проц.(т.е. avg )
при этом не используя профайлеры, а именно расчитывая эту загрузку в самом коде.

посмотрел пример кода из ядра, но там считается общая загрузка.
как сделать конкретно для куска кода просто не представляю ((

★★★★★

Что подразумевается под "на сколько сильно функция грузит процессор"? Сколько тактов на один вызов функции тратится? И average прямого отношения к загрузке cpu не имеет.

mv ★★★★★
()
Ответ на: комментарий от mv

про то, что LA != cpu load я в курсе, я имел ввиду среднее значение за период.

т.е. допустим, есть ф-я func(), которая где-то вызывается в коде программы xxx.
при выполнении этой ф-ии (пусть она просто считает 10 знаков ПИ), в top можно увидеть, что программа xxx использует 10% cpu time.

получается, что cpu load этой фу-ции = 10% от максимальной загрузки.

и вот этот параметр хочется считать прямо в коде.
т.е. упрощенно:

begin_cpu_calc();
func1();
cpu_load=end_cpu_calc();

print cpu_load;

dreamer ★★★★★
() автор топика
Ответ на: комментарий от dreamer

>в top можно увидеть, что программа xxx использует 10% cpu time.

Это зависит не от функции, а от того, как ядро распределяет нагрузку.

Sectoid ★★★★★
()
Ответ на: комментарий от Sectoid

про профайлеры я тоже в курсе - отладил не отду программу валгриндом.

мне нужен метод, который позволит расчитать это без потери производительности (ну может, менее 0.5%) .

внешние инструменты не годятся, т.к. приложение - mission critical
код на C.

dreamer ★★★★★
() автор топика
Ответ на: комментарий от Sectoid

>Это зависит не от функции, а от того, как ядро распределяет нагрузку.

верно. но ведь и от тяжести вычислений в функции не меньше.

dreamer ★★★★★
() автор топика
Ответ на: комментарий от dreamer

Без профилирования на уровне ядра такого не сделать. Можно перед вызовом функции и после возврата считывать значение time stamp counter (rdtsc на x86), считать разницу, накапливать и делить на общее число тактов (для раза в секунду это будет частота процессора), но это будет неточно, т.к. текущий процесс может быть вытеснен. Соответственно, по хорошему, нужно учитывать переключение задач и много чего ещё.

Если уж так важно точно знать, что сколько ест, то нужно интегрироваться с профилировщиком, например, oprofile. Но примитивно можно и с tsc посчитать, только с учётом того, что кол-во тактов прыгать будет.

mv ★★★★★
()
Ответ на: комментарий от mv

Либо, как вариант, вынести код этой функции в отдельный процесс, общаться с ним через ipc, а для контроля из родительского процесса использовать getrusage.

mv ★★★★★
()
Ответ на: комментарий от dreamer

>верно. но ведь и от тяжести вычислений в функции не меньше.

Дубль 2. Сколько процессорного времени будет отдано процессу зависит от настроек планировщика поцессов в ядре.

Цитирую (Роберт Лав "Разработка ядра Linux. 2е издание."): "... Процессы можно классифицировать как те, которые ограничены скоростью ввода-вывода (I/O bound), и те, которые ограничены скоростью процессора (processor-bound). К первому типу относятся процессы, которые большую часть своего веремени тратят на отправку запросов на ввод-вывод информации и на ожидание ответов на этп запросы. ... Процессы ограниченные скоростью процессора, наоборот, большую часть времени исполняют програмный код. Такие обычно процессы выполняются до того момента, пока они не будут вытеснены, т.к. эти процессы не блокируются в ожидании на запросы ввода-вывода..."

Т.е. когда процесс будет вытеснен зависит от ядра - я рассматриваю Ваш случай, как процесс-числодробилку. Или я где-то ошибаюсь?

Sectoid ★★★★★
()

PROFIL(2) FreeBSD System Calls Manual PROFIL(2)

NAME
profil -- control process profiling

LIBRARY
Standard C Library (libc, -lc)

SYNOPSIS
#include <unistd.h>

int
profil(char *samples, size_t size, vm_offset_t offset, int scale);

DESCRIPTION
The profil() system call enables or disables program counter profiling of
the current process. If profiling is enabled, then at every profiling
clock tick, the kernel updates an appropriate count in the samples
buffer. The frequency of the profiling clock is recorded in the header
in the profiling output file.

The buffer samples contains size bytes and is divided into a series of
16-bit bins. Each bin counts the number of times the program counter was
in a particular address range in the process when a profiling clock tick
occurred while profiling was enabled. For a given program counter
address, the number of the corresponding bin is given by the relation:

[(pc - offset) / 2] * scale / 65536

The offset argument is the lowest address at which the kernel takes pro-
gram counter samples. The scale argument ranges from 1 to 65536 and can
be used to change the span of the bins. A scale of 65536 maps each bin
to 2 bytes of address range; a scale of 32768 gives 4 bytes, 16384 gives
8 bytes and so on. Intermediate values provide approximate intermediate
ranges. A scale value of 0 disables profiling.

RETURN VALUES
The profil() function returns the value 0 if successful; otherwise the
value -1 is returned and the global variable errno is set to indicate the
error.

FILES
/usr/lib/gcrt0.o profiling C run-time startup file
gmon.out conventional name for profiling output file

ERRORS
The following error may be reported:

[EFAULT] The buffer samples contains an invalid address.

SEE ALSO
gprof(1)

HISTORY
The profil() function appeared in Version 7 AT&T UNIX.

BUGS
This routine should be named profile().

The samples argument should really be a vector of type unsigned short.

The format of the gmon.out file is undocumented.

FreeBSD 7.0 June 4, 1993 FreeBSD 7.0

swizard
()
Ответ на: комментарий от dreamer

>rdtsc

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

Pi ★★★★★
()
Ответ на: комментарий от dreamer

> верно. но ведь и от тяжести вычислений в функции не меньше.

не зависит, либо у тебя там есть вычисления и загрузка будет 100%, либо в функции происходит ожидание чего-то и загрузка будет 0%.

Reset ★★★★★
()
Ответ на: комментарий от dreamer

>верно. но ведь и от тяжести вычислений в функции не меньше.

Может, я чего не догоняю, но вычисления - это всегда 100% загрузки проца. (ну или ядра проца, если их несколько) Не 100 - значит функция ожидает ввода-вывода или что-то типа того.

Так что на сколько ф-ция грузит проц зависит от соотношения i/o и вычислений. м.б. man 2 times?

ratatosk
()
Ответ на: комментарий от ratatosk

+ это будет колебаться от системы к системе, да и на одной системе - тоже.

ratatosk
()
Ответ на: комментарий от ratatosk

> Так что на сколько ф-ция грузит проц зависит от соотношения i/o и вычислений. м.б. man 2 times?

utime, stime начисляется по тикам таймера, если функция будет работать меньше тика, то фигня-с выйдет. Собственно, даже CVE-баг есть такой, связанный с cheap attack, когда процесс синхронизируется на начало тика, работает, скажем, 80% времени тика, а всё пенальти достаётся другому процессу. В итоге, проц жрётся, а в top не видно :) На линуксе работало до CFS.

mv ★★★★★
()

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

parser ★★
()

хм, вот тут вспомнилось, что mplayer(консольный) как-то выводит загрузку процессора отдельно для разных стадий показа мувика(кусков кода) - видеодекодер, аудидекодер, рендер, etc.

cobold ★★★★★
()
Ответ на: комментарий от Pi

Это особенности некоторых железок.

подробности в доках к ядру.

cvv ★★★★★
()
Ответ на: комментарий от cobold

хм.. покопаюсь в коде - спасибо!

dreamer ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.