Pregunta

Estoy planeando implementar un sistema de adquisición de datos a pequeña escala en una plataforma RTOS. (Ya sea en un sistema QNX o RT-Linux).

Hasta donde yo sé, estos trabajos se realizan usando C / C ++ para aprovechar al máximo el sistema. Sin embargo, tengo curiosidad por saber y quiero conocer las opiniones de algunas personas experimentadas antes de saltar ciegamente a la acción de la codificación si sería factible y más inteligente escribir todo en Python (desde una interfaz gráfica de usuario de bajo nivel a través de una interfaz gráfica de usuario brillante). Si no, mezcle con partes críticas del tiempo del diseño con "C", o escriba todo en C y ni siquiera ponga una línea de código Python.

O al menos envolver el código C usando Python para proporcionar un acceso más fácil al sistema.

¿En qué forma me aconsejarías trabajar? Me alegraría si señala algunos casos de diseño similares y otras lecturas también.

Gracias

NOTA1: La razón de enfatizar QNX se debe a que ya tenemos un sistema de adquisición de datos basado en QNX 4.25 ( M300 ) para nuestros experimentos de medición atmosférica. Este es un sistema propietario y no podemos acceder a su parte interna. Ver más allá de QNX podría ser ventajoso para nosotros ya que 6.4 tiene una opción de licencia académica gratuita, viene con Python 2.5 y una versión reciente de GCC. Nunca he probado un sistema RT-Linux, no sé qué tan comparable es a QNX en términos de estabilidad y eficiencia, pero sé que todos los miembros del hábitat Python y las herramientas que no son Python (como Google Earth) que el nuevo sistema podría desarrollarse en trabajos la mayor parte del tiempo fuera de la caja.

¿Fue útil?

Solución

No puedo hablar de cada configuración de adquisición de datos que hay, pero la mayoría de ellos gasta la mayoría de sus "operaciones en tiempo real". esperando para que lleguen los datos, al menos en los que he trabajado.

Luego, cuando ingresan los datos no , debe registrar inmediatamente el evento o responder a él, y luego volver al juego en espera. Esa es típicamente la parte más crítica del tiempo de un sistema de adquisición de datos. Por esa razón, diría generalmente quédese con C para las partes de E / S de la adquisición de datos, pero no hay razones particularmente convincentes para no usar Python en las partes que no son críticas para el tiempo .

Si tiene requisitos bastante flexibles, solo necesita una precisión de milisegundos, tal vez, eso agrega más peso para hacer todo en Python. En lo que respecta al tiempo de desarrollo, si ya está cómodo con Python, probablemente tendría un producto terminado mucho antes si tuviera que hacer todo en Python y refactorizarlo solo cuando aparecen cuellos de botella. Hacer la mayor parte de su trabajo en Python también facilitará la prueba exhaustiva de su código, y como regla general, habrá menos líneas de código y, por lo tanto, menos espacio para los errores.

Si necesita específicamente la tarea múltiple (no el subproceso ), Stackless Python también puede ser beneficioso. Es like multi-threading, pero los subprocesos (o tasklets, en la jerga Stackless) no son subprocesos de nivel de sistema operativo, sino Python / nivel de aplicación, por lo que la sobrecarga de cambiar entre tasklets es significativamente reducido. Puede configurar Stackless para realizar múltiples tareas de forma cooperativa o preventiva. El mayor inconveniente es que el bloqueo de IO generalmente bloqueará todo su conjunto de tasklets. De todos modos, considerando que QNX ya es un sistema en tiempo real, es difícil especular si valdría la pena usar Stackless.

Mi voto sería tomar la ruta de Python tanto como sea posible, lo veo como de bajo costo y alto beneficio. Si y cuando necesite volver a escribir en C, ya tendrá un código de trabajo para comenzar.

Otros consejos

