Колледж классического приватного университета кафедра программирования и информационных технологий Отчет по лабораторной работе № 4 дисциплины "Операционные системы" Выполнил: ст. гр. DI-112 Троцко А.К. Принял: Хрипко С.Л Запорожье 2016 г Цель работы - исследовать временные характеристики программных процессов операционной системы Windows. Разработать программы измерения временных характеристик программных процессов. Разработать программы, моделирующие характерные программные процессы. Провести вычислительные эксперименты по определению и сопоставлению временных характеристик программных процессов. 4. Выполнить подбора параметра повторения с учетом операций ввода-вывода. Зафиксировать в отчете это значение и время выполнения. 5. Выполнить анализ полученных результатов. Выяснить количественно на сколько или во сколько раз операции ввода/вывода замедляют выполнение программы. 6. Выполните подобное сравнение (см. п.5) для случаев: - "вычислительный" процесс не использует вызов процедуры, например для probatime.cpp, "цикл расчета" реализован без вызова процедуры: for(long int k=1; k<=k_out; k++) { for(j=0; j<k_in; j++) { y= exp(x); // что вычисляется.... }; }; - "цикл расчета" реализован с использованием вызова процедуры (в место выше указанного фрагмента): for(long int k=1; k<=k_out; k++) { for(j=0; j<k_in; j++) { y= dig(x);// что вычисляется.... }; }; Саму процедуру оформите как: double dig(double x) { double x, y; y= exp(x); // что вычисляется.... return y; } Сравните и прокомментируйте полученные результата. 7. Выполните подобное сравнение для случаев - в часто (многократно) вызываемой процедуре определяются ("рождаются") локальные переменные и в процедуре используются статические переменны: например: double z(10000); - в первом случае, и static double z(10000) - во втором. Напомним, что динамически "получить" оперативную память для использования в программе можно, например, по следующей "схеме": double dig(double x) { double y, *ddd; int n=10000; ddd=(double*)malloc(n*sizeof(double)); y=exp(x); free(ddd); // или delete [] ddd; return y; } Подробнее см.testtime2. Сравните и прокомментируйте полученные результата. 8. Исследуйте влияния буферизованного (потокового) и не буферизованного ввода/вывода на время выполнения программного процесса. Для этого создайте два процесса по разному выводящие на винчестер достаточно большие файлы разными способами. Буферизованный (потоковый) и не буферизированный вывод в программах может быть организован путем использования соответствующих С++ библиотечных функций. Буферизированный вывод обычно выполняется по следующей схеме: char *buf=new char[101]; FILE *f1; f1=fopen("d:\\fff.txt","w+t"); if (!f1) { perror("d:\\fff.txt"); exit(16); }; //********************** sprintf(buf,"%99d\n", num_str++); fprintf(f1,"%s",buf); //********************** fclose(f1); Не буферизированный вывод обычно выполняется по следующей схеме: char *buf=new char[101]; int handle, result; handle=open("d:\\fff1.txt",O_RDWR|O_TRUNC|O_TEXT|O_CREAT, S_IWRITE); if (handle == -1) { perror("Open d:\\fff1.txt"); exit(16); } //********************** sprintf(buf,"%99d\n", num_str++); result=write(handle, buf, strlen(buf));// запись блоками по strlen(buf) байт. //********************** close (handle); можно, конечно записывать и по одному байту - //********************** sprintf(buf,"%99d\n", num_str++); for(int i=0; buf[i] != '\0'; i++) { result=write(handle, &buf[i], 1); if ( result == -1 ) { perror("write d:\\fff.txt"); exit (16); }; }; но это слишком "расточительно" Примеры таких программ здесь: буферизированный вывод - a_f.cpp не буферизированный вывод запись по 100 байт - a_s.cpp, не буферизированный вывод запись по 1 байту - a_s1.cpp или все программы в одном архиве. В этих примерах программы создают на диске D: файлы объемом около 400 Мбайт. 9. Выберите рациональное значение k_out1 , выполните процесс "А"testtime в режиме "без вывода" зафиксируйте его параметры T1all, T1cpu, T1wait. В дальнейшем такой процесс будем называть "I/O process". 9а. Выберите рациональное значение k_out2 , выполните процесс "В" testtime в режиме "с выводом" зафиксируйте его параметры T2all, T2cpu, T2wait. В дальнейшем такой процесс будем называть "CPU process". Подберите значения k_out1 и k_out2 так, что бы T1all и T2all были примерно одного порядка. 9б.Создайте пакетную процедуру запуска на выполнения двух процессов "А" и "В" (программ testtime). Запланируйте выполнение программ в тех же режимах, что и раньше. 9в. Укажите для этих процессов одинаковый класс приоритета, например выполнив процедурный файл: start "Процесс А I/O start "Процесс В - CPU process"/LOW testtime 100 process" /LOWtesttime1 2 Выполните эти два процесса в "параллельном" режиме. Зафиксируйте параметры Tall, Tcpu, Twait для каждого процесса и определите: - среднее ("астрономическое") время выполнения двух процессов T2s =(T1all+T2all)/2 среднее время ожидания двух процессов T2wait=(T1wait+T2wait)/2 - полное время выполнения двух процессов T2=max( T1all, T2all); 9г. Укажите для этих процессов разные класс приоритета - для "А" низкий, для "В" высокий, например: start "Процесс А I/O process"/LOW start "Процесс В - CPU process"/REALTIME testtime 100 testtime 1 2 Выполните эти два процесса в "параллельном" режиме и зафиксируйте для этого случая такую же как в п. 9в временную статистику. 9д. Укажите для этих процессов другое распределение приоритетов - для "А" высокий, для "В" - низкий, например: start "Процесс А - I/O process"/REALTIME testtime 1 2 start "Процесс В - CPU process"/LOW testtime 100 Выполните эти два процесса в "параллельном" режиме и зафиксируйте для этого случая такую же как в п. 9в временную статистику. 9.е Сравните и объясните полученные результаты. Сформулируйте простейшее правило назначение приоритетов для процессов, обладающих характерными свойствами. 10. Создайте два "I/O process" и один "CPU process". Выполните эти процессы последовательно и параллельно в режиме равных приоритетов. Для этого создайте соответствующие процедурные файлы, использующие команду операционной системы START(используйте опцию /wait ). Создайте процедурный файл "параллельного" запуска этих процессов и назначьте им наиболее рациональное распределение приоритетов. Проведите эксперимент и выясните, на сколько изменилась общие показатели выполнения этих процессов. Объясните почему. 2.Выполнение работы 4.При изменении увеличении переменных затрата времени на выполнение процесса увеличивается. 5. С вводом/выводом скорость выполнения замедляется в 3 раза. 6. При замени цикла требуется больше времени на реализацию 7. в часто (многократно) вызываемой процедуре определяются ("рождаются") локальные переменные: в процедуре используются статические переменны: Первый случай равен второму случаю. Не буферизированный вывод: не буферизированный вывод: 9. int main(int argc, char *argv[]) { unsigned __int64 Tall, Tcpu, Twait; double Pusing; long int kmax; /*Коэффициент повторения внешнего цикла */ long int p1=0; /* = 0 ни чего доп. не делать */ /* = 1 "слушать" консоль и прервать процесс по ESC */ /* = 2 выполнять вывод на консоль */ int rc; int k_in, k_out; sys_time("Начало процесса "); if (argc <= 1 ) kmax=1; else sscanf(argv[1], "%d" , &kmax); if (argc <= 2 ) p1=0; else sscanf(argv[2], "%d" , &p1); printf("============> Начали....(p1=%d)....\n", p1); printf("Коэффициент повторения цикла k=%d\n", kmax); k_out=kmax; k_in=0x0007FFFF; for(long int k=1; k<=kmax; k++) { rc=fon_proc(k_in, p1); //Sleep(2000); if ( rc==1) {k_out=k; break;}; if ( p1==1 && p1==2) // слушать консоль..... if ( (kbhit() != 0) && (getch() == 27) ) {k_out=k; break;}; }; printf("============> Кончили...(k_out=%ld)............\n", k_out); sys_time("Конец процесса "); proc_stat_time(); getchar(); return 0; } double dig(double x) { double y, *ddd; int n=10000; ddd=(double*)malloc(n*sizeof(double)); y=exp(x); free(ddd); //delete [] ddd; return y; } Вывод. При проведении ряда тестов было замечено что колебания времени при паралельно запуске процессов А и В время не значительно не меняется но колебания не превышают 20 миллисекунд. Такие же результаты замечены в 9а 9б .