适用于Linux 2的Windows子系统上的CUDA
适用于Linux 2的Windows子系统上的CUDA
Announcing CUDA on Windows Subsystem for Linux 2
为了响应大众的需求,微软在2020年5月的构建会议上宣布了WindowsSubsystem for Linux2(WSL2)的一个新特性——GPU加速。这一特性为许多计算应用程序、专业工具和工作负载打开了大门,目前只有Linux才有,但现在可以在Windows上按原样运行,并从GPU加速中获益。
最重要的是,NVIDIA CUDA加速度现在来到了WSL。在这篇文章中,将讨论在WSL 2的公共预览中对CUDA的期望。
What is WSL?
WSL是Windows 10的一个特性,使能够直接在Windows上运行本机Linux命令行工具,而不需要复杂的双引导环境。在内部,WSL是一个与Microsoft Windows操作系统紧密集成的容器化环境。这使得可以在传统的Windows桌面和现代商店应用程序的同时运行Linux应用程序。
WSL主要是开发人员的工具。如果正在Linux容器中处理计算工作负载,则可以使用熟悉的本地Linux工具在Windows PC上本地开发和测试工作负载。通常,这些应用程序需要大量的黑客、第三方框架和库才能在Windows系统上运行。所有这些都随WSL 2而改变,WSL 2为Windows世界带来了完整的Linux内核支持。
借助WSL 2和GPU半虚拟化(GPU-PV)技术,微软正在为Windows上的Linux支持添加另一个功能,允许运行针对GPU硬件的计算工作负载。在本文后面,将更详细地介绍WSL 2以及GPU是如何添加到其中的。
有关更多信息,请参见DirectX进入Windows Linux子系统和GitHub中的WSL2 Linux Kernel/driver/gpu目录。
CUDA in WSL
要利用WSL 2中的GPU,目标系统必须安装支持Microsoft WDDM模型的GPU驱动程序。这些驱动程序由NVIDIA等GPU硬件供应商提供。
CUDA允许编程NVIDIA GPU。几十年来,在Windows图形中的WDDM模型中得到了支持。新的Microsoft WSL 2容器提供了GPU加速,CUDA可以利用在WSL内部运行CUDA工作负载。有关更多信息,请参阅《关于WSL的CUDA用户指南》。
在WSL中对CUDA的支持包含在针对WDDM 2.9模型的NVIDIA显示驱动程序中。只需要在Windows主机上安装驱动程序。WSL中的CUDA用户模式驱动程序(利布达)自动映射到容器内并添加到该容器的加载程序搜索路径中。
NVIDIA驱动程序开发团队为CUDA驱动程序添加了对WDDM模型和GPU-PV的支持,以便能够在Windows上的Linux上运行。仍然是一个预览驱动程序,在Windows 10中WSL的官方GPU支持发布之前不会发布。有关该版本的更多信息,请参阅CUDA WSL 2下载。
图2显示了如何将CUDA驱动程序插入Linux客户机中的新WDDM模型的简单图。

Figure 1. Stack image showing layers involved while running Linux AI frameworks in WSL 2 containers.

Figure 2. A diagram of the WDDM model supporting CUDA user mode driver running inside Linux guest.
如果是从Microsoft Windows Insider程序的Fast Ring(build 20149或更高版本)在最新的Windows版本上安装了WSL发行版并将容器设置为以WSL 2模式运行的开发人员,并且如果是PC中NVIDIA GPU的受启发所有者,则可以尝试该驱动程序并在WSL 2中运行工作负载。只需在Windows主机操作系统上安装驱动程序,然后打开WSL容器。CUDA将在那里与CUDA应用程序一起工作,而不需要任何额外的努力。图3显示了在WSL 2容器中运行CUDA TensorFlow工作负载的屏幕截图。

