"sys time" ao rodar o programa

Iniciado por mpoloureiro, 28 de Março de 2011, 17:54

tópico anterior - próximo tópico

mpoloureiro

Ola a todos!
Recentemente me deparei com um problema na hora de executar um programa em c.
Tenho um programa grande, composto de muitas subrotinas. Dentro de uma delas (Sub1),
existe um loop que chama uma outra subrotina (Sub2) diversas vezes. O fato é que,
recentemente precisei fazer uma modificação na Sub2 e criei novos vetores. O problema
é que agora, apos compilar o programa, a execuçao do mesmo esta sendo feita usando
o "sys time" do processador (antes era o "user time").
Vou tentar especificar o problema em codigo.
-------------------------------------------------------------------------------------------------
void Sub1 ();
void Sub2 ();

void main ()
{
...
Sub1();
...
}

void Sub1()
{
...
for (i=0;i<1000000;i++)
{
...
Sub2 ();
...
}
...

return;
}

void Sub2 ()
{
int *v1,*v2,...;

v1=malloc...
v2=malloc...
for (i=0;i<1000000;i++)
{
  v1[i]=0;
  v2[i]=0;
  ...
}

free(v1);
free(v2);
...

return;
}
-------------------------------------------------------------------------------------------------

Note que Sub2 apenas cria um(s) vetor(es) (sim, os tamanhos que eu uso sao da ordem de 1.000.000), atribui
0 a todos os indices e fecha o(s) vetor(s).

Supondo que eu precise criar dois vetores, v1 e v2. Atribuindo tipos diferentes a cada um (ex: int e unsigned long),
o problema NAO ocorre, ou seja, todo o tempo de processamento é de "user time". Utilizando tipos iguais a execuçao
passa para "sys time"

Se ao invés de criar os vetores em Sub2 eu simplesmente cria-los em Sub 1, o programa volta a rodar integralmente
em "user time".
-------------------------------------
void Sub1()
{
...
for (i=0;i<1000000;i++)
{
...
int *v1,*v2,...;

v1=malloc...
v2=malloc...
for (j=0;j<1000000;j++)
{
  v1[j]=0;
  v2[j]=0;
  ...
}

free(v1);
free(v2);

...
}
...

return;
}

-------------------------------------

Espero ter conseguido me fazer entender.

Voces podem me ajudar a esclerecer este "fenomeno"? Ou mesmo me dizer se existe algum tipo de "efeito"
quando um programa roda utilizando o "sys time"?

Obrigado





zekkerj

Oi mpoloureiro,

você pode estar experimentando "trashing" de memória.

A memória virtual é dividida em blocos de memória chamados "páginas". Quando você precisa usar mais memória do que a máquina tem, ela tira uma página da memória física e joga pra disco, em seguida pega outra página do disco e joga pra memória física.

Quando teu código tem loops, às vezes acontece que o loop fica todo rodando dentro de uma mesma página de memória. Isso faz com que o programa rode macio, sem muita paginação. Daí vc mexe em alguma coisa no código, e o loop fica em parte em uma página, e parte em outra. Resultado: o programa começa a paginar desesperadamente.

Outra coisa que pode estar acontecendo aí é que você, ao colocar o código dentro da sub-rotina, está forçando a criação de um registro de ativação novo, a cada chamada da sub-rotina. Essa operação tem um certo custo, pro sistema (tanto em termos de quantidade de memória quanto em termos de operações de paginação).

Nesse caso vc pode tentar forçar algumas otimizações em seu código, como usar essas variáveis locais como variáveis estáticas (cuidado com side effects!!!) ou, melhor, como variáveis "register", que não ocupam espaço no registro de ativação.
Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D

mpoloureiro

Citação de: zekkerj online 28 de Março de 2011, 23:31
Oi mpoloureiro,

você pode estar experimentando "trashing" de memória.

A memória virtual é dividida em blocos de memória chamados "páginas". Quando você precisa usar mais memória do que a máquina tem, ela tira uma página da memória física e joga pra disco, em seguida pega outra página do disco e joga pra memória física.

Quando teu código tem loops, às vezes acontece que o loop fica todo rodando dentro de uma mesma página de memória. Isso faz com que o programa rode macio, sem muita paginação. Daí vc mexe em alguma coisa no código, e o loop fica em parte em uma página, e parte em outra. Resultado: o programa começa a paginar desesperadamente.

Outra coisa que pode estar acontecendo aí é que você, ao colocar o código dentro da sub-rotina, está forçando a criação de um registro de ativação novo, a cada chamada da sub-rotina. Essa operação tem um certo custo, pro sistema (tanto em termos de quantidade de memória quanto em termos de operações de paginação).

Nesse caso vc pode tentar forçar algumas otimizações em seu código, como usar essas variáveis locais como variáveis estáticas (cuidado com side effects!!!) ou, melhor, como variáveis "register", que não ocupam espaço no registro de ativação.

Obrigado zekkerj!

Realmente, o problema é o loop da sub-rotina que cria o vetor via malloc. De fato, quando o programa faz uma alocação de um array via malloc, ele "pede" ao sistema que disponibilize tal quantidade de memoria. Este processo de solicitação demanda um certo tempo (sys time). Como o array está sendo criado em um loop, consequentemente o programa (que roda em "user time") recorre ao sistema diversas vezes  para aloca-lo.

A soluçao é simples. Criei o vetor fora da sub-rotina e entrei com ele nela como argumento.

Aqui tem um link que ajuda a entender o que é "real time", "sys time" e "user time" e a relação com malloc.

http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1

Muito obrigado