Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
memmove在C中的实现_C_Memmove - Fatal编程技术网

memmove在C中的实现

memmove在C中的实现,c,memmove,C,Memmove,有人能帮我理解memmove是如何在C中实现的吗?我只有一个特殊条件,对吗 if((src<dst)&&((src+sz) > dst)) copy from the back if((src-dst)) 从后面抄 它还取决于堆栈的增长方式吗?取决于编译器。好的编译器将根据目标处理器指令集和总线宽度使用好的优化 如果两个内存区域不重叠,可以转换为memcpy。显然,memcpy在大多数系统上都得到了极大的优化(我使用的其中一个系统几乎利用了书中的每一个技巧,从展

有人能帮我理解memmove是如何在C中实现的吗?我只有一个特殊条件,对吗

if((src<dst)&&((src+sz) > dst))

copy from the back
if((src-dst))
从后面抄

它还取决于堆栈的增长方式吗?

取决于编译器。好的编译器将根据目标处理器指令集和总线宽度使用好的优化

如果两个内存区域不重叠,可以转换为memcpy。显然,memcpy在大多数系统上都得到了极大的优化(我使用的其中一个系统几乎利用了书中的每一个技巧,从展开的循环到支持最大吞吐量的SSE操作)

如果两个内存区域确实重叠,则出于所有目的,将要复制的区域移动到临时缓冲区中,并将临时缓冲区(很可能全部使用memcpy)复制回原始缓冲区的顶部。你不能从一开始就工作,也不能从一个重叠区域的后面工作,因为在这个过程中,你总会有一些数据被破坏

也就是说,我已经很久没有看过libc代码了,所以可能会有一个我还没有想到的memmove和重叠区域的优化

memmove完全不依赖于堆栈的增长方式——它只是将内存的一个区域复制到另一个位置——与memcpy完全相同,只是它处理重叠区域,而memcpy不处理


编辑:事实上,再想想。。。如果你从正确的“来源”(也就是说)出发,那么从后面工作就可以工作,这取决于移动本身(例如,来源是否从数学上讲,您不必担心它们是否重叠。如果
src
小于
dst
,只需从末尾复制即可。如果
src
大于
dst
,只需从头开始复制即可

如果
src
dst
相等,直接退出即可

这是因为您的案例是:

1) <-----s----->                start at end of s
                 <-----d----->

2) <-----s----->                start at end of s
            <-----d----->

3) <-----s----->                no action
   <-----d----->

4)          <-----s----->       start at beginning of s
   <-----d----->

5)               <-----s----->  start at beginning of s
   <-----d----->
1)从s的末尾开始
2) 从s结尾开始
3) 不采取行动
4) 从世纪初开始
5) 从世纪初开始
即使没有重叠,也可以很好地工作,简化您的条件


如果你有一种向前复制比向后复制更有效的方法,那么,如果可能的话,你应该检查重叠以确保你使用的是更有效的方法。换句话说,将上面的选项1更改为从头开始复制。

如果
src
dst
sz
均为正值,则该条件不可满足。如果
src>dst
,在它上面加上肯定的
sz
并不会使它变小。我一直有一个疑问。地址可以像你那样比较吗?我在某个地方听说,除非它们属于同一阵列或结构,否则它们不可能存在。有人请澄清!我认为这应该放在注释中,而不是单独的回复中。注意,这里有另一个隐藏的假设,即一次只复制一个字节。好的,无论你一次复制一个字节,还是一个四字或一些巨大的SSE9 1024位超字值,理论都是一样的。您必须确保不会复制到尚未复制的重叠区域。所有N-is-wide-than-char选项都引入了一种更复杂的重叠检测(和最终传输),如果它不是N值的直接倍数。@caf:If
src
dest
对于可以复制的较大类型具有相同的对齐方式,你永远不必担心撞到一个你还没有复制的区域,因为位置总是会相差至少那个大小。如果它们不共享相同的对齐方式,那么无论如何,您都会被困在以字节形式复制中…除非您想使用一些令人讨厌的x86未对齐io…@R..:在许多系统上,至少如果您使用的是一种正常的C方言,允许您绕过别名限制,更改对齐方式的复制操作仍然可以通过一次读取和写入多个字来完成,如果一个字抓取一个字并提取部分,然后在每次循环中读取(例如)四个32位寄存器,将其移位,与部分字结合,并抓取掉出的位,然后存储四个32位寄存器,等等。在许多ARM处理器上,即使在未对齐的情况下,性能也可能是使用字节的两倍。@R..:例如,在ARM7-TDMI上,不计算循环开销,使用对齐校正代码复制每组四个字需要20个周期。如果不进行对齐校正,则需要12分钟。单独复制字节或字需要5个周期。在任何情况下都不需要未对齐的访问(ARM7-TDMI不支持)。