He construido varios sistemas de tiempo real (RT) todo en Python, con tiempos de ciclo primario de 1 ms a 1 segundo. Hay algunas estrategias y tácticas básicas que he aprendido a lo largo del camino:

  1. Utilice subprocesamiento / multiprocesamiento only para descargar el trabajo que no sea RT del subproceso primario, donde las colas entre subprocesos son aceptables y es posible el subprocesamiento cooperativo (no es preventivo hilos!).

  2. Evita el GIL. Lo que básicamente significa no solo evitar los subprocesos, sino también evitar las llamadas al sistema en la mayor medida posible, especialmente durante las operaciones de tiempo crítico, a menos que no sean de bloqueo.

  3. Use módulos C cuando sea práctico. ¡Las cosas (usualmente) van más rápido con C! Pero principalmente si no tiene que escribir lo suyo: permanezca en Python a menos que realmente no haya alternativa. La optimización del rendimiento del módulo C es un PITA, especialmente cuando la traducción a través de la interfaz Python-C se convierte en la parte más cara del código.

  4. Usa aceleradores de Python para acelerar tu código. Mi primer proyecto de RT Python se benefició enormemente de Psyco (sí, he estado haciendo esto por un tiempo). Una razón por la que me quedo con Python 2.x hoy es PyPy: las cosas siempre van más rápido con LLVM!

  5. No tengas miedo de esperar ocupado cuando se necesita un momento crítico. Use time.sleep () para 'acercarse' a la hora deseada, luego espere ocupado durante los últimos 1-10 ms. He podido obtener un rendimiento repetible con temporización automática del orden de 10 microsegundos. Asegúrese de que su tarea de Python se ejecute con la máxima prioridad del sistema operativo.

  6. ROCKS Numpy! Si está haciendo análisis "en vivo" o toneladas de estadísticas, hay una forma NO de hacer más trabajo más rápido y con menos trabajo (menos código, menos errores) que utilizando Numpy. No en ningún otro idioma que conozca, incluido C / C ++. Si la mayoría de tu código consiste en llamadas Numpy, serás muy, muy rápido. ¡No puedo esperar a que se complete el puerto Numpy a PyPy!

  7. Sé consciente de cómo y cuándo Python realiza la recolección de basura. Controle el uso de su memoria y fuerce el GC cuando sea necesario. Asegúrese de desactivar explícitamente el GC durante las operaciones de tiempo crítico. Todos mis sistemas RT Python se ejecutan de forma continua, ya Python le encanta acaparar la memoria. La codificación cuidadosa puede eliminar casi toda la asignación de memoria dinámica, ¡en cuyo caso puede deshabilitar completamente GC!

  8. Intente realizar el procesamiento en lotes en la mayor medida posible. En lugar de procesar datos a la tasa de entrada, intente procesar datos a la tasa de salida, que a menudo es mucho más lenta. El procesamiento en lotes también hace que sea más conveniente recopilar estadísticas de nivel superior.

  9. ¿Mencioné el uso de PyPy? Bueno, vale la pena mencionarlo dos veces.

Hay muchos otros beneficios de usar Python para el desarrollo de RT. Por ejemplo, incluso si está bastante seguro de que su idioma de destino no puede ser Python, puede generar enormes beneficios desarrollar y depurar un prototipo en Python, luego utilizarlo como plantilla y herramienta de prueba para el sistema final. Había estado usando Python para crear prototipos rápidos de las " partes duras " de un sistema durante años, y para crear GUI de prueba rápida y rápida. Así es como nació mi primer sistema RT Python: ¡el prototipo (+ Psyco) fue lo suficientemente rápido, incluso con la GUI de prueba en ejecución!

-BobC

Editar: Olvidé mencionar los beneficios multiplataforma: mi código se ejecuta prácticamente en todas partes con a) sin recompilación (o dependencias del compilador, o la necesidad de compiladores cruzados), yb) casi ningún código dependiente de la plataforma (principalmente para Cosas misceláneas como manejo de archivos y E / S en serie). Puedo desarrollar en Win7-x86 e implementar en Linux-ARM (o cualquier otro sistema operativo POSIX, todos los cuales tienen Python en estos días). PyPy es principalmente x86 por ahora, pero el puerto ARM está evolucionando a un ritmo increíble.

En general, la razón avanzada para usar un lenguaje de alto nivel en un contexto en tiempo real es incertidumbre : cuando ejecuta una rutina, una vez puede llevar 100us; la próxima vez que ejecute la misma rutina, puede decidir extender una tabla hash, llamar a malloc, luego malloc le pide al kernel más memoria, lo que podría hacer cualquier cosa, desde regresar instantáneamente hasta devolver milisegundos más tarde y devolver segundos más tarde a error, ninguno de los cuales es inmediatamente aparente (o controlable) del código. Mientras que en teoría, si escribes en C (o incluso más bajo), puedes probar que tus rutas críticas " siempre " (a menos que se produzca una huelga de meteoros) ejecutarse en X.

Nuestro equipo ha realizado algunos trabajos combinando varios idiomas en QNX y tuvo mucho éxito con el enfoque. El uso de python puede tener un gran impacto en la productividad, y herramientas como SWIG y los ctypes hacen que sea muy fácil optimizar el código y combina características de los diferentes idiomas.

Sin embargo, si está escribiendo algo crítico en el tiempo, casi seguro debería escribirse en c. Hacer esto significa evitar los costos implícitos de un lenguaje interpretado como el GIL ( Global Interpreter Lock ) y contention en muchas asignaciones de memoria pequeña. Ambas cosas pueden tener un gran impacto en el rendimiento de su aplicación.

También python en QNX tiende a no ser 100% compatible con otras distribuciones (es decir, / a veces faltan módulos).

Una nota importante: Python para QNX generalmente está disponible solo para x86.

Estoy seguro de que puedes compilarlo para ppc y otros archs, pero eso no va a funcionar fuera de la caja.

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