2008-11-27 11 views
22

¿En qué circunstancias debería esperar que los memcpys superen las asignaciones en hardware moderno INTEL/AMD? Estoy usando GCC 4.2.x en una plataforma Intel de 32 bits (pero también estoy interesado en 64 bits).memcpy vs asignación en C

+0

¡Pregunta interesante! Como obviamente está preocupado por cómo mejorar la velocidad de las operaciones de memoria: Recientemente leí sobre el rol de la compresión en la transferencia de memoria de alguien que desarrolla pyTables: http://www.pytables.org/docs/StarvingCPUs.pdf Como se describe allí, el uso habitual de memcpy puede ser lento en comparación con sus mejoras con compresores muy rápidos ([blosc] (http://blosc.pytables.org/trac/)). ¡Por favor, considere esto solo como material de alto rendimiento! – math

+0

Esta pregunta es bastante amplia. –

Respuesta

33

Nunca debe esperar que superen las asignaciones. La razón es que el compilador usará memcpy de todos modos cuando crea que sería más rápido (si usa banderas de optimización). Si no es así, y si la estructura es razonablemente pequeña para que encaje en los registros, se podría utilizar la manipulación directa del registro, lo que no requeriría acceso alguno a la memoria.

GCC tiene patrones de movimiento de bloques especiales internos que determinan cuándo cambiar directamente los registros/celdas de memoria, o cuándo usar la función memcpy. Tenga en cuenta que al asignar la estructura, el compilador sabe en tiempo de compilación qué tan grande será el movimiento, por lo que puede desenrollar copias pequeñas (hacer un movimiento n veces en fila en lugar de hacer un bucle), por ejemplo. Nota -mno-memcpy:

-mmemcpy 
-mno-memcpy 
    Force (do not force) the use of "memcpy()" for non-trivial block moves. 
    The default is -mno-memcpy, which allows GCC to inline most constant-sized copies. 

Quién lo sabe mejor cuándo utilizar memcpy que el propio compilador?

+4

Tenga en cuenta que puede aplicarse lo contrario: en GCC al menos, la memcpy de un tamaño constante pequeño se reemplaza con instrucciones de copia, y si se utiliza con un puntero a una fuente pequeña y/o destino * no * impide optimizar uno o ambos registros. Entonces: haga lo que resulte en el código más simple. –

+2

No debe esperar que una supere a la otra. Si tiene un problema de rendimiento, debe perfilarlo, ver si la tarea/memcpy es el problema, y ​​si es así, intente cambiarlos para usar el otro, y vea si funciona mejor. Más perfiles, menos conjeturas. ;) – jalf

+1

Es decir, esperaría que "las asignaciones superen a memcpy" también sean falsas, dado que el interlocutor ha especificado un GCC reciente. Pero suponiendo que no se requiere un elenco, estoy de acuerdo con su consejo de usar asignación, ya que resulta en el código más claro. –