memcpy 取虚拟地址还是物理地址?
memcpy takes virtual address or physical address?
我正在处理视频 HAL 应用程序,我正在从 HAL 层获取相机帧回调。在编程过程中,我发现 memcpy 从物理地址复制数据会崩溃,而从 虚拟地址 复制数据是可以的。我搜索了有关 memcpy 的此类信息,但没有找到任何地方,甚至没有在其手册页上找到。
所以,我的问题是 memcpy 需要 物理地址还是虚拟地址 ?有没有提到关于 memcpy 的此类信息?
memcpy
用 C 语言实现或用汇编语言优化。因此,它不关心它获得的地址类型。它只是加载 CPU 寄存器中的地址并执行 mov
指令。
操作系统和内存硬件架构负责将任何逻辑(虚拟)地址映射到物理地址。
另请注意,对于现代 OS/memory 架构,每个进程都有自己的地址 space。在地址 space 之间传递地址将不起作用。
在这些情况下,OS 可能会提供在进程之间交换内存对象(共享或其他方式)的功能。
正如 Paul Ogilvie 正确解释的那样,memcpy
处理用户 space 地址。因此它们是虚拟地址,不一定是物理地址。
然而,通过请求 OS 将一些目标虚拟地址重新映射为映射到的物理内存的副本,具有非常特定对齐特征的非常大的区域有可能优化 memcpy
源地址。这些页面将获得 COPY_ON_WRITE 属性,以确保程序只修改适当数组中的页面,如果它写入任一页面。 GlibC 中 memcpy
的 generic 实现就是这样做的(参见 glibc-2.3.5/sysdeps/generic/memcpy.c
)。但这对于仍然在用户 space.
中提供地址的程序员来说是透明的
我正在处理视频 HAL 应用程序,我正在从 HAL 层获取相机帧回调。在编程过程中,我发现 memcpy 从物理地址复制数据会崩溃,而从 虚拟地址 复制数据是可以的。我搜索了有关 memcpy 的此类信息,但没有找到任何地方,甚至没有在其手册页上找到。 所以,我的问题是 memcpy 需要 物理地址还是虚拟地址 ?有没有提到关于 memcpy 的此类信息?
memcpy
用 C 语言实现或用汇编语言优化。因此,它不关心它获得的地址类型。它只是加载 CPU 寄存器中的地址并执行 mov
指令。
操作系统和内存硬件架构负责将任何逻辑(虚拟)地址映射到物理地址。
另请注意,对于现代 OS/memory 架构,每个进程都有自己的地址 space。在地址 space 之间传递地址将不起作用。
在这些情况下,OS 可能会提供在进程之间交换内存对象(共享或其他方式)的功能。
正如 Paul Ogilvie 正确解释的那样,memcpy
处理用户 space 地址。因此它们是虚拟地址,不一定是物理地址。
然而,通过请求 OS 将一些目标虚拟地址重新映射为映射到的物理内存的副本,具有非常特定对齐特征的非常大的区域有可能优化 memcpy
源地址。这些页面将获得 COPY_ON_WRITE 属性,以确保程序只修改适当数组中的页面,如果它写入任一页面。 GlibC 中 memcpy
的 generic 实现就是这样做的(参见 glibc-2.3.5/sysdeps/generic/memcpy.c
)。但这对于仍然在用户 space.