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 }
Run Code Online (Sandbox Code Playgroud)
我刚刚完成了一个实现memcpy,以了解它与使用循环的不同之处.但我看不出使用循环而不是memcpy在memcpy内部再次使用循环来复制之间的任何区别.
我无法理解if他们为整数做的部分 - i < len/sizeof(long).为什么需要这个计算?
And*_*ter 15
我无法理解他们是否为整数所做的部分.我<len/sizeof(长).为什么需要这个计算?
因为它们是复制单词,而不是单个字节,在这种情况下(正如评论所说,它是一种优化 - 它需要更少的迭代,CPU可以更有效地处理字对齐的数据).
len是要复制的字节数,并且sizeof(long)是单个字的大小,因此要复制的元素数(表示要执行的循环迭代)是len / sizeof(long).
了解它与使用循环的不同之处.但是我使用循环而不是memcpy没有任何区别,因为memcpy在内部再次使用循环来复制
那么它使用循环.也许libc的其他实现不会那样做.无论如何,如果它确实使用了循环,那么问题/问题是什么?另外,正如您所看到的那样,它不仅仅是一个循环:它会检查对齐并根据对齐方式执行不同类型的循环.
我无法理解他们是否为整数所做的部分.我<len/sizeof(长).为什么需要这个计算?
这是检查内存字对齐.如果目标和源地址是字对齐的,并且长度副本是字大小的倍数,那么它通过word(long)执行对齐的副本,这比使用bytes(char)更快,这不仅仅是因为大小,而是也因为大多数架构都能更快地进行字对齐复制.
len%sizeof(long)检查您是否尝试复制不属于的完整长度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<len/sizeof(long); i++) {
00043 d[i] = s[i];
00044 }
Run Code Online (Sandbox Code Playgroud)
检查是否对齐,如果为true,则快速复制(sizeof(long)一次复制一个字节)。
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 }
Run Code Online (Sandbox Code Playgroud)
这是用于未对齐的数组(慢速复制(一次1字节))