WSL中的GPU为当前仅在本机Linux环境中运行的各种CUDA计算应用程序打开了大门。
英伟达仍在积极地进行这一项目,并作出调整。除此之外,正在努力将以前特定于Linux的api引入WDDM层,以便越来越多的应用程序可以开箱即用地处理WSL。
另一个焦点是表现。如前所述,WSL 2 GPU支持极大地利用了GPU-PV,可以影响较小的GPU工作负载,而无需任何流水线。现在,正在尽可能减少这些开销。
NVML
NVML不包含在初始驱动程序包中,对此存在一些问题。为了解决这个问题,计划将NVML和其库一起引入WSL。
首先启动了核心CUDA驱动程序,让可以在这个早期预览中尝试大部分现有的工作负载。意识到一些容器和应用程序甚至在加载CUDA之前就利用NVML查询GPU信息。这就是为什么把NVML放在WSL的首要任务中。请继续关注此主题的更多更新。
GPU containers in WSL
除了DirectX和CUDA支持之外,NVIDIA还在WSL 2中添加了对NVIDIA容器工具包(以前是NVIDIA-docker2)的支持。数据科学家准备在Linux本地硬件下运行或在云中执行的容器化GPU工作负载,现在可以在Windows PC上的WSL2中运行。
不需要特定的WSL包。NVIDIA运行时库(libnvidia容器)可以动态检测libdxcore,并在具有GPU加速的WSL 2环境中运行时使用。这是在Docker和NVIDIA容器工具包包安装之后自动发生的,就像在Linux上一样,允许GPU加速的容器以开箱即用的方式运行。
建议使用Docker工具的最新版本(19.03或更高版本),以利用对--gpus选项的额外支持。要启用WSL 2支持,请按照针对Linux发行版的GitHub repo上的自述步骤进行操作,并安装可用的最新版本。
那么是如何工作的呢?所有特定于WSL 2的工作都由libnvidia容器库处理。这个库现在能够在运行时检测libdxcore.so文件并用来检测所有暴露在这个接口上的gpu。
如果需要在容器中使用这些gpu,则使用以下命令查询驱动程序存储的位置:包含Windows主机和WSL 2的所有驱动程序库的文件夹libdxcore.so文件. 这取决于libnvidia-container设置容器以便正确映射驱动程序存储,并为WSL 2 GPU支持的核心库进行设置,如图4所示。

Figure 4. Discovery and mapping scheme used by libnvidia-container.so on WSL 2.
而且,这与WSL之外使用的逻辑不同。这完全是由libnvidia-container.so抽象出来的-对最终用户来说应该尽可能透明。此早期版本的一个限制是在多GPU环境中缺少GPU选择:容器中始终可见所有GPU。
以下是可以在WSL容器中运行的内容:目前熟悉的任何NVIDIA Linux容器。NVIDIA支持专业人士使用的大多数现有Linux工具和工作流。从NVIDIA NGC下载最喜欢的容器工作负载并进行尝试。
在下一节中,将描述如何在WSL 2中运行TensorFlow和n-body容器,同时使用NVIDIA GPUs加速工作负载。
Running the N-body container
使用Docker安装脚本安装Docker:
user@PCName:/mnt/c$ curl https://get.docker.com | sh
安装NVIDIA容器工具包。从nvidia-docker2 v2.3和底层运行库libnvidia container 1.2.0-rc.1开始,就提供了WSL 2支持。
建立稳定的实验库和GPG密钥。支持WSL 2的运行时更改在实验存储库中可用。
user@PCName:/mnt/c$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
user@PCName:/mnt/c$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
user@PCName:/mnt/c$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
user@PCName:/mnt/c$ curl -s -L https://nvidia.github.io/libnvidia-container/experimental/$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list
安装NVIDIA运行时包及其依赖项:
user@PCName:/mnt/c$ sudo apt-get update
user@PCName:/mnt/c$ sudo apt-get install -y nvidia-docker2
打开WSL容器并在那里启动Docker守护进程。应该看到dockerd服务输出。
user@PCName:/mnt/c$ sudo dockerd
physical GPU (device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1)" src="file:///C:/Users/JIANMI~1.HAS/AppData/Local/Temp/msohtmlclip1/01/clip_image010.gif" border="0" v:shapes="图片_x0020_13">

