2010-05-22 12 views
5

He oído muchas cosas sobre el rendimiento en C; la fundición es lenta en comparación con las asignaciones normales, la llamada funcional es lenta, la operación binaria es mucho más rápida que las operaciones normales, etc ...C: rendimiento de asignaciones, operaciones binarias, etcétera

Estoy seguro de que algunas de estas cosas son específicas de la arquitectura y la optimización del compilador podría una gran diferencia, pero me gustaría ver un cuadro para tener una idea general de lo que debería hacer y lo que debo evitar para escribir programas de alto rendimiento. ¿Hay una tabla (o un sitio web, un libro, cualquier cosa)?

+8

* "... la conversión es lenta ..." * La conversión, en C, es una operación de tiempo cero en tiempo de ejecución. Sucede * completamente * en tiempo de compilación. De manera similar, las llamadas a funciones no son mucho más rápidas en un lenguaje de alto nivel que en C; * literalmente * simplemente "empuja el valor de retorno en la pila, empuja 0..n args en la pila, ejecuta un salto". ¿De dónde sacas estas "verdades"? Porque encontraría otra fuente. :-) –

+2

fundición es lenta? ¿Cª? Ni siquiera existe en tiempo de ejecución. –

+2

@ T.J. Algunos moldes no son gratuitos. Por ejemplo, lanzar un 'char' a un' doble'. Aún muy barato. –

Respuesta

10

Básicamente, no. No existe tal libro de "consejos y trucos" desde el nivel de sintaxis, porque no existe una garantía segura de que todo lo que usted declare sea verdadero (de hecho, la mayor parte es falso).

En general, la optimización del rendimiento debe centrarse más en los algoritmos, seguidos de la ubicación de la memoria y las optimizaciones de la memoria caché. Las mejores herramientas que tendrá son perfiladores (oprofile, valgrind, cachegrind, etc.) seguidos por una comprensión de la arquitectura de la máquina (combinaciones de instrucciones que son subóptimas, restricciones de alineación, jerarquía y tamaño de la memoria) y lenguaje ensamblador para su CPU (para capturar menos problemas óptimos de bucle interno).

Si está interesado en micro-optimizaciones en la arquitectura Intel (y todas las CPU compatibles con Intel), esta is a must read (PDF). Hay guías más interesantes en Agner's website.

+1

+1 para el orden de optmisations - poner algoritmos primero. Un mal algoritmo no se acelerará incluso si se microoptimiza en cada paso. –

+0

Es un sitio excelente. –

1

Básicamente todas las operaciones que menciona son muy, muy rápidas. A menos que los haga millones de veces por segundo, no se preocupe demasiado por las diferencias mínimas entre las alternativas.

Si tiene una parte de tiempo crítico de su programa que se está ejecutando demasiado lento, póngale un perfil para saber dónde se gasta exactamente y dónde tiene sentido optimizar.

9

Me parece que estás muy confundido por todo esto. Vamos a abordar algunos de estos mitos que has arrastrado.

La fundición es lenta en comparación con las asignaciones normales.

Eso realmente depende de lo que estés emitiendo. Entre diferentes tipos de direcciones, no; En realidad, el casting es gratuito ya que solo está aplicando una interpretación diferente al mismo valor. Casting entre diferentes anchuras de tipo numérico puede ser un poco más lento (y algunas veces se realiza implícitamente en la asignación) pero sigue siendo muy rápido.

Las llamadas de función son lentas.

Realmente no. No son gratuitos, pero el costo no es lo suficientemente alto como para evitarlos a menos que tenga datos de creación de perfiles que indique lo contrario. Nunca optimice sin una buena razón para hacerlo y prueba de que ayudará. (Para el registro, se sabe que revertí las optimizaciones intentadas que no tenían el equilibrio de ganancias de rendimiento que quería).

Las operaciones binarias son más rápidas que las operaciones normales.

¿Qué es una "operación normal"? FWIW, además es una operación binaria. También lo es la multiplicación. En hardware moderno, ambos son bastante rápidos.Deja que el compilador se preocupe por eso. Es mucho más importante que se concentre en describir lo que está haciendo correctamente.

