Problema de tiempo con memcpy.

Iniciado por SARGE553413, 24 Julio 2014, 18:16 PM

0 Miembros y 5 Visitantes están viendo este tema.

SARGE553413

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.

Eternal Idol

¿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
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

ivancea96

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.

SARGE553413

#3
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.

Eternal Idol

Seria mucho mejor que describieras el problema que estas tratando de resolver en lugar de la solucion  ;)
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

SARGE553413

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.

Eternal Idol

#6
¿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).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

SARGE553413

#7
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?

ivancea96

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?

Eternal Idol

#9
Cita de: SARGE553413 en 24 Julio 2014, 19:08 PMEntonces 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.

Cita de: SARGE553413 en 24 Julio 2014, 19:08 PMPensad 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.

Cita de: SARGE553413 en 24 Julio 2014, 19:08 PMEntonces 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.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón