Laboratório de Sistemas Operacionais 1

Pontifícia Universidade Católica de Campinas

Experimento # 1

Introdução

O primeiro experimento teve como base processos. A relação deles no sistema operacional *nix bem como o entendimento e criação dos mesmos.

Partindo do princípio que o computador é uma máquina digital, subentende-se que toda e qualquer medição de tempo é precisa e. Seguindo essa linha de raciocínio foi usado um programa para testes e comprovando que essa regra é uma excessão, ou seja, a medição de duração do tempo levado por um processo não é exata.

Diversos fatores contribuem para que isso ocorra, uma delas é chamada de multi-task (multi-tarefa). Multi-tarefa nada mais é que a capacidade do SO tem de lidar com vários processos (generalizando programas) ao mesmo tempo se utilizando apenas de um processador.

Racionalmente pode-se notar que com apenas 1 processador é muito díficil de processar duas coisas no mesmo e exato momento. A troca de processos entre o processador e a memória acarreta em um atraso, mesmo que pequeno, justificando em partes um dos motivos porque não é medido precisamente o tempo levado por um processo.

Utilizando o programa exemplo, foi medido diversas vezes tempos de execução e seu respectivo desvio total e médio, após isso, o programa fonte foi modificado e novamente nas mesmas condições o tempo foi medido. Veja abaixo a tabela seguida da descrição.

2) Programa exemplo - Experiment-2.c

/*******************************************************************************

* Este programa faz parte do curso sobre tempo real do Laboratorio Embry-Riddle

*

* Seguem os comentarios originais:

*

* Experiment #2: Multi-Tasking, Measuring Drift

*

* Programmer: Eric Sorton

* Date: 1/27/97

* For: MSE599, Special Topics Class

*

* Purpose: When a basic sleep call is used to determine the precise time

* when an action will occur the problem of drift occurs.

* The measurement of time is imprecise. Similarly, the time in

* which the sleep call returns is imprecise. Over time, this

* will cause the ocurrence of time to drift. Just as if a clock

* loses 1 second every day, over one day, it is significant, but

* over a year, it loses 365 seconds, which is over 6 minutes.

* This is an example of drift.

*

* Proposito: Quando uma chamada básica sleep é usada para determinar o

* instante exato em que alguma acao vai ocorrer, ocorre o problema

* do desvio. A medicao de tempo e imprecisa. Similarmente, o tempo

* que demora o retorno da chamada sleep tambem e impreciso. Ao

* longo do tempo, isto ocasionara um desvio de tempo. Algo como se

* um relogio perdesse um segundo a cada dia. Ao longo de um dia,

* essa diferenca e insignificante, mas, ao longo de um ano, sao

* perdidos 365 segundo, o que e superior a 6 minutos. Este e um

* exemplo de desvio.

*

*******************************************************************************/

/*

* Includes Necessarios, verifique se as bibliotecas no diretorio sys/ estao

* la. Caso nao estejam, verifique onde estao e altere o include

*/

#include <sys/time.h>	/* for gettimeofday() */

#include <unistd.h>	/* for gettimeofday() */

#include <stdio.h>	/* for printf() */

#include <unistd.h>	/* for fork() */

#include <sys/types.h>	/* for wait() */

#include <sys/wait.h>	/* for wait() */

/*

* NO_OF_ITERATIONS e o numero de vezes que se repete o loop existente

* em cada processo. Se este valor for maior, a media calculada sofrera

* menor desvio.

*/

#define NO_OF_ITERATIONS	500

/*

* NO_OF_CHILDREN e o numero de filhos a serem criados, cada qual responsavel

* pela medida do desvio. Quanto mais filhos, maior sera o desvio.

*/

#define NO_OF_CHILDREN	3

/*

* SLEEP_TIME corresponde a quantidade de tempo para ficar dormindo.

* essa quantidade tem efeito no desvio, quanto menor, maior sera o desvio.

*/

#define SLEEP_TIME	20

/*

* MICRO_PER_SECOND define o numero de microsegundos em um segundo

*/

#define MICRO_PER_SECOND	1000000

/*

* Programa Principal, e o programa pai

*/

