【发布时间】:2013-07-11 11:00:28
【问题描述】:
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 }
我刚刚经历了memcpy
的实现,以了解它与使用循环有何不同。但是我看不出使用循环而不是memcpy
之间有什么区别,因为memcpy
在内部再次使用循环来复制。
我无法理解 if
他们为整数所做的部分——i < len/sizeof(long)
。为什么需要这个计算?
【问题讨论】:
-
这段代码是从哪里来的?我见过更好的优化 memcpy 实现...
-
@Maxime:你怎么知道:你甚至不知道目标处理器(或编译器)!
-
@Angus,从您在*.com/questions/11772553/… 中的回答来看,您似乎了解对齐方式。
long
是一个处理器字,地址需要与处理器字对齐以获得更快的复制(大多数架构对对齐的数据执行更快的复制)。如果你做不到,那就慢慢做,一个字节一个字节。下面有很好的答案。 -
这个函数不会破坏别名规则(通过不一定声明为 long 的 long* 访问内存),因此是未定义的行为吗?
-
@jcoder 实现的实现不必遵循任何规则。如果您将此代码复制到您自己的名称的函数中并以此方式使用它,那将是一种违规行为。
标签: c