2010-06-13 19 views
14

Así que cada vez que escribo código siempre pienso en las implicaciones de rendimiento. A menudo me he preguntado, ¿cuál es el "costo" de usar una memoria en relación con otras funciones en términos de rendimiento?Costo de rendimiento de una Memcopy en C/C++

Por ejemplo, puedo escribir una secuencia de números en un búfer estático y concentrarme en un fotograma dentro del búfer, para mantener el fotograma una vez que llego al final del búfer, puedo memcopy todo al comienzo O puedo implementar un algoritmo para amortizar el cálculo.

+11

¿Alguna vez ha ido más allá de pensar en el rendimiento y lo ha medido? –

+0

No tengo, sin embargo, memoria. – Cenoc

+6

Siempre pensando en el rendimiento es una excelente manera de escribir código cutre (y tal vez lento). –

Respuesta

18

memcpy generalmente está optimizado para maximizar el ancho de banda de memoria de las copias grandes. Por supuesto, no es tan rápido como evitar una copia por completo, y para las copias cortas de tamaño fijo, la asignación directa puede ser más rápida ya que memcpy tiene un código adicional para tratar con longitudes impares.

Pero cuando necesita copiar un bloque de memoria, es difícil superar memcpy. Es muy portátil y la mayoría de los compiladores hacen todo lo posible para hacerlo rápido, ya sea usando instrucciones SIMD o tal vez en línea.

+1

El uso de memcpy en C++ debe evitarse, ya que es una copia "tonta" y pueden producirse problemas. El operador de asignación/constructor de copia definitivamente debe usarse alternativamente. Además, primero se debe ejecutar un perfil para determinar que es el problema. – Puppy

+13

@DeadMG: muchos programas en C++ funcionan con datos "tontos", que se llaman "datos antiguos simples" según el estándar C++ y es perfectamente seguro utilizar memcpy. En mi experiencia, el tipo de programas que no tienen POD son los programas que se escribirían mejor en un lenguaje de nivel superior. –

+2

Sí. * Puedes * usar memcpy y atornillar tu programa por completo con tipos que no sean POD. O bien, * usted * podría * usar el operador de asignación, que finalmente resultará en una memcpy para tipos POD y un programa que funciona para tipos que no son POD. – Puppy

1

Bueno, en primer lugar - usted debe pensar en el rendimiento sólo si la copia de memoria es su cuello de botella (y en realidad es un caso raro).

En segundo lugar, memcpy se implementa utilizando el ensamblador (consulte memcpy.asm) y, supongo, es la solución de copia de memoria más rápida disponible.

También mencionar, en general, memcpy llamadas crudas en C++ deben evitarse, intente utilizar envolturas y rutinas más abstractas.

+0

La asignación simple se puede implementar usando registros de CPU, pero el uso de memcpy no es el caso. Si la asignación es demasiado grande, el compilador recurrirá a memcpy de todos modos, así que mejor use la asignación (cuando corresponda ...) – MindTailor

1

memcpy() copia el contenido de la memoria en la fuente a dest. La copia obviamente es lineal a la cantidad de elementos en la fuente. Lo que constituye el tamaño óptimo de un elemento depende de la máquina. De todos modos, se puede aplicar una gran cantidad de magia negra de otomano del compilador dependiendo del contexto de la operación. En C++ generalmente es más prudente evitar memcpy y usar constructores de asignación o copia.

+0

En una arquitectura moderna, teniendo en cuenta la arquitectura de memoria y los efectos de caché, la copia casi con seguridad no es lineal a la cantidad de elementos El constructor memcpy y copy está comparando manzanas y naranjas. –

4

Está bien tener en cuenta las implicaciones de rendimiento, pero no te distraigas demasiado del objetivo real de escribir un buen código de limpieza. Si te inclinas a obsesionarte por el rendimiento incluso cuando sabes algo mejor, intenta enfocarte en implicaciones de mayor nivel e ignora las cosas poco a poco como memcpy, que puedes confiar en que el compilador y los autores de la biblioteca optimicen.

Generalmente, evite la optimización prematura de este tipo de nivel bajo, ya que consume tiempo, los efectos aparecen para infectar todo el programa y, sin mediciones, no puede esperar obtener ningún aumento de rendimiento.

1

Considere el libro de McCormick 'Code Complete'. Robo sin pudor desde allí ---

  1. La mejora del algoritmo generalmente tiene la mayor amortización en el rendimiento.

  2. Las declaraciones simples permiten al compilador optimizar de manera efectiva. Estos tienen un bajo costo de programador. Por lo general, aumentan la legibilidad. Son un "por defecto" predeterminado de bajo costo.

Como se ha mencionado memcpy ya se ha ajustado y es a menudo muy eficaz en los bloques de memoria más grandes.Entonces, ¿por qué evitarlo si la situación exige mantener los datos?

En general, no se optimiza sin ningún motivo. Supongamos que escribe un informe en un conjunto de datos masivo. Ningún usuario espera tener una respuesta instantánea en ese escenario. Comienzan el trabajo y toman un bocadillo. Entonces, si tu código se ejecuta en 10 minutos o tres minutos, no importa. Para ellos. Thet no se dará cuenta. Y ... escriben tu cheque de pago.

La optimización del programador es un enorme costo inicial. Así que gaste ese costo solo donde sea necesario.

+1

En realidad, es el código completo de Steve Mcconnell –

+0

. Es McConnell. Estoy corregido. –

Cuestiones relacionadas