int main( int argc, char *argv[] )

{

/*

* start_time e stop_time conterao o valor de tempo antes e depois

* que as trocas de contexto comecem

*/

struct timeval start_time;

struct timeval stop_time;

/*

* Outras variaveis importantes

*/

float drift;

int count;

int rtn;

int child_no;

/*

* Criacao dos processos filhos

*/

rtn = 1;

for( count = 0; count < NO_OF_CHILDREN; count++ ) {

if( rtn != 0 ) {

rtn = fork();

} else {

break;

}

}

/*

* Verifica-se rtn para determinar se o processo e pai ou filho

*/

if( rtn == 0 ) {

child_no = count;

/*

* Portanto, sou filho. Faco coisas de filho.

* Primeiro, obter o tempo inicial.

*/

gettimeofday( &start_time, NULL );

/*

* Este loop ocasiona a dormencia do filho, de acordo com

* SLEEP_TIME, tantas vezes quanto NO_OF_ITERATIONS

*/

for( count = 0; count < NO_OF_ITERATIONS; count++ ) {

usleep(SLEEP_TIME);

}

/*

* Paraobter o tempo final

*/

gettimeofday( &stop_time, NULL );

/*

* Calcula-se o desvio

*/

drift = (float)(stop_time.tv_sec - start_time.tv_sec);

drift += (stop_time.tv_usec - start_time.tv_usec)/(float)MICRO_PER_SECOND;

/*

* Exibe os resultados

*/

printf("Filho #%d -- desvio total: %.6f -- desvio medio: %.6f\n",

child_no, drift - NO_OF_ITERATIONS*SLEEP_TIME/MICRO_PER_SECOND,

(drift - NO_OF_ITERATIONS*SLEEP_TIME/MICRO_PER_SECOND)/NO_OF_ITERATIONS);

} else {

/*

* Sou pai, aguardo o termino dos filhos

*/

for( count = 0; count < NO_OF_CHILDREN; count++ ) {

wait(NULL);

}

}

exit(0);

}

3) Resultados do programa exemplo

Teste com o programa original: Experiment-2.c
Rodada	Filho 1 Filho 2 Filho 3 desvio total desvio médio desvio total desvio médio desvio total desvio médio
1	10.014920	0.020030	10.015351	0.020031	10.023901	0.020048
2	10.061352	0.020123	10.061788	0.020124	10.081298	0.020163
3	10.020868	0.020042	10.021707	0.020043	10.060897	0.020122
4	10.066015	0.020132	10.066564	0.020133	10.085992	0.020172
5	10.057559	0.020115	10.058211	0.020116	10.076928	0.020154
6	10.073845	0.020127	10.063996	0.020128	10.081773	0.020164
7	10.407375	0.020815	10.405574	0.020811	10.405830	0.020812
8	10.021778	0.020044	10.022298	0.020045	10.029570	0.020059
9	10.006906	0.020014	10.007421	0.020015	10.030146	0.020060
10	10.057081	0.020114	10.057194	0.020114	10.089799	0.020180

A tabela acima demonstra dados medidos em intervalos e situações diferentes de processamento. Nota-se que quanto maior a carga do sistema, maior o desvio, porém isso não é regra, visto que, em alguns momentos o tempo foi menor com uma carga maior.

Execução	Processos em execução
1	Normal, apenas rodando o programa exemplo.
2	Abrindo programa de email Evolution.
3	Abrindo programa Gimp 2.0pre e Mozilla Cliente Email.
4	Rodando em círculos uma janela do ambiente gráfico gnome(gtk).
5	Rodando gmplayer com filme divx, kde + gnome.
6	Rodando gmplayer com filme divx, xawtv(receptor de sinal de tv), kde, gnome e rodando em círculos uma janela do ambiente gráfico gnome(gtk).
7	Rodando gmplayer com filme divx, xawtv(receptor de sinal de tv), gnome e compilando o fonte de um programa(cc & gcc).
8	Rodando gmplayer com filme divx, xawtv(receptor de sinal de tv), gnome e compilando o fonte de um programa(cc & gcc) e rodando em círculos uma janela do ambiente gráfico gnome(gtk).
9	Rodando gmplayer com filme divx, xawtv(receptor de sinal de tv), gnome e compilando o fonte de um programa(cc & gcc) e rodando uma proteção de tela 3D.
10	Rodando gmplayer com filme divx, xawtv(receptor de sinal de tv), gnome e compilando dois códigos fontes (cc & gcc), programa de descriptografica com prioridade máxima (nice -19) e rodando uma proteção de tela 3D.