Figure 5. Starting the Docker daemon.
在另一个WSL容器窗口中,下载并启动N-body仿真容器。确保用户有足够的权限下载容器。可能需要在sudo中运行以下命令。GPU在输出中突出显示。
user@PCName:/mnt/c$ docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark

Figure 6. Starting the N-body simulation container.
Running the TensorFlow container
尝试另一个流行的容器:WSL 2中Docker中的TensorFlow。
下载TensorFlow Docker图像。为了避免Docker连接问题,该命令在sudo中运行。
user@PCName:/mnt/c$ docker pull tensorflow/tensorflow:latest-gpu-py3
保存稍微修改过–使用主机驱动器C上TensorFlow教程中的GPU,默认情况下,该驱动器在WSL2容器中映射为/mnt/C。
user@PCName:/mnt/c$ vi ./matmul.py
import sys
import numpy as np
import tensorflow as tf
from datetime import datetime
device_name = sys.argv[1] # Choose device from cmd line. Options: gpu or cpu
shape = (int(sys.argv[2]), int(sys.argv[2]))
if device_name == "gpu":
device_name = "/gpu:0"
else:
device_name = "/cpu:0"
tf.compat.v1.disable_eager_execution()
with tf.device(device_name):
random_matrix = tf.random.uniform(shape=shape, minval=0, maxval=1)
dot_operation = tf.matmul(random_matrix, tf.transpose(random_matrix))
sum_operation = tf.reduce_sum(dot_operation)
startTime = datetime.now()
with tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(log_device_placement=True)) as session:
result = session.run(sum_operation)
print(result)
# Print the results
print("Shape:", shape, "Device:", device_name)
print("Time taken:", datetime.now() - startTime)
在GPU和CPU上运行此脚本的结果如下所示,该脚本是从安装的驱动器C启动的。为了简单起见,减少了输出。
user@PCName:/mnt/c$ docker run --runtime=nvidia --rm -ti -v "${PWD}:/mnt/c" tensorflow/tensorflow:latest-gpu-jupyter python /mnt/c/matmul.py gpu 20000

Figure 7. Running the matmul.py script.
当在WSL 2容器中使用GPU进行先前的计算场景时,会有显著的加速。
下面是另一个演示,看看GPU加速的工作:Jupyter笔记本教程。当容器启动时,应该会看到打印到笔记本服务器的链接。
user@PCName:/mnt/c$ docker run -it --gpus all -p 8888:8888 tensorflow/tensorflow:latest-gpu-py3-jupyter

Figure 8. Launching the Jupyter notebook.
现在应该可以在Jupyter笔记本上运行演示示例了。连接到笔记本时,请小心使用Microsoft Edge浏览器中的localhost,而不是127.0.0.1。
导航到tensorflow教程并运行分类.ipynb笔记本。
要查看Windows PC的GPU加速的工作,请导航到“单元格”菜单,选择“全部运行”,然后检查Jupyter笔记本的WSL 2容器中的日志。
physical GPU (device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1)" src="file:///C:/Users/JIANMI~1.HAS/AppData/Local/Temp/msohtmlclip1/01/clip_image018.gif" border="0" v:shapes="图片_x0020_27">

