背景

工作学习要用 Ubuntu,打游戏要用 Windows,双系统的方案开关机不太方便,而且也不是很稳定,这一点在读研期间就尝试过。

听说 WSL2 可以在 Hyper-V 上直接运行 Linux(微软定制版 kernel),性能比 WSL1 有了很大提升。

所以本文要测试一下在 Windows 11 上的 WSL2 和原生 Windows 11 系统上进行深度学习训练的性能差异。

B 站视频中也查到了相关的测试,基本上是 WSL2 比 Windows 11 快很多,百分之25?

但本着求真务实的态度,还是自己测试一下。

Background

For work and study I need Ubuntu; for gaming I need Windows. The dual-boot approach is inconvenient to switch between and not very stable either — I tried that during grad school.

I heard that WSL2 can run Linux directly on Hyper-V (with Microsoft’s customized kernel), with a big performance boost over WSL1.

So this article tests the performance difference in deep learning training between WSL2 on Windows 11 and native Windows 11.

I also found related tests in Bilibili videos — basically WSL2 is much faster than Windows 11, 25%?

But in the spirit of seeking truth from facts, I decided to test it myself.

测试环境

硬件配置

参考这里关于配置选择的内容。

系统环境

  1. Windows 11

Windows 11 系统信息

  1. WSL2(Ubuntu 24.04)

wsl 版本:

1
2
3
4
5
6
7
8
PS C:\Users\wgxls> wsl --version
WSL 版本: 2.4.13.0
内核版本: 5.15.167.4-1
WSLg 版本: 1.0.65
MSRDC 版本: 1.2.5716
Direct3D 版本: 1.611.1-81528511
DXCore 版本: 10.0.26100.1-240331-1435.ge-release
Windows 版本: 10.0.26100.4061

Linux 版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@wgxls-desktop:~# neofetch
.-/+oossssoo+/-. root@wgxls-desktop
`:+ssssssssssssssssss+:` ------------------
-+ssssssssssssssssssyyssss+- OS: Ubuntu 24.04.2 LTS on Windows 10 x86_64
.ossssssssssssssssssdMMMNysssso. Kernel: 5.15.167.4-microsoft-standard-WSL2
/ssssssssssshdmmNNmmyNMMMMhssssss/ Uptime: 1 hour, 20 mins
+ssssssssshmydMMMMMMMNddddyssssssss+ Packages: 886 (dpkg)
/sssssssshNMMMyhhyyyyhmNMMMNhssssssss/ Shell: bash 5.2.21
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Theme: Adwaita [GTK3]
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Icons: Adwaita [GTK3]
ossyNMMMNyMMhsssssssssssssshmmmhssssssso Terminal: vscode
ossyNMMMNyMMhsssssssssssssshmmmhssssssso CPU: AMD Ryzen 7 9700X (16) @ 3.799GHz
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ GPU: 45bb:00:00.0 Microsoft Corporation Basic Render Driver
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Memory: 1383MiB / 31250MiB
/sssssssshNMMMyhhyyyyhdNMMMNhssssssss/
+sssssssssdmydMMMMMMMMddddyssssssss+
/ssssssssssshdmNNNNmyNMMMMhssssss/
.ossssssssssssssssssdMMMNysssso.
-+sssssssssssssssssyyyssss+-
`:+ssssssssssssssssss+:`
.-/+oossssoo+/-.

软件环境

  1. python 环境

python 版本使用的是 3.10,没有使用更高的版本是担心我的老代码可能不兼容。

cuda 版本都使用的 12.8,没有在系统环境中安装什么 cuda 和 cudnn,直接使用 pytorch 的包管理器安装。

1
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
  1. 测试代码

测试代码使用我的毕业论文代码,我手上可以拿来直接跑的就只有这一份。

我总共进行了 2 次测试,分别是 1 个 epoch 和 50 个 epoch 的训练。

测试一: 测试 50 个 epoch 的训练时间

训练的过程其实就是 2 个 for 循环,外层循环是 epoch,内层循环是每个 batch 的训练。

训练数据总共是 800 张图像,每个 batch 的大小是 8,所以每个 epoch 有 100 次迭代。

我在代码中记录了开始和结束时间。

1
2
3
4
5
6
7
8
9
10
def train(config):
...
start_time = time.time() # 记录开始时间
for epoch in range(config.num_epochs):

for iteration, data in enumerate(train_loader):
...
optimizer.step()
end_time = time.time() # 记录结束时间
print(f"Total training time for {config.num_epochs} epochs: {end_time - start_time:.2f} seconds")