A tabela acima descreve resumidamente o que foi feito e executado na máquina para aumentar o número de processamento e carga do SO.

Alguns dos programas utilizados, requerem da máquina instruções de alto desempenho, como processamento 3d, vídeos, na sua maioria recursos multi-mídia. Note que essa tabela foi também utilizada depois da modificação do programa exemplo.

4) Programa exemplo modificado - Experiment-2_modificado.c

/*******************************************************************************

* Este programa faz parte do curso sobre tempo real do Laboratorio Embry-Riddle

*

* Seguem os comentarios originais:

*

* Experiment #2: Multi-Tasking, Measuring Drift

*

* Programmer: Eric Sorton

* Date: 1/27/97

* For: MSE599, Special Topics Class

*

* Purpose: When a basic sleep call is used to determine the precise time

* when an action will occur the problem of drift occurs.

* The measurement of time is imprecise. Similarly, the time in

* which the sleep call returns is imprecise. Over time, this

* will cause the ocurrence of time to drift. Just as if a clock

* loses 1 second every day, over one day, it is significant, but

* over a year, it loses 365 seconds, which is over 6 minutes.

* This is an example of drift.

*

* Proposito: Quando uma chamada básica sleep é usada para determinar o

* instante exato em que alguma acao vai ocorrer, ocorre o problema

* do desvio. A medicao de tempo e imprecisa. Similarmente, o tempo

* que demora o retorno da chamada sleep tambem e impreciso. Ao

* longo do tempo, isto ocasionara um desvio de tempo. Algo como se

* um relogio perdesse um segundo a cada dia. Ao longo de um dia,

* essa diferenca e insignificante, mas, ao longo de um ano, sao

* perdidos 365 segundo, o que e superior a 6 minutos. Este e um

* exemplo de desvio.

*

*******************************************************************************/

/*

* Includes Necessarios, verifique se as bibliotecas no diretorio sys/ estao

* la. Caso nao estejam, verifique onde estao e altere o include

*/

#include <sys/time.h>	/* for gettimeofday() */

#include <unistd.h>	/* for gettimeofday() */

#include <stdio.h>	/* for printf() */

#include <sys/types.h>	/* for wait() */

#include <sys/wait.h>	/* for wait() */

/*

* NO_OF_ITERATIONS e o numero de vezes que se repete o loop existente

* em cada processo. Se este valor for maior, a media calculada sofrera

* menor desvio.

*/

#define NO_OF_ITERATIONS	500

/*

* NO_OF_CHILDREN e o numero de filhos a serem criados, cada qual responsavel

* pela medida do desvio. Quanto mais filhos, maior sera o desvio.

*/

#define NO_OF_CHILDREN	3

/*

* SLEEP_TIME corresponde a quantidade de tempo para ficar dormindo.

* essa quantidade tem efeito no desvio, quanto menor, maior sera o desvio.

*/

//#define SLEEP_TIME	20
// vai ser lido do teclado

/*

* MICRO_PER_SECOND define o numero de microsegundos em um segundo

*/

#define MICRO_PER_SECOND	1000000

/*

* Programa Principal, e o programa pai

*/

int main( int argc, char *argv[] )

