繁体   English   中英

mem中的C实现

[英]memmove implementation in C

有人可以帮助我理解如何在C中实现memmove。我只有一个特殊条件吗?

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

copy from the back

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

在数学上,你不必担心它们是否重叠。 如果src小于dst ,只需从末尾复制。 如果src大于dst ,只需从头开始复制。

如果srcdst相等,则直接退出。

那是因为您的案例是以下之一:

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以从头开始复制。

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

如果两个内存区域确实重叠,则为了所有意图和目的,将要复制的区域移动到临时缓冲区中,并将临时缓冲区复制(所有内容都使用memcpy,最有可能)返回到原始缓冲区之上。 您无法从一开始就工作,也不能从后面开始使用重叠区域,因为在此过程中至少会有一些数据被破坏。

话虽如此,自从我查看libc代码已经有很长一段时间了,因此可能会对memmove和重叠区域进行优化,这是我尚未想到的。

memmove根本不依赖于堆栈的增长方式 - 它只是将一个内存区域复制到另一个位置 - 就像memcpy一样,除了它处理重叠区域而memcpy没有。

编辑:实际上,再考虑一下......如果你从正确的“源头”(可以这么说)出发,可以从后面工作,这取决于移动本身(例如,源是<dest还是不?)。 您可以在这里阅读newlib的实现,并且也得到了相当好的评论。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM