Estamos trabajando en una base de código C ++ de tamaño moderado (10Mloc) que a través de nuestros esfuerzos de optimización se está volviendo uniformemente lenta .
Esta base de código es un conjunto de bibliotecas que combinamos para ponerlas a trabajar. Cuando se desarrolló el marco general de cómo se comunican estas bibliotecas, hubo un cierto énfasis en el rendimiento y más tarde, cuando se agregaron más partes, el marco general no cambió mucho. La optimización se realizó cuando fue necesario y a medida que nuestro hardware evolucionó. Esto hizo que la decisión temprana y costosa fuera evidente solo mucho más tarde. Ahora estamos en un punto donde las optimizaciones adicionales son mucho más caras ya que requerirían reescribir grandes partes de la base del código. Nos encontramos acercándonos a un mínimo local indeseable ya que sabemos que, en principio, el código debería poder ejecutarse mucho más rápido.
¿Existen metodologías exitosas que ayuden a decidir qué turnos para hacerse cargo de la evolución de una base de código hacia una solución global de rendimiento óptimo que no se confunde fácilmente con las oportunidades de optimización fácil?
EDITAR
Para responder a la pregunta de cómo nos perfilamos actualmente:
Realmente solo tenemos 2 escenarios diferentes de cómo se puede usar este código, ambos vergonzosamente paralelos. La creación de perfiles se realiza tanto con el tiempo promedio del reloj de pared sobre una gran muestra de entradas como con ejecuciones más detalladas (costos de instrucción, predicciones erróneas de rama y problemas de almacenamiento en caché). Esto funciona bien ya que corremos exclusivamente en nuestras máquinas extremadamente homogéneas (un grupo de miles de máquinas idénticas). Dado que generalmente mantenemos ocupadas todas nuestras máquinas la mayor parte del tiempo funcionando más rápido, podemos ver cosas nuevas adicionales. El problema es, por supuesto, que cuando aparezcan nuevas variaciones de entrada, podrían recibir una penalización tardía, ya que eliminamos las microeficiencias más obvias para los otros casos de uso, lo que posiblemente reduzca el número de escenarios de "ejecución óptima".
sloc
. Lo llamé "de tamaño moderado" porque no tengo idea de lo que se considera "grande" aquí.