2012-02-27 11 views
10

Mi trabajo se centra principalmente en informática 'científica' de alto rendimiento. He estado haciendo eso durante ~ 15 años, pero solo recientemente me di cuenta de que mi software desperdicia tiempo de computación. En palabras cortas: mis formas de escribir código C++ eficiente ya no funcionan.Computacionalmente eficiente C++ - lectura general

De vez en cuando veo un código, escrito por un niño, que básicamente hace los mismos cálculos que el mío (el mismo algoritmo, enfoque similar), pero - mágicamente! - realiza mucho más rápido. ¡En la mayoría de los casos ni siquiera puedo rastrear los orígenes de la diferencia!

Mi pregunta es: ¿cómo puedo aprender el arte de la optimización del código moderno de C++? Quizás algo sobre SSE, problemas de alineación de caché/memoria? ¡Cualquier sugerencia de libro, PDF, artículo, ejercicio o sitio web es bienvenida!

PS. Soy muy consciente de trucos que son o bien:

  • demasiado generales (por ejemplo, 'Uso de perfiles', 'Usar buenos algoritmos', 'ir multiproceso')
  • Trivial (por ejemplo, 'Evitar las funciones virtuales', ' hacer ++ i en lugar de i ++ ' 'Habilitar -O3')
  • cuestionable (por ejemplo, 'la memoria su reutilización con reinterpret_cast <>', 'en forma de tabla seno y el coseno', 'Escribir ensamblado en línea')
  • ridículo (por ejemplo' Hacer metaprogramación de plantillas ')

Estos son no lo que estoy preguntando.

+0

Un buen libro IMO: http://www.intel.com/intelpress/sum_swcb2.htm – Tudor

+0

Por lo que he visto hasta ahora, diría que evite la asignación de memoria dinámica cuando sea posible y empaquete sus datos de forma inteligente en lugar de que al azar. En general, la memoria de la aplicación es el cuello de botella (bueno, aparte de los IO de disco/red ...). Además, en situaciones MT, compartir falsamente es un asesino ahora que tenemos verdaderos entornos multi-core/multiprocesador; un poco más difícil de diagnosticar también. Sin embargo, no tengo idea de cómo esto se aplica a la informática científica. –

+0

* "de vez en cuando ... una pieza de código, ... básicamente hace los mismos cálculos que la mía ... pero - ¡por arte de magia! - se comporta mucho más rápido". * - Publica tus pocos ejemplos que tengas (posiblemente en diferentes pregunta). Estoy seguro de que la gente aquí podrá descubrir cómo se produce la diferencia. –

Respuesta

10

Yo también trabajo en computación científica por más tiempo que OP y principalmente en Fortran. aquí hay un pequeño consejo de mi experiencia;

1) Manténgase al día con lo que los compiladores pueden hacer. Por un lado, no intente vencer al compilador en los trucos de optimización que el compilador conoce, por otro, sepa en qué compiladores todavía no son buenos. Por ejemplo, ahora mismo creo que puedo hacer un mejor trabajo que mi compilador en el mosaico de bucles. Aprenda también cómo facilitar al compilador la optimización del código.

OP tendrá la tentación de pasar este punto como un ejemplo de consejo que es demasiado general para ser utilizado. Veo que el manual del compilador Intel C++ tiene alrededor de 800 páginas de documentación de las opciones del compilador, y otras 400 en la optimización de aplicaciones. ¿OP ha leído todo esto (o una cantidad similar de documentación para el compilador preferido)?

2) Manténgase actualizado con la arquitectura de la computadora, en particular con el diseño de la jerarquía de la memoria y del fpus. Si nada más, esto ayuda a comprender cuáles son los límites de rendimiento que uno puede esperar razonablemente. Pero también proporciona información para las decisiones sobre el diseño e implementación del programa, y ​​las indicaciones de cómo esas decisiones deberían cambiar cuando los programas se trasladan a la próxima generación de hardware.

3) Utilice las bibliotecas. Escriba el código como último recurso.

4) No deje de lado las ideas como la metaprogramación de plantillas que tienen una muy buena reputación para ayudar al programador a crear código rápido. Study Boost y Blitz.

5) El rendimiento del programa es una disciplina empírica. Solo cree en los datos, no en los argumentos. Ni siquiera un argumento hecho por mí.

Finalmente, incluso en computación de alto rendimiento a gran escala (mis trabajos más grandes se ejecutan durante días en CPU de 10 K y más, tengo un poco de conocimiento de esto), a veces la actividad para optimizar es el tiempo de desarrollo, no de ejecución.

PD ¿Le pidió al niño instrucciones?

+0

+1 para todo. –

3

no puedo llamar a este tipo un "niño", pero usted puede encontrar útil este curso: Advanced STL de MSDN Channel9 Conferencias de Stephan T Lavavej (miembro del equipo de VC++ y mantenedor de STL allí). La calidad del video, sin embargo, no es buena de mi parte. Probablemente, tendrás más suerte.

hace
2
tiempo

Log Me readed dos libros que me ayudaron:

  1. Efficient C++ Técnicas de Programación Actuación de Bulka & Meyhew
  2. más eficaz C++

Además, visitan BrDobbs periódicamente y, de Por supuesto, stackoverflow !!!

6

Los procesadores son mucho más rápidos que hace 15 años. La memoria no se ha incrementado en velocidad al mismo ritmo. Esto combinado con conjuntos de datos más grandes, particularmente en grandes simulaciones científicas, significa que debe pensar con más cuidado sobre cómo se accede a los datos. Esa es quizás una de las diferencias.

He encontrado estos artículos interesantes:

http://overbyte.com.au/2011/10/21/optimisationmasterclass1/

http://overbyte.com.au/2011/11/10/optimisation-lesson-2/

que están escritos por un tipo que conozco que escribió motores de juegos y que ahora optimiza los juegos de PS3. Puede encontrarlos útiles.

1

No olvide el procesamiento de la red.Se pueden realizar cálculos largos en múltiples CPU o múltiples hilos.

Esa es una forma moderna de mejorar el tiempo de cálculo.

Los otros tienden a ser los estándares: - uso eficiente de almacenamiento en caché - uso eficiente de la evaluación perezosa

y evitando bloqueo/desbloqueo al mismo tiempo haciendo todo esto.

3

El libro "Arquitectura de computadora: un enfoque cuantitativo" hennessey y patterson. No apunta específicamente a C++, pero es aún más importante la arquitectura general. Esto es crucial para HPC incluso más que cualquier "truco y consejos".

Cuestiones relacionadas