Pergunta

EDITAR: Eu só encontrei o meu problema, depois de escrever este longo post explicando cada pequeno detalhe...Se alguém puder me dar uma boa resposta sobre o que eu estou fazendo de errado e como posso obter o tempo de execução em segundos (utilizando um flutuador com 5 casas decimais ou assim), eu vou marcar que, como aceites.Dica:O problema era como eu interpretei o clock_getttime() na página de manual.

Olá,

Vamos dizer que eu tenho uma função chamada myOperation o que eu preciso para medir o tempo de execução.Para medir isso, eu estou usando clock_gettime() como era recomendo aqui em um dos comentários.

Meu professor recomenda-nos a medida N vezes, para que possamos obter uma média, desvio padrão e mediana para o relatório final.Ele também recomenda-nos executar myOperation M vezes em vez de apenas um.Se myOperation é uma operação muito rápida, medição M vezes nos permitem ter uma noção do "tempo real" é preciso;causa o relógio a ser usado pode não ter a precisão necessária para medir-se a tal operação.Assim, a execução myOperation apenas uma vez ou M os tempos realmente depende se a operação demora tempo suficiente para que o relógio de precisão que estamos utilizando.

Estou tendo problemas para lidar com isso M os tempos de execução.Aumentar M diminui (e muito) a média final valor.O que não faz sentido para mim.É assim, em média, de 3 a 5 segundos para viajar do ponto a ao B.Mas, em seguida, você vai de a para B e de volta para Uma 5 vezes, o que a torna 10 vezes, causa de a para B, é o mesmo que B para A) e medida.Do que você dividir por 10, a média de que você é suposto para ser a mesma média, você leva a viajar do ponto a para o B, que é de 3 a 5 segundos.

Isso é o que eu quero que o meu código para fazer, mas ele não está funcionando.Se eu continuar a aumentar o número de vezes que vou de a para B e de volta Uma, a média será cada vez menor, não faz nenhum sentido para mim.

Chega de teoria, aqui está o meu código:

#include <stdio.h>
#include <time.h>

#define MEASUREMENTS 1
#define OPERATIONS   1

typedef struct timespec TimeClock;

TimeClock diffTimeClock(TimeClock start, TimeClock end) {
    TimeClock aux;

    if((end.tv_nsec - start.tv_nsec) < 0) {
        aux.tv_sec = end.tv_sec - start.tv_sec - 1;
        aux.tv_nsec = 1E9 + end.tv_nsec - start.tv_nsec;
    } else {
        aux.tv_sec = end.tv_sec - start.tv_sec;
        aux.tv_nsec = end.tv_nsec - start.tv_nsec;
    }

    return aux;
}

int main(void) {
    TimeClock sTime, eTime, dTime;
    int i, j;

    for(i = 0; i < MEASUREMENTS; i++) {
        printf(" » MEASURE %02d\n", i+1);

        clock_gettime(CLOCK_REALTIME, &sTime);

        for(j = 0; j < OPERATIONS; j++) {
            myOperation();
        }

        clock_gettime(CLOCK_REALTIME, &eTime);

        dTime = diffTimeClock(sTime, eTime);

        printf("   - NSEC (TOTAL): %ld\n", dTime.tv_nsec);
        printf("   - NSEC (OP): %ld\n\n", dTime.tv_nsec / OPERATIONS);
    }

    return 0;
}

Notas: Acima diffTimeClock função é a partir desta post de blog.Troquei a minha verdadeira operação com myOperation() porque não faz qualquer sentido para postar minhas funções reais como eu teria que post longo blocos de código, você pode facilmente código de um myOperation() com tudo o que você gostaria de compilar o código, se você desejar.

Como você pode ver, OPERATIONS = 1 e os resultados são:

 » MEASURE 01
   - NSEC (TOTAL): 27456580
   - NSEC (OP): 27456580

Para OPERATIONS = 100 os resultados são:

 » MEASURE 01
   - NSEC (TOTAL): 218929736
   - NSEC (OP): 2189297

Para OPERATIONS = 1000 os resultados são:

 » MEASURE 01
   - NSEC (TOTAL): 862834890
   - NSEC (OP): 862834

Para OPERATIONS = 10000 os resultados são:

 » MEASURE 01
   - NSEC (TOTAL): 574133641
   - NSEC (OP): 57413

Agora, eu não sou um mago da matemática, longe disso, na verdade, mas isso não faz qualquer sentido para mim.Eu já falei sobre isso com um amigo que neste projeto comigo e ele também não pode compreender as diferenças.Eu não entendo por que o valor está ficando menor e menor, quando eu aumentar OPERATIONS.A operação em si deve demorar o mesmo tempo (em média, claro, não exatamente o mesmo tempo), não importa quantas vezes eu executá-lo.

Você poderia me dizer o que na verdade depende de que a operação em si, os dados que estão sendo lidos e que alguns dados já poderia estar no cache e bla bla, mas eu não acho que é o problema.No meu caso, myOperation é a leitura de 5000 linhas de texto a partir de um arquivo CSV, separando os valores por ; e inserir esses valores em uma estrutura de dados.Para cada iteração, estou destruindo a estrutura de dados e inicializar novamente.

Agora que penso nisso, eu também que acho que há um problema de medir o tempo com clock_gettime(), talvez eu não estou usando-o para a direita.Quero dizer, olhe para o último exemplo, onde OPERATIONS = 10000.O tempo total foi 574133641ns, o que seria cerca de 0,5 s;isso é impossível, ele levou um par de minutos, como eu não podia ficar olhando para a tela de espera e fui comer algo.

Foi útil?

Solução

Você só precisa mudar seu diffTimeClock() função para retornar o número de segundos diferença, como um double:

double diffTimeClock(TimeClock start, TimeClock end) {
    double diff;

    diff = (end.tv_nsec - start.tv_nsec) / 1E9;
    diff += (end.tv_sec - start.tv_sec);

    return diff;
}

e na principal mudança de rotina dTime para um double, e os printfs para se adequar:

printf("   - SEC (TOTAL): %f\n", dTime);
printf("   - SEC (OP): %f\n\n", dTime / OPERATIONS);

Outras dicas

Parece que o tipo de cronômetro possui dois campos, um por segundos e outro para nanossegundos. Não faz sentido apenas dividir o campo Nanosec com o número de operações. Você precisa dividir o tempo total.

Se você estiver usando um sistema POSIX onde houver gettimeofday (), poderá usar algo assim para obter o horário atual em microssegundos:

long long timeInMicroseconds(void) {
    struct timeval tv;

    gettimeofday(&tv,NULL);
    return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
}

A razão pela qual isso é muito útil é que, para calcular quanto sua função levou, você precisa fazer exatamente isso:

long long start = timeInMicroseconds();
... do your task N times ...
printf("Total microseconds: %lld", timeInMicroseconds()-start);

Portanto, você não precisa lidar com dois números inteiros, um com segundos e outro com microssegundos. Adicionar e subtrair tempos funcionarão de uma maneira óbvia.

Eu geralmente uso a função time() para isso.Ele mostra o relógio de parede do tempo, mas o que eu realmente importam no final.

Uma pegadinha com o teste de desempenho é o sistema operacional pode ficheiro de cache do sistema de operações relacionadas.Assim, a segunda (e mais tarde) executado pode ser muito mais rápido do que o primeiro.Você geralmente precisa de teste pode operações e a média do resultado para obter uma boa sensação para os resultados de quaisquer alterações efectuadas.Existem muitas variáveis que isso pode ajudar você a filtrar o ruído.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top