Figure 9. The Jupyter notebook log.
这个演示和这个容器中的其一些演示突出了小提交的虚拟化层当前的开销问题,前面也提到过。与这些玩具模型相关联的提交会导致GPU运行时比同步开销本身要短。在WSL 2上的这些极小型模型案例中,CPU时间可能比GPU时间更好。目前正在对其进行优化,并应仅限于较小的非流水线工作负载。
WSL overview
为了了解GPU是如何添加到WSL 2的,现在讨论Windows上的Linux是什么以及硬件是如何暴露给容器的。
微软在2016年的构建会议上引入了WSL。很快获得了发展势头,并成为Linux开发人员中的一个流行工具,希望在运行Linux开发工具和目标工作负载的同时运行Office等Windows应用程序。
WSL 1允许运行未修改的Linux二进制文件。但是,仍然使用Linux内核仿真层,是作为NT内核内的子系统实现的。该子系统通过将来自Linux应用程序的调用转发到相应的Windows 10功能来处理这些调用。
WSL 1是一个很有用的工具,但并不兼容所有的Linux应用程序,因为需要模拟可能每个Linux系统调用。一般来说,文件系统的访问也很慢,这导致了一些实际应用程序无法接受的性能。
考虑到这一点,微软决定走另一条路,推出了WSL 2,一个新版本的WSL。WSL 2容器在虚拟化环境中运行完整的Linux发行版,同时仍然充分利用Windows 10新容器系统的优点。 虽然使用Windows 10的Hyper-V服务,WSL 2仍然不是一个传统的VM,而是一个轻量级的实用VM。该实用程序管理虚拟地址备份内存,允许wsl2容器从主机Windows系统动态分配内存。
WSL 2的一些主要目标是提高文件系统性能并支持完全的系统调用兼容性。还具有更好的整体Windows主机系统集成。允许从Windows shell到运行在容器内的Linux系统的快捷方式,以及对自动装载到容器文件系统的选定目录的主机文件系统的访问。
WSL2作为WindowsInsider程序的预览功能启用,并作为最新的Windows10更新版本2004发布。
在最新的Windows版本中,WSL 2容器有了更多的改进,从网络堆栈到底层存储VHD。描述所有细节将超出本文的范围。有关WSL 2容器的一些有趣和令人兴奋的新特性的更多信息,请参阅比较wsl2和WSL 1。
WSL 2 Linux kernel
WSL 2中的Linux内核是由微软基于kernel.org网站. 这个内核专门针对WSL 2进行了调整,针对大小和性能进行了优化,以在Windows上提供Linux体验。内核由Windows Update提供服务,这意味着无需自己管理即可获得最新的安全修复和内核改进。
微软在WSL中支持几个Linux发行版。遵循开放源代码社区的规则,WSL2内核源代码是公共的,可以在WSL2 Linux内核GitHub repo上使用,其中包含允许系统与Windows 10主机集成所需的修改。
GPU in WSL
微软开发人员正在通过GPU-PV技术将真正的GPU硬件支持引入WSL 2容器,在那里OS图形内核(dxgkrnl)将运行在guest VM内的用户模式组件调用封送到主机上的内核模式驱动程序。
在独立硬件供应商(IHV)的帮助下,微软开发了这项技术,作为其WDDM图形驱动程序模型的一项功能。NVIDIA图形驱动程序自Windows操作系统的Windows Insider程序中的功能预览早期起就支持GPU-PV。所有当前支持的NVIDIA gpu都可以暴露给运行在Hyper-V VM guest中的Windows操作系统。
对于WSL 2能够利用GPU-PV的能力,微软必须在Linux客户机中实现其图形框架的基础:使用GPU-PV协议的WDM模型。新的微软驱动程序支持Linux上的WDDM模型dxgkrnl。还可以作为WSL2 Linux内核GitHub repo中的源代码项目使用。
dxgkrnl驱动程序有望为WDDM 2.9版本的wsl2容器带来对GPU加速的支持。微软解释说,dxgkrnl是一个基于GPU-PV协议的Linux GPU驱动程序,与同名的Windows驱动程序没有任何共同之处。
目前,可以下载预览版的NVIDIA WDDM 2.9驱动程序。在接下来的几个月里,NVIDIA WDDM 2.9驱动程序将从Windows Update的WIP版本中分发,这使得手动下载和安装驱动程序变得不必要。
GPU-PV in a nutshell
dxgkrnl驱动程序在Linux guest中将新的/dev/dxg设备公开给用户模式。D3DKMT内核服务层已经在Windows上提供,也作为dxcore库的一部分被移植到Linux上。使用一组私有IOCTL调用与dxgkrnl通信。
来宾Linux版本的dxgkrnl使用多个虚拟机总线通道连接到Windows主机上的dxg内核。主机上的dxg内核对待Linux进程提交的方式与运行在WDDM模型中的本地Windows应用程序提交进程的方式相同。将发送到KMD(一个特定于IHV的内核模式驱动程序),KMD准备并将提交给硬件GPU。图10显示了这种通信信道的简化图。