测试二: 测试 1 个 epoch 的训练时间

同样的代码,只是将 config.num_epochs 改为 1。

更改了记录开始和结束时间的位置如下:

1
2
3
4
5
6
7
8
9
10
def train(config):
...

for epoch in range(config.num_epochs):
start_time = time.time() # 记录开始时间
for iteration, data in enumerate(train_loader):
...
optimizer.step()
end_time = time.time() # 记录结束时间
print(f"Total training time for {config.num_epochs} epochs: {end_time - start_time:.2f} seconds")

下文介绍结果时会解释为什么我还要测试 1 个 epoch 的训练时间。

: 按网上的说法,WSL2 访问 Windows 文件系统的速度很慢,所以在测试WSL2 时,我将数据集放在了 WSL2 的文件系统中,而不是 Windows 的文件系统中。

测试结果

测试一: 测试 50 个 epoch 的训练时间

结果如下:

  • Windows 11: Total training time for 50 epochs: 1298 seconds
  • WSL2: Total training time for 50 epochs: 944 seconds

WSL2 比 Windows 11 快 37.5%

测试过程中我发现在 Windows 11 系统中,在每个 epoch 结束时,GPU 的使用率会下降到 0%,并且要等待较长一段时间(相比每个 batch 的时间)才会恢复到正常的使用率。

Windows 11 GPU占用

而在 WSL2 中,也有 GPU 使用率下降的情况,但下降的幅度和时间都比 Windows 11 短很多。

WSL2 GPU占用

我没有深入调查这个现象的原因,但我猜测可能是 Windows 11 在每个 epoch 结束时会进行一些额外的操作,所以我又进行了测试二,只测试一个 epoch 的训练时间。

测试二: 测试 1 个 epoch 的训练时间

结果如下:

  • Windows 11: Total training time for 1 epochs: 25.83 seconds
  • WSL2: Total training time for 1 epochs: 18.86 seconds

WSL2 比 Windows 11 快 36.95%

结果竟然和测试一的结果差不多,WSL2 依然比 Windows 11 快很多。

2025-08-03 补充:

放弃 WSL,转向『LSW』 中,我使用 Ubuntu 24.04 原生 Linux 系统测试了深度学习训练性能,结果显示原生 Linux 系统的性能最好。

总结

WSL2 在深度学习训练性能上确实比 Windows 11 快很多,约为 37% 左右。

考虑到 WSL2 和 Windows 11 之间的交互非常丝滑,如果你平时对 Linux 的需求主要在于一些应用层的开发和测试,WSL2 是一个非常不错的选择。基本上是开箱即用。

但如果你对 Linux 的需求是在系统层面工作,比如驱动开发、内核模块开发等,WSL2 可能就不太适合了。

因为我发现这个 kernel 里面 lsmod 竟然什么都没有。

1
2
root@wgxls-desktop:~# lsmod
Module Size Used by

要么放弃 Windows,用原生 Linux 系统。

要么尝试折腾 https://github.com/microsoft/WSL2-Linux-Kernel

Test Environment

Hardware Configuration

See the configuration selection here.

System Environment

  1. Windows 11

Windows 11 system info

  1. WSL2 (Ubuntu 24.04)

wsl version:

1
2
3
4
5
6
7
8
PS C:\Users\wgxls> wsl --version
WSL 版本: 2.4.13.0
内核版本: 5.15.167.4-1
WSLg 版本: 1.0.65
MSRDC 版本: 1.2.5716
Direct3D 版本: 1.611.1-81528511
DXCore 版本: 10.0.26100.1-240331-1435.ge-release
Windows 版本: 10.0.26100.4061

