Esto puede sonar como una pregunta extraña, pero en mi departamento estamos teniendo problemas con la siguiente situación:
Estamos trabajando aquí en una aplicación de servidor, que está creciendo cada vez más, incluso en el punto en que estamos considerando dividirla en diferentes partes (archivos DLL), cargando dinámicamente cuando sea necesario y descargando luego, para poder manejar Los problemas de rendimiento.
Pero: las funciones que estamos utilizando pasan parámetros de entrada y salida como objetos STL, y como se menciona en una respuesta de desbordamiento de pila , esta es una muy mala idea. (La publicación contiene algunas soluciones ± y hacks, pero no todo parece muy sólido).
Obviamente, podríamos reemplazar los parámetros de entrada / salida por tipos C ++ estándar y crear objetos STL a partir de aquellos que alguna vez estuvieron dentro de las funciones, pero esto podría estar causando caídas en el rendimiento.
¿Está bien concluir que, en caso de que esté considerando construir una aplicación, que podría crecer tanto que una sola PC ya no pueda manejarla, no debe usar STL como tecnología?
Más información sobre esta pregunta:
parece haber algunos malentendidos sobre la pregunta: el problema es el siguiente:
mi aplicación está utilizando una gran cantidad de rendimiento (CPU, memoria) para completar su trabajo, y me gustaría dividir este trabajo en diferentes partes (ya que el programa ya está dividido en múltiples funciones), no es tan difícil crear algunas DLL fuera de mi aplicación y poner algunas de las funciones en la tabla de exportación de esas DLL. Esto daría como resultado la siguiente situación:
+-----------+-----------+----
| Machine1 | Machine2 | ...
| App_Inst1 | App_Inst2 | ...
| | |
| DLL1.1 | DLL2.1 | ...
| DLL1.2 | DLL2.2 | ...
| DLL1.x | DLL2.x | ...
+-----------+-----------+----
App_Inst1 es la instancia de la aplicación, instalada en Machine1, mientras que App_Inst2 es la instancia de la misma aplicación, instalada en Machine2.
DLL1.x es una DLL, instalada en Machine1, mientras que DLL2.x es una DLL, instalada en Machine2.
DLLx.1 cubre la función exportada1.
DLLx.2 cubre la función exportada2.
Ahora en Machine1 me gustaría ejecutar function1 y function2. Sé que esto sobrecargará Machine1, por lo que me gustaría enviar un mensaje a App_Inst2, pidiéndole a esa instancia de la aplicación que realice la función2.
Los parámetros de entrada / salida de function1 y function2 son objetos STL (Biblioteca de tipos estándar de C ++), y regularmente podría esperar que el cliente realice actualizaciones de App_Inst1, App_Inst2, DLLx.y (pero no todas, el cliente podría actualizar Machine1 pero no Machine2, o solo actualice las aplicaciones pero no las DLL o viceversa, ...). Obviamente, si la interfaz (parámetros de entrada / salida) cambia, entonces el cliente se ve obligado a realizar actualizaciones completas.
Sin embargo, como se menciona en la URL de StackOverflow referida, una simple compilación de App_Inst1 o una de las DLL puede hacer que todo el sistema se desmorone, de ahí mi título original de esta publicación, desaconsejando el uso de STL (Plantilla estándar de C ++ Biblioteca) para grandes aplicaciones.
Espero haber aclarado algunas preguntas / dudas.
Respuestas:
Este es un problema clásico XY muy frío.
Su verdadero problema son los problemas de rendimiento. Sin embargo, su pregunta deja en claro que no ha realizado perfiles u otras evaluaciones de dónde provienen los problemas de rendimiento. En cambio, espera que dividir su código en archivos DLL resuelva mágicamente el problema (que no lo hará, para el registro), y ahora está preocupado por un aspecto de esa falta de solución.
En cambio, debes resolver el problema real. Si tiene múltiples ejecutables, verifique cuál está causando la desaceleración. Mientras lo hace, asegúrese de que realmente sea su programa el que tome todo el tiempo de procesamiento, y no un controlador Ethernet mal configurado o algo así. Y después de eso, comience a perfilar las diversas tareas en su código. El temporizador de alta precisión es tu amigo aquí. La solución clásica es monitorear los tiempos de procesamiento promedio y en el peor de los casos para una porción de código.
Cuando tenga datos, puede averiguar cómo lidiar con el problema, y luego puede averiguar dónde optimizar.
fuente
Si tiene que dividir un software entre varias máquinas físicas, debe tener alguna forma de serialización al pasar datos entre máquinas, ya que solo en algunos casos puede enviar el mismo binario exacto entre máquinas. La mayoría de los métodos de serialización no tienen problemas para manejar los tipos de STL, por lo que ese caso no es algo que me preocupe.
Si tiene que dividir una aplicación en Bibliotecas Compartidas (DLL) (antes de hacerlo por razones de rendimiento, realmente debe asegurarse de que realmente resolverá sus problemas de rendimiento) pasar objetos STL puede ser un problema, pero no es necesario. Como el enlace que proporcionó ya describe, pasar objetos STL funciona si usa el mismo compilador y la misma configuración del compilador. Si los usuarios proporcionan las DLL, es posible que no pueda contar fácilmente con esto. Sin embargo, si proporciona todas las DLL y compila todo junto, es posible que pueda contar con él y que sea muy posible utilizar objetos STL a través de los límites de DLL. Todavía debe tener cuidado con la configuración de su compilador para que no obtenga múltiples montones diferentes si pasa la propiedad del objeto, aunque eso no es un problema específico de STL.
fuente
La RAM es barata y, por lo tanto, el código inactivo es barato. La carga y descarga de código (especialmente la descarga) es un proceso frágil y es poco probable que tenga un efecto significativo en el rendimiento de sus programas en hardware moderno de escritorio / servidor.
La memoria caché es más costosa, pero eso solo afecta el código que está activo recientemente, no el código que está en la memoria sin usar.
En general, los programas superan sus computadoras debido al tamaño de los datos o el tiempo de CPU, no el tamaño del código. Si el tamaño de su código se está volviendo tan grande que está causando problemas importantes, es probable que desee ver por qué eso está sucediendo en primer lugar.
Debería estar bien siempre que los archivos dlls y el ejecutable se creen con el mismo compilador y se vinculen dinámicamente con la misma biblioteca de tiempo de ejecución de C ++. De ello se deduce que si la aplicación y sus dlls asociados se crean y se implementan como una sola unidad, entonces no debería ser un problema.
Donde puede convertirse en un problema es cuando las bibliotecas están construidas por diferentes personas o se pueden actualizar por separado.
Realmente no.
Una vez que comience a distribuir una aplicación en varias máquinas, tendrá muchas consideraciones sobre cómo pasar los datos entre esas máquinas. Es probable que los detalles de si se utilizan tipos STL o tipos más básicos se pierdan en el ruido.
fuente
No, no creo que esa conclusión siga. Incluso si su programa se distribuye en varias máquinas, no hay razón para que el uso de STL lo obligue internamente a usarlo en la comunicación entre módulos / procesos.
De hecho, diría que debe separar el diseño de interfaces externas de la implementación interna desde el principio, ya que la primera será más sólida / difícil de cambiar en comparación con lo que se usa internamente
fuente
Te estás perdiendo el punto de esa pregunta.
Básicamente hay dos tipos de DLL. La tuya y la de otra persona. El "problema STL" es que usted y ellos pueden no estar utilizando el mismo compilador. Obviamente, eso no es un problema para su propia DLL.
fuente
Si compila las DLL desde el mismo árbol de origen al mismo tiempo con el mismo compilador y las mismas opciones de compilación, entonces funcionará bien.
Sin embargo, la forma "con sabor a Windows" de dividir una aplicación en varias partes, algunas de las cuales son reutilizables, son los componentes COM . Estos pueden ser pequeños (controles individuales o códecs) o grandes (IE está disponible como control COM, en mshtml.dll).
Para una aplicación de servidor, esto probablemente tendrá una eficiencia terrible ; solo es realmente viable cuando tiene una aplicación que se mueve a través de múltiples fases durante un largo período de tiempo para que sepa cuándo algo no será necesario nuevamente. Me recuerda a los juegos de DOS que utilizan el mecanismo de superposición.
Además, si su sistema de memoria virtual funciona correctamente, se encargará de esto por paginación de páginas de códigos no utilizadas.
Compre una PC más grande.
No olvide que con la optimización correcta, una computadora portátil puede superar a un clúster hadoop.
Si realmente necesita múltiples sistemas, debe pensar con mucho cuidado sobre el límite entre ellos, ya que ahí es donde está el costo de serialización. Aquí es donde debe comenzar a mirar marcos como MPI.
fuente
La primera parte tiene sentido (dividir la aplicación en diferentes máquinas, por razones de rendimiento).
La segunda parte (carga y descarga de bibliotecas) no tiene sentido, ya que es un esfuerzo adicional y no mejorará (realmente) las cosas.
El problema que está describiendo se resuelve mejor con máquinas de computación dedicadas, pero estas no deberían funcionar con la misma aplicación (principal).
La solución clásica se ve así:
Entre las máquinas de front-end y de cómputo, puede tener cosas adicionales, como equilibradores de carga y monitoreo de rendimiento, y mantener un procesamiento especializado en máquinas dedicadas es bueno para el almacenamiento en caché y las optimizaciones de rendimiento.
Esto de ninguna manera implica una carga / descarga adicional de archivos DLL, ni nada que ver con el STL.
Es decir, use STL internamente según sea necesario, y serialice sus datos entre los elementos (consulte las memorias intermedias de protocolo y grpc y el tipo de problemas que resuelven).
Dicho esto, con la información limitada que proporcionó, esto se parece al clásico problema xy (como dijo @Graham).
fuente