Pregunta

EDIT: que acabo de encontrar mi problema después de escribir este largo post explicando todos los detalles ... Si alguien me puede dar una buena respuesta en lo que estoy haciendo mal y cómo puedo obtener el el tiempo de ejecución en segundos (utilizando un flotador con 5 decimales o menos), voy a marcar que a medida aceptada. Pista:. El problema estaba en cómo interpreté la página del manual clock_getttime ()

Hola,

Vamos a decir que tengo una función llamada myOperation que necesito para medir el tiempo de ejecución. Para medirlo, estoy usando clock_gettime() como lo fue recomendar aquí en uno de los comentarios.

Mi maestro nos recomienda medirlo N veces, así que podemos hacer una, desviación estándar promedio y la mediana para el informe final. También recomienda que nosotros ejecutamos veces myOperation M en lugar de sólo uno. Si myOperation es una operación muy rápida, midiéndolo M veces nos permiten tener una idea de la "tiempo real" que se necesita; hacer que el reloj que se utiliza tal vez no tienen la precisión necesaria para medir dicha operación. Por lo tanto, la ejecución myOperation sólo un momento o momentos M realmente depende si la operación en sí toma tiempo suficiente para que la precisión del reloj que estamos usando.

Estoy teniendo problemas para lidiar con tiempos de ejecución que M. El aumento de M disminuye (mucho) el valor promedio final. Lo que no tiene sentido para mí. Es así, en promedio se toma de 3 a 5 segundos en recorrer desde el punto A al punto B. Pero entonces se pasa de A a B y de vuelta a A 5 veces (lo que lo hace 10 veces, la causa de A a B es lo mismo que B a a) y que se mide. Que se divide por 10, la media se obtiene se supone que es el mismo promedio que toma, viajar del punto A al B, que es de 3 a 5 segundos.

Esto es lo que yo quiero que mi código para hacer, pero que no está funcionando. Si sigo aumentando el número de veces Desplazamiento de A a B y de vuelta A, el promedio será menor y bajar cada vez, no tiene sentido para mí.

Suficiente teoría, aquí está mi 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: rel La función diffTimeClock arriba es de este entrada de blog . He reemplazado mi verdadera operación con myOperation(), ya que no tiene ningún sentido para publicar mis funciones reales que tendría que publicar largos bloques de código, puede codificar fácilmente un myOperation() con lo que desee para compilar el código si lo desea.

Como se puede ver, OPERATIONS = 1 y los resultados son los siguientes:

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

Para OPERATIONS = 100 los resultados son los siguientes:

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

Para OPERATIONS = 1000 los resultados son los siguientes:

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

Para OPERATIONS = 10000 los resultados son los siguientes:

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

Ahora, yo no soy un genio de las matemáticas, ni mucho menos en realidad, pero esto no tiene ningún sentido para mí en absoluto. Ya he hablado de esto con un amigo que está en este proyecto conmigo y él también no puedo entender las diferencias. No entiendo por qué el valor es cada vez más bajo cuando puedo aumentar OPERATIONS. La operación en sí debe tomar al mismo tiempo (en promedio por supuesto, no exactamente el mismo tiempo), no importa cuántas veces me ejecutarlo.

Se podría decirme que que realmente depende de la operación en sí, que los datos sean leídos y que algunos datos podrían estar ya en la caché y bla bla, pero no creo que ese es el problema. En mi caso, myOperation es la lectura de 5000 líneas de texto de un archivo CSV, separando los valores por ; y la inserción de esos valores en una estructura de datos. Para cada iteración, estoy destruyendo la estructura de datos e inicializar de nuevo.

Ahora que lo pienso, yo también creo que hay que'S de un tiempo de medición clock_gettime() problema, tal vez no lo estoy usando derecha. Es decir, mira en el último ejemplo, donde OPERATIONS = 10000. El tiempo total que tomó fue 574133641ns, lo que sería más o menos 0,5 s; eso es imposible, se tomó un par de minutos ya que no podía estar de pie mirando a la pantalla de espera y se fue a comer algo.

¿Fue útil?

Solución

Sólo tiene que cambiar su función diffTimeClock() para devolver el número de segundos de diferencia, como 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;
}

y en el principal cambio de rutina dTime a un double, y los printfs para adaptarse:

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

Otros consejos

Parece que el tipo Timeclock tiene dos campos, uno para el segundo y uno para nanosegundos. No tiene sentido para simplemente dividir el campo de nanosegundos con el número de operaciones. Es necesario dividir el tiempo total.

Si está utilizando un sistema POSIX donde hay gettimeofday () la función se puede usar algo como esto para obtener la hora actual en microsegundos:

long long timeInMicroseconds(void) {
    struct timeval tv;

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

La razón por la que esto es muy práctico es que el fin de calcular la cantidad de su función se necesita para hacer precisamente esto:

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

Así que usted no tiene que lidiar con dos números enteros, uno con segundos y una con microsegundos. Adición y resta de horas trabajarán de manera obvia.

I generalmente utilizar la función de tiempo () para esto. Se muestra el tiempo de reloj de pared, pero eso es realmente lo que importa al final.

Uno de gotcha con pruebas de rendimiento es el sistema operativo puede almacenar en caché del sistema de archivos operaciones relacionadas. Así que la segunda (y posteriores) carreras pueden ser mucho más rápido que la primera ejecución. Por lo general, necesita prueba puede operaciones y el promedio del resultado para obtener una buena idea de los resultados de los cambios que realice. Hay tantas variables que esto puede ayudar a filtrar el ruido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top