Linux version:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@wgxls-desktop:~# neofetch
.-/+oossssoo+/-. root@wgxls-desktop
`:+ssssssssssssssssss+:` ------------------
-+ssssssssssssssssssyyssss+- OS: Ubuntu 24.04.2 LTS on Windows 10 x86_64
.ossssssssssssssssssdMMMNysssso. Kernel: 5.15.167.4-microsoft-standard-WSL2
/ssssssssssshdmmNNmmyNMMMMhssssss/ Uptime: 1 hour, 20 mins
+ssssssssshmydMMMMMMMNddddyssssssss+ Packages: 886 (dpkg)
/sssssssshNMMMyhhyyyyhmNMMMNhssssssss/ Shell: bash 5.2.21
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Theme: Adwaita [GTK3]
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Icons: Adwaita [GTK3]
ossyNMMMNyMMhsssssssssssssshmmmhssssssso Terminal: vscode
ossyNMMMNyMMhsssssssssssssshmmmhssssssso CPU: AMD Ryzen 7 9700X (16) @ 3.799GHz
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ GPU: 45bb:00:00.0 Microsoft Corporation Basic Render Driver
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Memory: 1383MiB / 31250MiB
/sssssssshNMMMyhhyyyyhdNMMMNhssssssss/
+sssssssssdmydMMMMMMMMddddyssssssss+
/ssssssssssshdmNNNNmyNMMMMhssssss/
.ossssssssssssssssssdMMMNysssso.
-+sssssssssssssssssyyyssss+-
`:+ssssssssssssssssss+:`
.-/+oossssoo+/-.

Software Environment

  1. Python environment

Python version 3.10 is used; I didn’t use a newer version out of concern that my old code might be incompatible.

CUDA version 12.8 is used for both. I didn’t install any system-wide CUDA or cuDNN, using pytorch’s package manager instead.

1
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
  1. Test code

The test code is from my graduation thesis; it’s the only piece I have on hand that can run directly.

I ran the test twice in total — training for 1 epoch and 50 epochs.

Test 1: Training time for 50 epochs

The training process is basically 2 for loops: the outer loop is over epochs, and the inner loop is the training over each batch.

The training data consists of 800 images total, with a batch size of 8, so each epoch has 100 iterations.

I recorded the start and end times in the code.

1
2
3
4
5
6
7
8
9
10
def train(config):
...
start_time = time.time() # Record start time
for epoch in range(config.num_epochs):

for iteration, data in enumerate(train_loader):
...
optimizer.step()
end_time = time.time() # Record end time
print(f"Total training time for {config.num_epochs} epochs: {end_time - start_time:.2f} seconds")

Test 2: Training time for 1 epoch

Same code, just changing config.num_epochs to 1.

The start/end time recording positions were changed as follows:

1
2
3
4
5
6
7
8
9
10
def train(config):
...

for epoch in range(config.num_epochs):
start_time = time.time() # Record start time
for iteration, data in enumerate(train_loader):
...
optimizer.step()
end_time = time.time() # Record end time
print(f"Total training time for {config.num_epochs} epochs: {end_time - start_time:.2f} seconds")

The reason why I also tested the 1-epoch training time will be explained in the results section below.

Note: According to what’s said online, WSL2 accessing the Windows filesystem is very slow, so when testing WSL2, I put the dataset in WSL2’s own filesystem instead of the Windows filesystem.

Test Results

Test 1: Training time for 50 epochs

Results:

  • Windows 11: Total training time for 50 epochs: 1298 seconds
  • WSL2: Total training time for 50 epochs: 944 seconds

WSL2 is 37.5% faster than Windows 11

During testing I found that in Windows 11, at the end of each epoch, GPU utilization drops to 0% and takes a long time (compared to the per-batch time) to recover to normal utilization.

Windows 11 GPU usage

In WSL2, GPU utilization also drops, but the magnitude and duration are much smaller than Windows 11’s.

WSL2 GPU usage

I didn’t investigate the cause of this phenomenon deeply, but I guess Windows 11 performs some extra operations at the end of each epoch, so I ran Test 2 — training time for just one epoch.

Test 2: Training time for 1 epoch

Results:

  • Windows 11: Total training time for 1 epochs: 25.83 seconds
  • WSL2: Total training time for 1 epochs: 18.86 seconds

WSL2 is 36.95% faster than Windows 11

The result is surprisingly similar to Test 1 — WSL2 is still much faster than Windows 11.

2025-08-03 update:

In Abandoning WSL for ‘LSW’, I tested deep learning training performance on native Ubuntu 24.04 Linux, and the results showed that native Linux delivers the best performance.

Summary

WSL2 is indeed much faster than Windows 11 for deep learning training — about 37% faster.

Considering how smooth the interaction between WSL2 and Windows 11 is, if your Linux needs are mainly application-level development and testing, WSL2 is a great choice — basically out-of-the-box.

But if your Linux needs are at the system level — such as driver development or kernel module development — WSL2 may not be suitable.

Because I found that lsmod in this kernel shows absolutely nothing.

1
2
root@wgxls-desktop:~# lsmod
Module Size Used by

Either give up Windows and use native Linux.

Or try tinkering with https://github.com/microsoft/WSL2-Linux-Kernel