零拷贝技术

mmap 和 DMA-BUF 在零拷贝技术上的区别

在 Linux 系统中,mmapDMA-BUF 都是实现 零拷贝(Zero-Copy) 的关键技术,但它们的应用场景、设计目标和实现方式有显著差异。以下是两者的对比:


📌 1. 核心概念

技术主要用途适用场景
mmap文件/设备内存 映射到 用户进程虚拟地址空间,允许直接访问。文件 I/O、显存映射、进程间共享内存。
DMA-BUF提供 跨驱动/设备的缓冲区共享框架,允许不同硬件(如 GPU、摄像头、编码器)直接共享内存,无需拷贝。多媒体流水线(如摄像头→GPU→显示器)。

📌 2. 零拷贝的实现方式

(1) mmap 的零拷贝

  • 机制
    通过内存映射,用户进程直接访问 内核管理的物理内存(如文件页缓存、GPU 显存),避免数据在用户态和内核态之间的拷贝。

  • 示例

    • 文件读取mmap 文件后,应用直接读写页缓存,无需 read()/write()
    • GPU 显存:DRM 驱动通过 mmap 将显存映射到用户空间,渲染程序直接操作。
  • 优点

    • 减少 CPU 拷贝开销。
    • 适用于 单设备内 的零拷贝(如 CPU 访问 GPU 显存)。
    • 应用比较广泛,使用大部分简单的zero-copy场合
  • 缺点

    • 无法跨设备共享mmap 的缓冲区通常仅对当前设备有效(如 GPU 显存无法直接用于摄像头硬件)。
    • 缺乏同步机制:需手动处理 CPU/GPU 缓存一致性(如 msync 或 DRM 的原子提交)。

(2) DMA-BUF 的零拷贝

  • 机制

    • DMA-BUF 是一个 共享内存的标准化接口,核心是 struct dma_buf,代表一块可跨设备共享的物理内存。
    • 通过 文件描述符(fd) 传递缓冲区,支持跨进程、跨驱动、跨硬件访问。
    • 依赖 DMABUF HeapsDRM/KMS 分配内存。
  • 示例

    • 摄像头→GPU→显示器流水线
      1. 摄像头驱动分配 DMA-BUF 缓冲区(/dev/dma_heap/system)。
      2. 通过 fd 将缓冲区传递给 GPU 驱动(如 OpenGL/Vulkan)。
      3. GPU 渲染后,同一 fd 传递给显示控制器(KMS)直接输出。
  • 优点

    • 真正的跨设备零拷贝:GPU、VPU、摄像头等硬件直接访问同一块物理内存。
    • 内置同步机制:通过 fence(同步原语)保证设备间读写顺序。
    • 标准化:所有主流 Linux 驱动(DRM、V4L2、Media)均支持 DMA-BUF。
  • 缺点

    • 需要驱动支持(旧硬件可能不兼容)。
    • 用户态需处理 fd 的传递和管理。

📌 3. 关键区别总结

特性mmapDMA-BUF
设计目标用户态直接访问内核内存跨设备/驱动的内存共享
共享范围单进程或进程间(需显式设置)跨进程、跨设备(通过 fd 传递)
同步机制需手动处理(如 msync内置 fence 同步(自动协调设备访问)
硬件支持通用(所有文件/设备)需驱动支持(如 DRM、V4L2)
典型用例文件映射、GPU 显存访问摄像头→GPU→显示器的多媒体流水线
性能减少 CPU 拷贝,但限于单设备真正的跨设备零拷贝

📌 4. 如何选择?

  • mmap

    • 只需要 CPU 访问文件或设备内存(如 GPU 显存)。
    • 不涉及多设备协作。
  • DMA-BUF

    • 需要 多个硬件模块(GPU、摄像头、编码器)共享同一块内存
    • 需要自动同步(如 GPU 渲染完成后,显示器再读取)。

📌 5. 代码示例对比

(1) mmap 实现零拷贝(GPU 显存)

// DRM 分配显存并 mmap 到用户空间
struct drm_mode_create_dumb create_arg = { .width=1920, .height=1080, .bpp=32 };
ioctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);

void *map = mmap(NULL, create_arg.size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd, create_arg.handle);
// 直接操作 map 渲染...

(2) DMA-BUF 实现跨设备零拷贝

// 从 DMA-BUF Heap 分配缓冲区
int dma_heap_fd = open("/dev/dma_heap/system", O_RDWR);
struct dma_heap_allocation_data alloc = { .len = 1024*1024 };
ioctl(dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &alloc);

// 将 fd 传递给 GPU 驱动(如 Vulkan)
VkImportMemoryFdInfoKHR import_info = { .fd = alloc.fd, ... };
vkAllocateMemory(device, &import_info, ...);

// 同一 fd 可传递给其他设备(如摄像头或显示器)

📌 6. 总结

  • mmap
    单设备零拷贝,适合 CPU 直接访问文件或设备内存(如 GPU 显存),但无法跨硬件共享。
  • DMA-BUF
    跨设备零拷贝,通过标准化 fdfence 实现多媒体流水线的高效内存共享。
    现代图形/多媒体栈的核心技术(如 Wayland、GStreamer、ML 推理)。

若需最大化性能(如摄像头→GPU→显示器的 4K 流水线),DMA-BUF 是唯一选择

DMA-buf技术来自Samsung的drm驱动开发人员,提出该框架后很快merge到linux drm主线,并在v4l2,drm等展开应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值