¿Progtwig rápido de C ++, C # GUI, posible?

Estoy estudiando el desarrollo de una aplicación que procesará datos desde una cámara de escaneo de líneas a aproximadamente 2000 líneas (cuadros) por segundo. Para esta aplicación en tiempo real, creo que C / C ++ es el camino a seguir. (Es mi opinión, y otros estarán de acuerdo en que el código administrado no es el adecuado para esta tarea).

Sin embargo, he hecho muy poco MFC, o cualquier otra GUI de C ++. Aunque realmente estoy logrando hacer GUIs de C # muy bien.

Así que me parece natural escribir el código de uso intensivo de datos en C / C ++ y la GUI en C #. La GUI se usará para la configuración / calibración / monitoreo en línea (y posiblemente la salida de datos a través de UDP, porque es más fácil en C #).

Así que primero, me gustaría ver si alguien está de acuerdo en que este sería el camino a seguir. Basado en mi experiencia de progtwigción (bueno en algoritmos de C de bajo nivel y diseño de GUI de C # de alto nivel), se siente bien.

En segundo lugar, no estoy seguro de la forma correcta de hacerlo. Acabo de encontrar una solución en VS2005, que llama a algunas funciones DLL (externas “C”) desde una aplicación de C #. Y para asegurarme de que podía hacerlo, escribí sobre algunas variables globales en la DLL, y leí:

prueba.h

int globaldata; extern "C" __declspec(dllexport) void set(int); extern "C" __declspec(dllexport) int get(); 

test.cpp

 extern int data=0; __declspec(dllexport) void set(int num) { data = num; } __declspec(dllexport) int get() { return data; } 

test.cs

 [DllImport("test")] private static extern void set(int num); [DllImport("test")] private static extern int get(); 

Las llamadas a get() y set() funcionan correctamente ( get() devuelve el número que pasé a set() ).

Ahora, sé que también puede exportar una clase de C ++, pero ¿tiene que ser administrada? ¿Cómo funciona? ¿Voy a hacer esto de la manera correcta?

¡Gracias por toda tu ayuda!

*** EDIT ***

En primer lugar, ¡ GRACIAS por sus fantásticas respuestas hasta ahora! Siempre estoy increíblemente impresionado con Stack Overflow …

Supongo que una cosa que debería haber golpeado más, no fue necesariamente la velocidad bruta (esto puede ser un prototipo y un punto de referencia). Una cosa que me preocupa más es el comportamiento no determinista del recolector de basura. Esta aplicación no toleraría un retraso de 500 ms al realizar la recolección de basura.

Estoy a favor de la encoding y el bash de esto en C # puro, pero si sé de antemano que el GC y cualquier otro comportamiento no determinista de .NET (?) Causará un problema, creo que sería mejor emplear mi tiempo en codificarlo. C / C ++ y descubrir la mejor interfaz de C #.

    No hay razón para que no pueda escribir código de alto rendimiento completamente en C #.

    • Rendimiento (Guía de progtwigción C #)

    • Blog de rendimiento de Rico Mariani (un excelente recurso)

    • Ajuste de rendimiento de aplicaciones .NET

    SO preguntas sobre el mismo tema / similar:

    • Rendimiento de C ++ vs. Java / C #
    • ¿Cuánto más rápido es c ++ que c #?

    Otros articulos:

    • Microbenchmarking C ++, C # y Java
    • Aproveche las características de C # para impulsar sus proyectos de computación científica
    • Buscar cuellos de botella de la aplicación con Visual Studio Profiler
    • Debunking C # vs C ++ Performance

    En mi opinión, su solución es sólida:

    1. A pesar de que C # es rápido, nunca puede competir con un C / C ++ bien escrito y no administrado, he hecho aplicaciones de alto rendimiento que lo demuestran más allá de los pequeños ejemplos que la gente siempre publica cuando alguien publica este tipo de declaraciones.
    2. La progtwigción de la interfaz de usuario de MFC o ATL es complicada y lenta, C # es el camino a seguir aquí, NUNCA haré la progtwigción de la interfaz de usuario de MFC / ATL otra vez, a menos que sea forzado a

    Su solución, en caso de que aún no lo haya descubierto, se llama “Modo mixto”, lo que básicamente significa que combina el código administrado (C #) y no administrado (C / C ++) en los mismos proyectos, a menudo es un poco de una molestia para poner en marcha el proyecto VS (errores LNK2020..argh ..) pero cuando encuentre la configuración correcta, debería funcionar bien.

    Lo único negativo es que los ensamblados de modo mixto deben ejecutarse en plena confianza, si eso está bien, entonces supongo que sabes qué hacer.

    Otra cosa que debería considerar es un proyecto de código abierto llamado SWIG . SWIG toma su código C / C ++ y crea un ensamblado .NET a partir de él. Lo he usado yo mismo en mi proyecto de código abierto TM ++ . Consulte aquí para obtener más información sobre SWIG http://www.swig.org/ .

    Para aplicaciones en tiempo real: recomiendo C ++, serás más flexible con la administración de memoria, más rápido e incluso multiplataforma, dependiendo de qué marco se use …!

    Sobre framework y GUI, te recomiendo que eches un vistazo a Qt . Qt es un gran marco para el desarrollo de software C ++.

    ¡Supongo que es la solución a tu problema!

    Lo primero que debe hacer es probar su suposición . ¿Cuáles son sus limitaciones de rendimiento? ¿Qué tipo de hardware espera para alojar la aplicación? Escriba un pequeño progtwig en C # que aborde el problema central y mida la velocidad con la que se ejecuta.

    Solo una vez que tenga los hechos podrá tomar una decisión sobre si usar o no C / C ++ en una solución administrada.

    Junto con otros que han comentado, sospecho que una solución C # / administrada funcionará bien, especialmente si utiliza las Extensiones Paralelas de .NET .

    Si terminas yendo por la ruta C / C ++, hay dos opciones para interoperar, a saber, pInvoke y COM interop . No creo que haya una forma limpia de acceder a clases de C ++ no administradas directamente desde .NET; para este fin, debería considerar la implementación de un ensamblado de C ++ administrado / no administrado .

    Mi compañía hace algo muy similar, aunque con cámaras CCD en lugar de cámaras de escaneo de línea. Estamos utilizando C # para la GUI, comunicación de red, “plomería” de alto nivel y C ++ / CLI para los algoritmos de bajo nivel. Funciona bastante bien. Nunca podrá escribir un verdadero sistema en tiempo real con tiempos de respuesta máximos garantizados en Windows, pero según mi experiencia, el GC será el menor de sus problemas aquí. Por un lado, el GC solo se ejecuta cuando asignas memoria; también lo hace malloc / new en C / C ++, y también necesitan tiempo (piense en la fragmentación de la memoria). A partir de las mediciones que hemos realizado, un GC completo toma 10-50ms y no necesariamente detendrá los otros subprocesos durante ese tiempo (a menos que intenten asignar memoria administrada, creo), lo cual está bien para nosotros. Pero no estoy seguro de si estos números se pueden generalizar a cualquier tipo de aplicación, probablemente debería hacer su propio perfil para estar seguro.

    Si tiene miedo de que su GUI pueda romper sus restricciones en tiempo real, podría considerar poner el procesamiento de la imagen real en un proceso separado y comunicarse con la GUI utilizando tuberías / sockets. O, al menos, tenga en cuenta esa opción cuando diseñe su sistema, de modo que tenga la peor opción si realmente se encuentra con problemas imprevistos de rendimiento.

    Su segunda pregunta fue si debería usar C ++ o C # para los algoritmos reales. Personalmente, me siento más cómodo en C ++ cuando escribo algoritmos complejos de procesamiento de imágenes. Creo que el lenguaje es más adecuado para la tarea, y hay muchas más bibliotecas de ejecución de problemas para C / C ++ que para C #. Pero eso podría ser una cuestión de preferencia personal. Desde el punto de vista del rendimiento, C ++ tiene la ventaja de que el Clineador en línea de C ++ es mejor que el .NET JIT en línea (es decir, puede en línea más de sus llamadas de función pequeña).

    Si elige usar C ++, sugeriría usar C ++ / CLI: de esa manera, puede escribir clases de C ++ comstackdas en código administrado. El optimizador de C ++ los optimizará, solo el último paso de comstackción al código nativo se realizará mediante .NET JIT. La gran ventaja es que puede acceder directamente a sus clases .NET desde C ++ / CLI, y puede crear fácilmente clases administradas en C ++ / CLI a las que se puede acceder desde C #. No es necesario que escriba el código del envoltorio en ambos lados de la cerca. (C ++ / CLI es un poco torpe porque contiene construcciones de lenguaje para progtwigción administrada y no administrada, pero si ya está familiarizado con C ++ y C # no administrados, es probable que no tenga problemas para entenderlo).

    Para C ++, utiliza C ++ / CLI, que en realidad no es tan malo. Es mucho mejor que las antiguas extensiones gestionadas.

    Para comentar sobre el rendimiento. Realmente depende. ¿Cuánto tiempo atrás habrá entre su código C ++ y su código C #? ¿Tendrá un hilo de fondo que recopile datos en C ++ y los envíe periódicamente al código C #? Si va a interactuar con un dispositivo, ¿usará serial, USB, alguna API que se le ha dado?

    Estoy de acuerdo con Mitch 100%.

    Si después de investigar sus recursos, aún siente que necesita usar un código no administrado, puede escribir una capa “comercial” en C ++ (o en este caso, realmente una capa funcional) y escribir su UI en C #. Use COM Interop para llamar desde C # / código administrado a su código no administrado.

    Una vez más, sin embargo, mi sensación es que no necesitarás hacer esto.

    El idioma que elija no afectará mucho el rendimiento (digamos que puede afectar la velocidad en un 5/10%). Lo que marcará la diferencia son los algoritmos que utilizará, cómo procesa los datos, perfila su aplicación, etc. (el rendimiento podría cambiar con una relación de 10x).

    Lo he hecho con C ++ .NET.

    Dado que tanto C ++ .NET como C # se administran, no veo por qué no se pudo hacer. El punto es cómo lo harás.

    Mi escáner tenía hasta 3000 líneas / seg, pero la estrategia clave era mostrar bloques de 32 líneas a la vez. No tenía requisitos de tiempo real difíciles por lo que a veces podía atrasarme un poco. Si el tiempo real es muy importante para usted, debe considerar cambiar de plataforma.

    Existe una solución de Windows en tiempo real llamada “InTime OS” pero es realmente doloroso de usar.

    Otro enfoque que puede tener es separar el tiempo real duro en una dll o biblioteca separada y hacer que C # muestre lo que puede a su propia velocidad. Realmente, el usuario nunca podrá saber si su interfaz tiene 2000 fps o 500 fps

    Tengo experiencia en sistemas de latencia muy baja C / C ++ y C # nativos.

    • en C / C ++ el 80% del tiempo del procesador se pierde en los métodos deterministas de malloc, pero el código nativo es 10 veces más rápido que el código msil

    • en C # la asignación de memoria es más rápida porque es un proceso asíncrono

    Su elección debe hacerse por la proporción: tiempo de proceso / número de malloc

    Así que la granularidad !!!

    La solución para C / C ++ es la asignación previa de todos los buffers en la memoria (use el caché L2 / L3 de búsqueda previa si es necesario)

    La solución para C # es minimizar el mecanismo de conversión P-Invoke.

    Enhorabuena por tu proyecto, Paul.

    El front-end wpf y c ++ backend (pinvoke) son rápidos, pero cuando haces tu trabajo de GUI también en hilos, tu hilo de GUI no se bloquea por tu código de fondo. Cuando hagas eso tu progtwig lucirá más rápido y ligero.

    ¿Por qué ventanas? Tiene un rendimiento de memoria horrible y una red peor en comparación con cualquiera de los Unix que existen. La captura especializada de un sensor de línea implica que necesita un dispositivo para manejar la entrada sin procesar. Considere usar el sistema operativo correcto primero, lo que reducirá en gran medida las otras presiones con las que tendrá que lidiar (estoy muy familiarizado con las tecnologías de escáner de línea).