memcpy的内部实现如何工作?

时间:2013-07-06 01:28:32

标签: c memory copy ram memcpy

标准C函数'memcpy'如何工作?它必须将(大)RAM块复制到RAM中的另一个区域。因为我知道你不能在汇编中直接从RAM移动到RAM(使用mov指令)所以我猜它在复制时使用CPU寄存器作为中间存储器?

但它如何复制?通过块(如何通过块复制?),按单个字节(char)或它们拥有的最大数据类型(复制在long long double中 - 在我的系统上为12个字节)。

编辑:显然你可以直接将数据从RAM移动到RAM ,我不是汇编专家,我所学的关于汇编的所有内容都来自这个文件(X86 assembly guide)在关于mov指令的部分中,您无法从RAM移动到RAM。显然这不是真的。

3 个答案:

答案 0 :(得分:18)

取决于。一般情况下,你不能在一个周期内物理复制大于最大可用寄存器的任何东西,但这并不是机器如何工作的。实际上,你真的不关心CPU在做什么,而是更关心DRAM的特性。机器的内存层次结构将以尽可能最快的方式执行此副本(例如,您是否正在加载整个缓存行?与复制操作相关的DRAM行的大小是多少?)。实现可能会选择使用某种向量指令来实现memcpy。在没有参考具体实现的情况下,它实际上是一个具有一位缓冲区的逐字节复制。

Here's a fun article描述了一个人对优化memcpy的冒险。主要的观点是,它总是会根据您可以低成本执行的指令针对特定的体系结构和环境。

答案 1 :(得分:8)

memcpy的实现非常特定于实现它的系统。实现通常是硬件辅助的。

内存到内存的移动指令并不常见 - 它们至少在PDP-11次出现,当你可以写这样的东西时:

    MOV FROM, R2
    MOV TO,   R3
    MOV R2,   R4
    ADD LEN,  R4
CP: MOV (R2+), (R3+) ; "(Rx+)" means "*Rx++" in C
    CMP R2, R4
    BNE CP

评论的行大致相当于C的

*to++ = *from++;

当代CPU具有直接实现memcpy的指令:使用源地址和目标地址加载特殊寄存器,调用内存复制命令,让CPU完成其余操作。

答案 2 :(得分:5)

memcpy的一个简单实现是:

 while (n--) *s2++ = *s1++;

glibc通常在汇编代码中使用一些聪明的实现。 memcpy来电通常是内联的。

在x86上,代码检查size参数是2的字面倍数还是4的倍数(使用gcc内置函数)并使用{{1}的循环指令(复制movl字节),否则调用一般情况。

一般情况使用4rep指令使用快速块复制程序集。