Архитектура операционной системы UNIX


         

Построение профиля - часть 2


На пользовательском уровне для измерения параметров выполнения процессов можно использовать системную функцию profil: profil(buff,bufsize,offset,scale);

где buff - адрес массива в пространстве задачи, bufsize - размер массива, offset - виртуальный адрес подпрограммы пользователя (обычно, первой по счету), scale - способ отображения виртуальных адресов задачи на адрес массива. Ядро трактует аргумент "scale" как двоичную дробь с фиксированной точкой слева. Так, например, значение аргумента в шестнадцатиричной системе счисления, равное Oxffff, соответствует однозначному отображению счетчика команд на адреса массива, значение, равное Ox7fff, соответствует размещению в одном слове массива buff двух адресов программы, Ox3fff - четырех адресов программы и т.д. Ядро хранит параметры, передаваемые при вызове системной функции, в пространстве процесса. Если таймер прерывает выполнение процесса тогда, когда он находится в режиме задачи, программа обработки прерываний проверяет значение счетчика команд в момент прерывания, сравнивает его со значением аргумента offset и увеличивает содержимое ячейки памяти, адрес которой является функцией от bufsize и scale.

Рассмотрим в качестве примера программу, приведенную на Рисунке 8.12, измеряющую продолжительность выполнения функций f и g. Сначала процесс, используя системную функцию signal, делает указание при получении сигнала о прерывании вызывать функцию theend, затем он вычисляет диапазон адресов программы, в пределах которых будет производиться измерение продолжительности (начиная с адреса функции main и кончая адресом функции theend), и, наконец, запускает функцию profil, сообщая ядру о том, что он собирается начать измерение. В результате выполнения программы в течение 10 секунд на несильно загруженной машине AT&T 3B20 были получены данные, представленные на Рисунке 8.13. Адрес функции f превышает адрес начала профилирования на 204 байта; поскольку текст функции f имеет размер 12 байт, а размер целого числа в машине AT&T 3B20 равен 4 байтам, адреса функции f отображаются на элементы массива buf с номерами 51, 52 и 53. По такому же принципу адреса функции g отображаются на элементы buf c номерами 54, 55 и 56. Элементы buf с номерами 46, 48 и 49 предназначены для адресов, принадлежащих циклу функции main. В обычном случае диапазон адресов, в пределах которого выполняется измерение параметров, определяется в результате обращения к таблице идентификаторов для данной программы, где указываются адреса программных секций. Пользователи сторонятся функции profil из-за того, что она кажется им слишком сложной; вместо нее они используют при компиляции программ на языке Си параметр, сообщающий компилятору о необходимости сгенерировать код, следящий за ходом выполнения процессов.

#include <signal.h> int buffer[4096]; main() { int offset,endof,scale,eff,gee,text; extern theend(),f(),g(); signal(SIGINT,theend); endof = (int) theend; offset = (int) main; /* вычисляется количество слов в тексте программы */ text = (endof - offset + sizeof(int) - 1)/sizeof(int); scale = Oxffff; printf ("смещение до начала %d до конца %d длина текста %d\n", offset,endof,text); eff = (int) f; gee = (int) g; printf("f %d g %d fdiff %d gdiff %d\n",eff,gee, eff-offset,gee-offset); profil(buffer,sizeof(int)*text,offset,scale); for (;;) { f(); g(); } } f() { } g() { } theend() { int i; for (i = 0; i < 4096; i++) if (buffer[i]) printf("buf[%d] = %d\n",i,buffer[i]); exit(); }

Рисунок 8.12. Программа, использующая системную функцию profil

смещение до начала 212 до конца 440 длина текста 57 f 416 g 428 fdiff 204 gdiff 216 buf[46] = 50 buf[48] = 8585216 buf[49] = 151 buf[51] = 12189799 buf[53] = 65 buf[54] = 10682455 buf[56] = 67

Рисунок 8.13. Пример результатов выполнения программы, использующей системную функцию profil




Содержание  Назад  Вперед