Entendiendo el código fuente de memcpy ()

00018 void *memcpy(void *dst, const void *src, size_t len) 00019 { 00020 size_t i; 00021 00022 /* 00023 * memcpy does not support overlapping buffers, so always do it 00024 * forwards. (Don't change this without adjusting memmove.) 00025 * 00026 * For speedy copying, optimize the common case where both pointers 00027 * and the length are word-aligned, and copy word-at-a-time instead 00028 * of byte-at-a-time. Otherwise, copy by bytes. 00029 * 00030 * The alignment logic below should be portable. We rely on 00031 * the compiler to be reasonably intelligent about optimizing 00032 * the divides and modulos out. Fortunately, it is. 00033 */ 00034 00035 if ((uintptr_t)dst % sizeof(long) == 0 && 00036 (uintptr_t)src % sizeof(long) == 0 && 00037 len % sizeof(long) == 0) { 00038 00039 long *d = dst; 00040 const long *s = src; 00041 00042 for (i=0; i<len/sizeof(long); i++) { 00043 d[i] = s[i]; 00044 } 00045 } 00046 else { 00047 char *d = dst; 00048 const char *s = src; 00049 00050 for (i=0; i<len; i++) { 00051 d[i] = s[i]; 00052 } 00053 } 00054 00055 return dst; 00056 } 

Acababa de pasar por una implementación de memcpy , para entender en qué se diferencia del uso de un bucle. Pero no pude ver ninguna diferencia entre usar un bucle en lugar de memcpy , ya que memcpy usa el bucle de nuevo internamente para copiar.

No podría entender if partes lo hacen para los enteros – i < len/sizeof(long) . ¿Por qué se requiere este cálculo?

No podría entender si parte lo hacen por enteros. i

Debido a que están copiando palabras, no bytes individuales, en este caso (como dice el comentario, es una optimización: requiere menos iteraciones y la CPU puede manejar los datos alineados con palabras de manera más eficiente).

len es el número de bytes para copiar, y sizeof(long) es el tamaño de una sola palabra , por lo que el número de elementos para copiar (significa, iteraciones de bucle para ejecutar) es len / sizeof(long) .

para entender cómo difiere de usar un bucle. Pero no pude diferenciar de usar un bucle en lugar de memcpy, ya que memcpy usa el bucle de nuevo internamente para copiar

Bueno, entonces utiliza un bucle. Tal vez otras implementaciones de libc no lo hagan así. De todos modos, ¿cuál es el problema / la pregunta si utiliza un bucle? También, como ve, hace más que un bucle: comprueba la alineación y realiza un tipo diferente de bucle dependiendo de la alineación.

No podría entender si parte lo hacen por enteros. i

Esto está comprobando la alineación de la palabra de memoria. Si las direcciones de destino y origen están alineadas por palabra, y la copia de longitud es múltiple en tamaño de palabra, entonces realiza una copia alineada por palabra ( long ), que es más rápida que usar bytes ( char ), no solo por el tamaño , pero también porque la mayoría de las architectures hacen copias alineadas por palabras mucho más rápido.

 for (i=0; i 

En este bucle for, cada vez que se copia un long , hay un tamaño total de len para copiar, por eso necesita i como condición para terminar el bucle.

len%sizeof(long) comprueba si está intentando copiar largos completos que no forman parte del long .

 00035 if ((uintptr_t)dst % sizeof(long) == 0 && 00036 (uintptr_t)src % sizeof(long) == 0 && 00037 len % sizeof(long) == 0) { 00038 00039 long *d = dst; 00040 const long *s = src; 00041 00042 for (i=0; i 

comprueba la alineación y, si es verdadero, copia rápidamente ( sizeof(long) bytes sizeof(long) a la vez).

 00046 else { 00047 char *d = dst; 00048 const char *s = src; 00049 00050 for (i=0; i 

esto es para las matrices desalineadas (copia lenta (1 byte a la vez))