Figure 10. A simplified diagram showing Windows host components backing the new graphics dxg device in Linux guest.
NVIDIA驱动程序在许多版本中都支持Windows 10 GPU-PV和Windows来宾。NVIDIA GPU可用于在所有使用Microsoft虚拟化层的最终用户Windows 10应用程序中加速计算和图形,并使用GPU-PV功能添加vGPU:
11显示了在NVIDIA GeForce GTX 1070 GPU上的Windows沙盒容器中运行示例DirectX应用程序的示例。

Figure 11. Windows Sandbox container gets GPU acceleration on an NVIDIA GeForce GTX 1070 GPU.
User mode support
为了在WSL中启用图形,Windows图形团队还将一个用户模式组件移植到Linux:dxcore。
dxcore库提供了一个API函数,用于枚举系统中符合WDDM的图形适配器。旨在作为Windows和Linux中DXGI适配器枚举的跨平台、低级替代品。还使用D3DKMT层API抽象了对dxgkrnl服务(Linux上的IOCTLs和Windows上的GDI调用)的访问,CUDA和其依赖WSL中WDDM模型支持的用户模式组件使用该API。
据微软称,dxcore(libdxcore.so文件)库将在Windows和Linux上都可用。NVIDIA计划在驱动程序中添加对DirectX 12和cudapi的支持,目标是WDDM 2.9模型的新WSL特性。两个API库都将链接到dxcore,以便可以指示dxg内核将请求封送到主机上的KMD。
Try it today
如果想使用Windows PC在Linux环境中进行真正的ML和AI开发,WSL中对CUDA的支持将为带来一个令人兴奋的机会。WSL是Docker CUDA容器被证明是数据科学家中最流行的计算环境之一。
加入Microsoft Windows Insider程序以访问启用GPU加速的WSL 2预览。
下载最新的NVIDIA驱动程序,安装,并尝试在WSL 2中运行CUDA容器化工作负载。
适用于Linux 2的Windows子系统上的CUDA的更多相关文章
- Linux 2 的 Windows 子系统上发布 CUDA
Linux 2 的 Windows 子系统上发布 CUDA 为响应大众需求,微软 宣布 在 2020 年 5 月的 建造 大会上推出了 建造 ( WSL 2 ) – GPU 加速功能.这一特性为许多计 ...
- 在Linux的Windows子系统上(WSL)使用Docker(Ubuntu)
背景 平时开发大部人都是在提供了高效GUI的window下工作,但是真正部署环境普遍都是在Linux中,所以为了让开发环境和部署环境统一,我们需要在windows模拟LInux环境,以前我们可能通过虚 ...
- linux挂载远程windows服务器上的ISO,给内网的服务器安装软件
原文: http://blog.csdn.net/chagaostu/article/details/45195817 给内网的服务器安装软件 直接用yum install XXX的话,会告知找不到源 ...
- 【Linux】在Win10上搭建WSL(适用于Linux的Windows子系统)
1.打开WSL ,控制面板 -- 程序 -- 程序和功能 -- 打开或关闭Windows功能 - 选中[适用于Linux的Windows子系统] 2.开启后重启电脑 3.在Win10自带的Micro ...
- 【ASP.NET Core】准备工作:在 Windows 10 上配置 Linux 子系统
ASP.NET Core 其实比传统的 ASP.NET 要简单很多,而且也灵活很多,并且可以跨平台独立运行. 在 Windows 平台上,我们只要在安装 Visual Studio 的时候选择跨平台的 ...
- 适用于Linux的windows子系统
Windows基于图形界面的易用性是有目共睹的,这也是很多普通用户往往难以舍弃的原因.但是Linux系统更强大的网络应用开发能力,却又是Windows系统所无法比拟的.一直以来,很多人都在试图采用各种 ...
- Windows Azure 上 Linux VM 中的交换空间 – 第 2 部分
本文章由 Azure CAT 团队的 Piyush Ranjan (MSFT) 撰写. 在前一篇文章 Windows Azure 上Linux VM 中的交换空间第 1 部分中,我介绍了在默认情况下, ...
- 在Windows Azure上配置VM主备切换(1)——Linux篇
对任何一个上线系统来说,高可用设计是不可或缺的一个环节,这样才可以确保应用可以持续.稳定的运行,而不是频繁的掉线.停机.高可用设计的核心思路很简单,就是消除一切单点故障,将单点链路或者节点升级为多点. ...
- svn从Windows服务器上迁移到Linux上
svn从Windows服务器迁移到Linux服务器 author:headsen chen 2017-10-16 16:50:32 个人原创,转载请注明.否则依法追究法律责任 ...
随机推荐
- 从苏宁电器到卡巴斯基(后传)第03篇:我与鱼C论坛的是是非非
前言与铺垫 当我刚读研一的时候,对自己的未来还是非常迷茫的.尽管我读的是数字媒体技术专业,但是我对这一行根本就不感兴趣,对于平面设计.三维建模以及游戏引擎的使用这一类知识根本就不会,也不太想学(由于我 ...
- LA4851餐厅(求好的坐标的个数)
题意: 有一个m*m的格子,左下角(0,0)右上角(m-1,m-1),网格里面有两个y坐标相同的宾馆(A,B),每个宾馆里面有一个餐厅,一共用n个餐厅,第1,2个都在宾馆里,3,4...在 ...
- MS08_067漏洞攻击
MS08_067 MS08_067是典型的缓冲区溢出漏洞,Windows的Server服务在处理特制RPC请求时存在缓冲区溢出漏洞,远程攻击者可以通过发送恶意的RPC请求触发这个溢出,导致完全入侵用户 ...
- [CTF]凯撒密码
[CTF]凯撒密码 --------------------- 作者:___Blue_H 来源:CSDN 原文:https://blog.csdn.net/qq_37653144/article ...
- Day009 冒泡排序
冒泡排序 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序! 冒泡排序的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知. 我们看到嵌套循环,应该立马就可以得出这个算法的 ...
- Spring-Cloud之Ribbon原理剖析
我们知道Ribbon主要的工作就是进行负载均衡,帮助我们无需再关注微服务中集群的地址信息,因此在源码剖析中我们就主要关注这部分的内容. 内置的负载均衡规则 RoundRobinRule:直接轮询的方案 ...
- 中文NER的那些事儿2. 多任务,对抗迁移学习详解&代码实现
第一章我们简单了解了NER任务和基线模型Bert-Bilstm-CRF基线模型详解&代码实现,这一章按解决问题的方法来划分,我们聊聊多任务学习,和对抗迁移学习是如何优化实体识别中边界模糊,垂直 ...
- 运行程序显示丢失“MSVCR100D.dll”
前言 写了一个Dll注入工具,结果发现程序在其他机器上会出现丢失"MSVCR100D.dll".这个dll是vs2010自带的动态链接库,如果在没安装vs2010运行库的电脑中使用 ...
- opencv——图像直方图与反向投影
引言 在图像处理中,对于直方图这个概念,肯定不会陌生.但是其原理真的可以信手拈来吗? 本文篇幅有点长,在此列个目录,大家可以跳着看: 分析图像直方图的概念,以及opencv函数calcHist()对于 ...
- 简单了解 MySQL 中相关的锁
本文主要是带大家快速了解 InnoDB 中锁相关的知识 为什么需要加锁 首先,为什么要加锁?我想我不用多说了,想象接下来的场景你就能 GET 了. 你在商场的卫生间上厕所,此时你一定会做的操作是啥?锁 ...