2009-12-25 11 views
21

Al usar memcpy() cuando la superposición de origen y destino puede conducir a un comportamiento no definido, en esos casos solo se puede usar memmove().¿Cuál usar - memmove() o memcpy() - cuando los almacenamientos intermedios no se superponen?

Pero, ¿y si sé con seguridad que los búferes no se superponen? ¿Existe alguna razón para usar específicamente memcpy() o específicamente memmove()? ¿Qué debería usar y por qué?

+3

¿O 'std :: copy'? ;) – jalf

+0

No usaría 'std :: copy' si mi vida dependiera de ello. –

+0

@Matt Joiner: ¿Podría explicar por qué no le gusta mucho 'std :: copy()'? – sharptooth

Respuesta

32

Suponiendo que el implementador de una biblioteca es sane, memcpy siempre será al menos tan rápido como memmove. Sin embargo, en la mayoría de las plataformas, la diferencia será mínima, y ​​en muchas plataformas memcpy es solo un alias para memmove que admite el código heredado que (incorrectamente) llama a memcpy en búferes superpuestos.

Tanto memcpy como memmove se deben escribir para aprovechar las cargas y tiendas más rápidas disponibles en la plataforma.

Para responder a su pregunta, debe utilizar la que es semánticamente correcta. Si puede garantizar que los buffers no se superponen, debe usar memcpy. Si no puede garantizar que los almacenamientos intermedios no se superpongan, debe usar memmove.

+0

+1. Me gusta especialmente el contrapunto "asumiendo el sentido" de mi propia respuesta :-) – paxdiablo

+0

Nitpick: 'memcpy' y' memmove' deben escribirse para aprovechar las cargas y tiendas 'desalineadas' más rápidas disponibles en la plataforma. Si sabe que sus búferes están alineados correctamente, a menudo puede obtener un rendimiento mucho mejor utilizando cosas como MMX, que copian unidades de datos mucho más grandes a la vez. –

+0

@ Adam: En términos generales, uno puede hacer arreglos para usar cargas alineadas y almacenar en memcopy copiando primero algunas unidades más pequeñas para lograr la alineación apropiada. Si los almacenamientos intermedios no tienen una alineación similar, será necesario aplicar algún cambio o permutación antes de almacenarlos, pero esto es más rápido que usar accesos de memoria no alineados en muchas arquitecturas. –

29

memcpy() no tiene ningún manejo especial para la superposición de almacenamientos intermedios por lo que carece de algunos controles, por lo tanto, es más rápido que memmove().

También en algunas arquitecturas memcpy() puede beneficiarse del uso de las instrucciones de la CPU para mover bloques de memoria, algo que memmove() no puede usar.

+0

su edición capturó lo que quería decir, +1. – falstro

+0

+1, por mencionar las instrucciones de la CPU. – MAK

+0

Incluso en una arquitectura RISC, a menudo hay operaciones de bloqueo de movimiento de las cuales se puede beneficiar memcpy(). PowerPC tiene VMX, por ejemplo. – Crashworks

5

Si está interesado en cuál funcionará mejor, debe probarlo en la plataforma de destino. Nada en el estándar ordena cómo se implementan las funciones y, si bien puede parecer lógico que una no verificación memcpy sea más rápida, esto de ninguna manera es una certeza.

Es muy posible, aunque poco probable, que la persona que escribió memmove para su compilador particular era un genio certificado mientras que la pobre alma que consiguió el trabajo de escribir memcpy era el tonto del pueblo :-)

Aunque, en realidad, me resulta difícil imaginar que el memmove podría ser más rápido que memcpy, no descarto la posibilidad. Mida, no adivine.

+1

'memcpy' tiene el calificador de restricción en sus argumentos, no' memmove'. (Codifica precisamente el hecho de que los buffers no se superponen). –

+0

D'Oh! Tienes razón, por supuesto, @StephenC, los recibí al revés. Eliminado ese doble sentido de mi respuesta :-) – paxdiablo

2

En alguna plataforma ARM en la que estoy trabajando, memmove era 3 veces más rápido que memcpy para carga corta no alineada. Como memcpy y memmove son el único mecanismo de tipografía realmente portátil, hubieras pensado que el compilador verificaría algo antes de intentar usar el NEON para hacerlo.

Cuestiones relacionadas