Songqian Li's Blog

去历史上留点故事

image.png

用户层虚拟化

本地 API 拦截和 API formwarding

image.png

  • 在用户态实现一个函数库,假设叫 libwrapper, 它要实现底层库的所有 API;
  • 让 APP 调用这个 libwrapper。如何做?
  • libwrapper 拦截用户的函数调用,对参数进行解析,然后使用参数去调用实际的底层库相同名称的函数。
  • 调用完成后,libwrapper 把结果返回给 APP;

实现关键:

  1. APP 和底层可的静态链接变成动态链接;
  2. libwrapper 使用类似 dlopen 打开底层库;

远程 API forwarding

image.png

  • libwrapper 通过网络,去调用不同机器上的底层库
  • libwrapper 变为两部分
    • client:拦截,转发
    • server:接收,调用

可以实现 GPU 池化:即多个 GPU 可以组成调用池,由多个 client 来调用,可以做到让不具备 GPU 的机器能实现 GPU 的功能
实现关键:

  1. 调用函数类似 RPC,参数需要进行序列化和反序列化;
  2. 相对本机来说,远程数据传输的性能对函数调用的延迟影响很大。一般可以通过 RDMA 进行网络加速。

半虚拟化 API forwarding

image.png

  1. APP 和 libwrapper 运行在虚机中;
  2. libwrapper 通过半虚拟化(virtio)进行通讯,调用宿主机的底层库;
  3. VM 的内核要实现 virtio frontend
  4. Host 的 Hypervisor 要实现 virtio backend
  5. 宿主机完成底层库的调用

内核层虚拟化

内核层 GPU 驱动拦截

image.png
实现原理:内核模块通过设备文件拦截

  • 通常底层库通过设备文件访问 GPU 驱动的功能,假设为/dev/realgpu
  • 实现一个内核模块,输出模拟的设备文件给用户空间,/dev/fakegpu
  • 把模拟的设备文件 bind mount 到容器里,伪装成真的设备文件,/dev/realgpu
  • APP 和底层库都在容器里运行,底层库访问伪装的设备文件/dev/realgpu,此时所有访问被内核模块拦截;

实现关键

  1. 需要了解底层库调用 GPU 驱动的系统调用的含义;
  2. 内核拦截模块只需要拦截必要的系统调用;
  3. 适合容器应用;

内核层 GPU 驱动半虚拟化

image.png
实现原理:GPU 驱动半虚拟化

  • APP 和底层库都在 VM 里;
  • VM 的 GPU 驱动实现半虚拟化接口,通过类似 hpyercall 的方式,调用 Host 实际的 GPU 驱动;
  • hpyercall 切换 guest 到 Hypervisor,Hypervisor 通过内核中的驱动代理来访问实际的 GPU 驱动;

实现关键

  1. 适合 VM 应用;
  2. 结合硬件虚拟化支持类似 vGPU 功能;

硬件虚拟化

全虚拟化/透传 GPU

image.png
全虚拟化,Full Virtualization,又称透传 GPU。

  • 虚机的 GPU 驱动,不需要做任何修改,基本上访 问的是 GPU 真实的硬件资源;
  • 整个 GPU 透传给虚机,性能损耗最小;
  • 因为无法实现 GPU 资源共享,一般认为不属于 GPU 虚拟化。

NVIDIA vGPU

image.png

  • 虚拟机内核需要安装特定的虚拟化驱动:GRID 驱动。
  • 显存按照固定切分,直接分配给 VM;
  • 算力调度采用时分方案,按时间片分配给 VM;

NVIDIA MIG

NVIDIA 硬件切分方案:MIG
image.png

  • MIG:Multi-Instance GPU,NVIDIA 自己退出的硬件资源切分方案。可以直接把 GPU 切分多分,每一份资源硬件隔离;
  • 每一 MIG 的切分,可以当作一个 GPU 来使用,同时可以结合容器来部署;
  • 目前仅在 A30、A100、H100 显卡上支持;

NVIDIA MIG vGPU

MIG 和 vGPU 的结合:NVIDIA MIG vGPU
image.png

  • 显存,算力都按照 MIG 硬件切分,直接分配给 VM;
  • 算力损耗相对 vGPU 小;

