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:
|
||||||
---|---|---|---|---|---|---|
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.