Ahora, para las cosas que realmente cuestan :

  • de E/S.
  • Asignación de memoria.
  • Copias de memoria.
  • Anillos profundamente anidados (o muy largos).

Mantenga sus ojos en aquellos; están donde el software generalmente se vuelve lento. Y siempre elija buenos algoritmos y estructuras de datos.

+0

Excelente respuesta. Excelente. Aunque, la asignación de la memoria del montón no está en la misma clase que E/S, ni siquiera está cerca. Heap es muy rápido. No rápido como un yeso, pero rápido, hasta que te quedas sin energía, por supuesto. :-) –

+0

@ T.J. La E/S es la más lenta y, por lo general, la más difícil de eliminar; usualmente haces 'leer()' por una buena razón. La asignación de montones es mucho más rápida, pero a menudo se hace mucho más; no es para temer, pero definitivamente no es gratis. –

+1

Y un área que a menudo es innecesariamente costosa es el manejo de cadenas. Los codificadores pobres a menudo escriben código desastrosamente malo en esa área porque no mantienen un buen manejo de las copias de memoria y los bucles que están sucediendo. –

1

¿Dónde escucha estas cosas? De todos los mitos que "se vuelven virales" en este campo, es posiblemente el más sorprendente que he escuchado.

C es lo más cercano que se puede llegar al lenguaje de la máquina y sigue siendo un lenguaje de "alto nivel" independiente de la máquina.

Todas las otras respuestas son correctas.

Solo agregaría, en el software real (no en programas de dos páginas) exceso de generalidad, sobre-abstracción, matar moscas con bazucas, son la causa abrumadora de bajo rendimiento, aunque cada último programador considera su solución "sencillo".

2

Érase una vez un libro llamado Efficient C. Algo más tarde, hubo un libro llamado Programación eficiente C/C++: Más pequeño, más rápido, mejor. Más recientemente todavía, se llamó Efficient C++.

Todos ellos cubren muchas de las cosas que parecen interesarle. Los dos primeros parecen estar agotados, y el tercero probablemente debería estarlo. Para seguir siendo correcto y significativo, tal gráfico probablemente debería actualizarse una vez al mes. Casi todo lo que piense que es a lo largo de tales líneas probablemente sea incorrecto para empezar, y lo poco que es correcto probablemente se vuelva erróneo bastante pronto de todos modos.

Solo por ejemplo, de todas maneras sigue las recomendaciones que, si le importa el rendimiento, debe evitar el punto flotante. En un momento, esto era incluso razonable, pero hoy en día, algunas CPU realmente hacen números enteros convirtiendo el entero en coma flotante, haciendo los cálculos matemáticos, y luego convirtiendo el resultado en un número entero. Usando el punto flotante en todas partes puede mejorar la velocidad de.

1

He oído muchas cosas sobre el rendimiento en C ...

alguien le ha dado algunos mismas ideas extrañas. Me gusta especialmente la distinción entre operaciones "binarias" y "normales". Pensé que para una computadora, el código binario era normal. Alguien tendrá que explicarme esta distinción.

Me gustaría ver un cuadro para tener una idea general de lo que debería hacer y lo que debo evitar para escribir programas de alto rendimiento.

Te proporciono un cuadro a continuación. Asume que se ha informado sobre el lenguaje C a nivel de Kernighan y Ritchie, que es el libro de texto clásico sobre C y el único libro en C que necesitará , necesitará (aunque otros son útiles).

Have you read Jon Bentley's book "Programming Pearls"? --no--> read it 
      | 
      | yes 
      V 
    Have you read Peter van der Linden's book 
    "Expert C Programming: Deep C Secrets"?     --no--> read it 
      | 
      | yes 
      V 
    Have you learned how to use valgrind --tool=callgrind 
    and the kcachegrind visualizer?       --no--> learn them 
      | 
      | yes 
      V 
    Congratulations! You are now equipped to write 
    reasonably efficient C programs. 

La mayor parte de los temas en el libro de Bentley, especialmente algoritmos, vale la pena perseguir con mayor profundidad en otro lugar. Pero esta tabla será manera fácil e inofensiva de comenzar.

Cuestiones relacionadas