AMD MxGPU

基于 SRIOV 方式切分 GPU 为 VF
image.png

Intel GVT-g

类似 Nvidia vGPU
image.png

总结

image.png

参考

相关文章
评论
分享
  • 硬件虚拟化

    硬件虚拟化介绍 硬件虚拟化要做的事情 体系结构支持 体系结构 实现功能 作用 模式切换 Host CPU <-> Guest CPU 切换 CPU 资源隔离 二阶段地址转换 GVA-> GPA...

    硬件虚拟化
  • 《操作系统真象还原》:第十章 输入输出系统

    上一章中我们遇到的字符混乱和 GP 异常问题,根本原因是由于临界区代码的资源竞争,这需要一些互斥的方法来保证操作的原子性。 10.1 同步机制——锁 10.1.1 排查 GP 异常,理解原子操作 多线程执行刷屏时光标值越界导致...

    《操作系统真象还原》:第十章 输入输出系统
  • 《操作系统真象还原》:第九章 线程

    线程和进程将分两部分实现,本章先讲解线程。 9.1 实现内核线程 9.1.1 执行流 在处理器数量不变的情况下,多任务操作系统采用多道程序设计的方式,使处理器在所有任务之间来回切换,这称为“伪并行”,由操作系统中的任务调度器决定当...

    《操作系统真象还原》:第九章 线程
  • 《操作系统真象还原》:第八章 内存管理系统

    8.1 makefile 简介 这部分可参考阮一峰的讲解:https://www.ruanyifeng.com/blog/2015/02/make.html 8.1.1 makefile 是什么 makefile 是 Linu...

    《操作系统真象还原》:第八章 内存管理系统
  • 《操作系统真象还原》:第七章 中断

    7.1 中断是什么,为什么要有中断 运用中断能够显著提升并发,从而大幅提升效率。 7.2 操作系统是中断驱动的 略 7.3 中断分类 把中断按事件来源分类,来自 CPU 外部的中断就称为外部中断,来自 CPU 内部的中断称为内部...

    《操作系统真象还原》:第七章 中断
  • 《操作系统真象还原》:第六章 完善内核

    6.1 函数调用约定简介 咱们实验使用cdecl。这里提一下stdcall,cdecl与stdcall的区别在于由谁来回收栈空间。 stdcall是被调用者清理参数所占的栈空间。 举例来说: 12int subtract(int ...

    《操作系统真象还原》:第六章 完善内核
  • 《操作系统真象还原》:第五章 保护模式进阶——加载内核

    5.3 加载内核 5.3.1 用 C 语言写内核 第一个 C 语言代码: 1234int main(void) { while(1); return 0;} 这个内核文件什么都没做,通过while(1)这个死循...

    《操作系统真象还原》:第五章 保护模式进阶——加载内核
  • 《操作系统真象还原》:第五章 保护模式进阶——内存分页机制

    从这一刻起,我们才算开始了真正的操作系统学习之旅 5.1 获取物理内存容量 5.1.1 Linux 获取内存的方法 在 Linux 2.6 内核总是用detect_memory函数来获取内存容量的。其函数本质上是通过调用 BI...

    《操作系统真象还原》:第五章 保护模式进阶——内存分页机制
  • 《操作系统真象还原》:第四章 保护模式入门

    4.1 保护模式概述 在本章大家会见到全局描述符表、中断描述符表、各种门结构,这是 CPU 提供给应用的,咱们用好就行。 保护模式强调的是“保护”,它是在 Intel 80286 CPU 中首次出现,这是继 8086 之后,Inte...

    《操作系统真象还原》:第四章 保护模式入门
  • 《操作系统真象还原》:第三章 完善MBR——I/O接口

    3.3 让我们对显示器说点什么吧 3.3.1 CPU 如何与外设通信——IO 接口 IO 接口功能: 设置数据缓冲,解决 CPU 与外设的速度不匹配 设置信号电平转换电路 设置数据格式转换 设置时序控制电路来同步 CPU 和外部...

    《操作系统真象还原》:第三章 完善MBR——I/O接口