Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: SARGE553413 en 24 Julio 2014, 18:16 pm



Título: Problema de tiempo con memcpy.
Publicado por: SARGE553413 en 24 Julio 2014, 18:16 pm
Hola a todos.

Estoy intentando desarrollar un programa que básicamente lo que tiene que hacer es un memcpy() cada cierto tiempo (tiempo muy bajo, 10 milis por ej.). La cantidad de memcpy() que hago la controlo con un contador, y el tiempo entre uno y otro con Sleep(). Siempre copio exactamente la misma cantidad de datos a memoria.

He comprobado que un memcpy() (junto con incrementar el contador) concreto cuesta hacerlo "0". Lo he probado con la librería <ctime>. Hago clock antes y después y, al imprimir la diferencia, da 0. También he imprimido los dos instantes (antes y después del memcpy y el incremento) y los dos son iguales.

Entonces por ej. si quiero que se realice dicho memcpy() cada 10 milis, en 3 segundos deberían hacerse 300 (o muy cerca de 300), pues a mí me salen 260.

No entiendo por qué pasa esto, ¿alguien puede ayudarme?

Gracias y saludos.

EDITO:
Un dato: ahora tengo el bucle para que, como máximo, haga 1024 veces memcpy(). Bien, si quito todo el delay (borro el Sleep()) llega a los 1024.
Y si le pongo Sleep(10) solo 260. No tiene sentido.


Título: Re: Problema de tiempo con memcpy.
Publicado por: Eternal Idol en 24 Julio 2014, 18:32 pm
¿Estas tratando de hacer algo que requeriria un S.O. de tiempo real? En los S.O. modernos que solemos usar casi todos no tenes posibilidad de asegurate que algo se vaya a ejecutar en X tiempo, son multitarea, tu programa se ejecuta junto a muchos otros  ... y cuando llamas a Sleep le das prioridad a otros procesos explicitamente.

http://en.wikipedia.org/wiki/Real_time_os


Título: Re: Problema de tiempo con memcpy.
Publicado por: ivancea96 en 24 Julio 2014, 18:40 pm
lo que puedes hacer, es un for para controlar el número de veces que lo haces. Dentro del for, el sleep y el memcpy.


Título: Re: Problema de tiempo con memcpy.
Publicado por: SARGE553413 en 24 Julio 2014, 18:41 pm
Entonces lo que trato de hacer es imposible ¿cierto?.

Supongo que lo único que podría hacer es buscar la manera de ajustar el valor del Sleep() (reduciéndolo) para llegar al valor que necesito, pero tiene pinta de ser muy complicado, porque unas veces serán 10 milis, otras 30, otras 50... además, por lo que entiendo, no puedo preveer cuantos procesos estarán activos en el sistema etc. así que no puedo saber como ajustar ese valor, ¿me equivoco?

¿Hay alguna manera mejor de hacerlo que con Sleep()?

Grcias y saludos.

EDITO: he probado a cambiar el while() por un for() pero me da la misma cantidad de operaciones. Gracias de todas formas.


Título: Re: Problema de tiempo con memcpy.
Publicado por: Eternal Idol en 24 Julio 2014, 18:42 pm
Seria mucho mejor que describieras el problema que estas tratando de resolver en lugar de la solucion  ;)


Título: Re: Problema de tiempo con memcpy.
Publicado por: SARGE553413 en 24 Julio 2014, 18:50 pm
Ok, el problema es:

Tengo una cámara híper-espectral que hace fotos de una resolución 240x360 píxels, a 2 bytes por píxel.

Se supone que, como máximo, funciona a 100 fps pero en realdiad va a unos 95-96.

El caso es que (y esto lo he hablado con el fabricante), una vez se le da la orden de capturar (cam->StartCapture()) se pone a capturar imágenes al máximo de lo que puede (100 fps teóricos)

A mí me piden, entre otras cosas, regular los fps que da la cámara, para ello lo que hago es copiar desde la memoria de la cámara a la del pc (con memcpy) cada cierto tiempo (Sleep() ).

Y ese es el problema.

Saludos.


Título: Re: Problema de tiempo con memcpy.
Publicado por: Eternal Idol en 24 Julio 2014, 19:04 pm
¿El output del programa es una X cantidad de imagenes por segundo? Entiendo que sos capaz de capturar unas 95/96 imagenes por segundo, si esto es correcto entonces podrias capturar todas esas imagenes en memoria (96 * 240 * 360 * 2 son un poco menos de 16 MB) y despues descartar - no escribirlas en disco - las que sean necesarias para llegar al FPS configurado. El bucle lo que haria es capturar sin parar y al llegar al numero de FPS por segundo segun el hardware con lo que hay en memoria se estableceria el output (imagenes 1, 20, 50, 70, etc. por poner un ejemplo).


Título: Re: Problema de tiempo con memcpy.
Publicado por: SARGE553413 en 24 Julio 2014, 19:08 pm
En realidad, al final, la salida será una sola imagen .raw (escrita en disco) generada a partir de las 'x' imágenes anteriormente mencionadas. Esta es una de las "piezas" del programa final si.
No se como se hará, pero se tiene que poder creo yo porque la cámara trae su propio software de captura, y me imagino que lo hará bien. (El motivo por el cual no usar ese software es porque hay que sincronizar el funcionamiento de una cámara con otra de otro fabricante)

Entonces lo que sugieres es que en lugar de añadir un delay capture todas las imágenes a tope y luego descarte las que sobren. Solo hay un problema y es que si elimino por completo el delay, el programa copia cientos de veces la misma captura, es decir: Ahora mismo la cantidad máxima de imágenes que puedo coger es 1024 (por un parámetro). Bien, si quito el delay la cámara en 3 segundos tendrá unas 95*3 imágenes, yo en memoria tengo 1024, es decir muchas repetidas.