{

/*

* start_time e stop_time conterao o valor de tempo antes e depois

* que as trocas de contexto comecem

*/

struct timeval start_time;

struct timeval stop_time;

extern char **environ;

/*

* Outras variaveis importantes

*/

float drift;

int count;

int rtn;

char child_no, st;

int SLEEP_TIME; // para sleep_time ser lido do teclado
/* Ler SLEEP TIME */
while(1)
{
printf("Digite o numero do sleep time, multiplo de 50 : ");
scanf("%d",&SLEEP_TIME);
if((SLEEP_TIME % 50)==0)
break;
}
/*

* Criacao dos processos filhos

*/

for( count = 0; count < NO_OF_CHILDREN; count++ ){

if( rtn != 0 ){

rtn = fork();

}
else{

break;

}
}
if( rtn == 0 ){
child_no = count+48;
st=SLEEP_TIME+48;
execl("Exper_modificado_filho",&child_no,&st,NULL);
}
else {
/*
* Sou pai, aguardo o termino dos filhos
*/
for( count = 0; count < NO_OF_CHILDREN; count++ ) {
wait(NULL);
}

}

exit(0);

}

Experiment-2_modificado_filho.c

#include <sys/time.h>	/* for gettimeofday() */

#include <unistd.h>	/* for gettimeofday() */

#include <stdio.h>	/* for printf() */

#include <sys/types.h>	/* for wait() */

#include <sys/wait.h>	/* for wait() */

/*

* NO_OF_ITERATIONS e o numero de vezes que se repete o loop existente

* em cada processo. Se este valor for maior, a media calculada sofrera

* menor desvio.

*/

#define NO_OF_ITERATIONS	500

/*

* NO_OF_CHILDREN e o numero de filhos a serem criados, cada qual responsavel

* pela medida do desvio. Quanto mais filhos, maior sera o desvio.

*/

#define NO_OF_CHILDREN	3

/*

* MICRO_PER_SECOND define o numero de microsegundos em um segundo

*/

#define MICRO_PER_SECOND	1000000

int main( int argc, char *argv[])

{

struct timeval start_time;

struct timeval stop_time;

/*

* Outras variaveis importantes

*/

float drift;

int count;

int child_no;

int SLEEP_TIME;

if(argc!=2)

{

printf("\nParametros invalidos!\n\n");

exit(1);

}

child_no=atoi(argv[0]);

SLEEP_TIME=atoi(argv[1]);

gettimeofday( &start_time, NULL );

/*

* Este loop ocasiona a dormencia do filho, de acordo com

* SLEEP_TIME, tantas vezes quanto NO_OF_ITERATIONS

*/

for( count = 0; count < NO_OF_ITERATIONS; count++ ) {

usleep(SLEEP_TIME);

}

/*

* Paraobter o tempo final

*/

gettimeofday( &stop_time, NULL );

/*

* Calcula-se o desvio

*/

drift = (float)(stop_time.tv_sec - start_time.tv_sec);

drift += (stop_time.tv_usec - start_time.tv_usec)/(float)MICRO_PER_SECOND;

/*

* Exibe os resultados

*/

printf("Filho #%d -- desvio total: %.6f -- desvio medio: %.6f\n",

child_no, drift - NO_OF_ITERATIONS*SLEEP_TIME/MICRO_PER_SECOND,

(drift - NO_OF_ITERATIONS*SLEEP_TIME/MICRO_PER_SECOND)/NO_OF_ITERATIONS);

}

Resultado do programa modificado

Teste com o programa modificado: Experiment-2_modificado_filho.c Experiment-2_modificado.c
Rodada	Filho 1 Filho 2 Filho 3 desvio total desvio médio desvio total desvio médio desvio total desvio médio
1	5.014185	0.010028	5.043105	0.010086	5.062240	0.010124
2	5.006345	0.010013	5.065142	0.010130	5.086568	0.010173
3	5.123408	0.010247	5.242499	0.010485	5.351712	0.010703
4	5.077588	0.010155	5.086613	0.010173	5.095653	0.010191
5	5.026096	0.010052	5.002021	0.010004	4.997804	0.009996
6	5.142824	0.010286	5.171788	0.010344	5.200973	0.010402
7	5.056455	0.010113	5.014129	0.010028	5.019106	0.010038
8	5.098501	0.010197	5.068639	0.010137	5.068093	0.010136
9	5.027053	0.010054	5.048405	0.010097	5.067672	0.010135
10	5.095501	0.010242	5.086413	0.010483	5.095353	0.010172

Análise dos resultados

Após a modificação do programa exemplo nota-se visualmente um declínio no desvio de execução dos processos.

Cesar Henrique Kállas

2004-02-16T15:18:24