Entonces como se cual quitar y cual no, porque además:

Pensad que la cantidad de imágenes que yo "cojo" ya no viene determinada por la cantidad de fps que tiene la cámara, si no por la velocidad del PC, y cuando alcanzo el tamaño máximo de mi buffer dejo de coger imágenes. Entonces puede ser que coja las 1024 imágenes en los primeros 1.5 segundos y luego nada.

PD:
Entonces una pregunta, si yo hago Sleep(10), esa función no me GARANTIZA que el proceso va a retomar su ejecución en 10 milisegundos ¿cierto?
Y esto es porque al suspender la ejecución de un hilo, otros entran a la CPU y la dejarán libre no se sabe cuando ¿correcto?


Título: Re: Problema de tiempo con memcpy.
Publicado por: ivancea96 en 24 Julio 2014, 19:12 pm
Van a ser aproximadamente 10ms, si es lo que le pides al Sleep. Pero muchos sleeps encadenados, acaban acarreando tiempo perdido en la llamada al sleep, y otros factores como comentó EI.

Pero nada es perfecto xD
Quizás tengas otra manera de sincronizar la cámara con el programa. ¿No tienes alguna forma de saber cuando la cámara ha sacado una fotografía?


Título: Re: Problema de tiempo con memcpy.
Publicado por: Eternal Idol en 24 Julio 2014, 19:15 pm
Entonces lo que sugieres es que en lugar de añadir un delay capture todas las imágenes a tope y luego descarte las que sobren. Solo hay un problema y es que si elimino por completo el delay, el programa copia cientos de veces la misma captura, es decir: Ahora mismo la cantidad máxima de imágenes que puedo coger es 1024 (por un parámetro). Bien, si quito el delay la cámara en 3 segundos tendrá unas 95*3 imágenes, yo en memoria tengo 1024, es decir muchas repetidas.
Entonces como se cual quitar y cual no.

Podrias descartar con memcmp, si son exactamente iguales, al llegar a X (100 por ejemplo) ya podrias descartar X - FPS, aunque como bien dice ivancea96 deberias ser capaz de saber cuando una foto es tomada.

Pensad que la cantidad de imágenes que yo "cojo" ya no viene determinada por la cantidad de fps que tiene la cámara, si no por la velocidad del PC, y cuando alcanzo el tamaño máximo de mi buffer dejo de coger imágenes. Entonces puede ser que coja las 1024 imágenes en los primeros 1.5 segundos y luego nada.

Tenes que descartar las imagenes de una alguna manera, no podes seguir acumulando por siempre de ninguna forma.

Entonces una pregunta, si yo hago Sleep(10), esa función no me GARANTIZA que el proceso va a retomar su ejecución en 10 milisegundos ¿cierto?
Y esto es porque al suspender la ejecución de un hilo, otros entran a la CPU y la dejarán libre no se sabe cuando ¿correcto?

No, no lo garantiza, Windows no es un S.O. de tiempo real.


Título: Re: Problema de tiempo con memcpy.
Publicado por: ivancea96 en 24 Julio 2014, 19:19 pm
Así un método que puedes usar, es, al inicio, establecer un clock().
Luego, en vez de hacer Sleep() esperando 10 ms, hacer otro clock() y comparar si este último es el anterior+10 o superior. No se si me expliqué bien.

Código
  1. if(clock()>=clock_inicial+10*contador){
  2.    ++contador;
  3.    //Función
  4. }

Eso metido en un while quizás sea una solución.

En cualquier caso, revisa si la cámara te avisa al sacar foto.


Título: Re: Problema de tiempo con memcpy.
Publicado por: SARGE553413 en 24 Julio 2014, 19:52 pm
Lo único que me permite la cámara es "preguntarle" si está capturando (isCampturing()), pero saber cuando echa cada foto que yo vea no.

Hay otro método en la api que se llama captureImage() pero que en lugar de darme una imagen de 320*256*2 bytes me da solo 6, y todo ceros.

Sigo en ello...


Título: Re: Problema de tiempo con memcpy.
Publicado por: ivancea96 en 24 Julio 2014, 20:20 pm
¿Probaste con ese code para calcular el tiempo?


Título: Re: Problema de tiempo con memcpy.
Publicado por: SARGE553413 en 24 Julio 2014, 21:46 pm
Con "isCapturing()"? No se como calcular el tiempo con eso, una vez le das a startCapture() ya no para hasta que le das a stopCapture().


Título: Re: Problema de tiempo con memcpy.
Publicado por: ivancea96 en 24 Julio 2014, 22:13 pm
No, con el snippet que te dejé. Es para poner tiempos lo más precisos posibles.


Título: Re: Problema de tiempo con memcpy.
Publicado por: SARGE553413 en 25 Julio 2014, 12:38 pm
Ok gracias a todos por las respuestas.

Pero lo he solucionado de otra forma, eh conseguido usar una API mas moderna (que hasta ahora no había sido capaz de hacer funcionar por ciertos motivos) que tiene ejemplos mucho mejores y sobre todo una función getFrame() que permite mediante un parámetro pillar frames "nuevos". Es decir, le das a getFrame() y el programa se queda ahí esperando hasta que la cámarra le dice que ya tiene un frame nuevo, de tal manera que ya no pillo frames replicados. Intentaré seguir por ese camino.

Gracias de nuevo a todos, saludos.