带你读《弹性计算技术指导及场景应用》——1. 单实例上运行Linux桌面多开解决方案(1):https://developer.aliyun.com/article/1423692
使用EGL Backend
使用EGL Backend时,Host上不用安装Xorg、xfce4、x11vnc等组件,只需要安装NVIDIA驱动,创建容器时,也不用将X11的unix socket目录(/tmp/.X11-unix)映射给容器访问。
Host安装与设置
Host上安装与配置步骤如下:
∙ 安装NVIDIA驱动;
∙ 安装nvidia-docker2;
∙ 下载NVIDIA官方docker镜像(比如nvidia/cuda:14.3-base-ubuntu18.04);
∙ 启动容器(启动时,不需要将/tmp/.X11-unix映射到容器中);
容器安装与设置
容器中安装与配置步骤如下:
∙ 安装桌面环境(本文安装xfce4);
∙ 从VirtualGL官方网站下载VirtualGL和TurboVNC安装包进行安装;
∙ 配置VirtualGL:/opt/VirtualGL/bin/vglserver_config -config +s +f +t
∙ 安装NVIDIA用户态驱动(容器中安装驱动时,不要安装内核态驱动),命令示例:./NVIDIA-Linux-x86_64-470.80run -a -q --ui=none --no-kernel-module
∙ 启动运行TurboVNC:
export TVNC_VGLRUN="vglrun -d egl0 +wm"
/opt/TurboVNC/bin/vncserver -wm xfce -vgl -geometry 1920x1080 -depth 24
其中egl0表示第一个GPU;
性能测试
glmark2测试结果
分别在Host上和Container中,使用glmark2软件,设置不同的2D X Server(DISPLAY环境变量)以及不同的Backend(vglrun命令的-d参数),测试跑分,结果如下表所示。
编号 |
测试 位置 |
Xfce4 Backend |
使用VirtualGL |
测试命令 |
画面 输出 |
GPU 使用率 |
glmark2 CPU使用率 |
Host Xorg CPU使用率 |
Xvnc CPU 使用率 |
glmark2 得分 |
1 |
Host |
/ |
否 |
DISPLAY=:0 glmark2 |
Host(:0) |
100% |
100% |
400% |
0.00% |
11350 |
2 |
Host |
GLX |
是 |
DISPLAY=:0 vglrun -d :0 glmark2 |
Host(:0) |
79% |
45% |
900% |
0.00% |
849 |
3 |
Host |
GLX |
是 |
DISPLAY=:1 vglrun -d :0 glmark2 |
Host(:1) |
39% |
105% |
4.00% |
67.00% |
2086 |
4 |
Host |
GLX |
是 |
DISPLAY=:0 vglrun -d egl glmark2 |
Host(:0) |
83% |
53% |
98.00% |
0.00% |
902 |
5 |
Host |
GLX |
是 |
DISPLAY=:1 vglrun -d egl glmark2 |
Host(:1) |
39% |
107% |
0.00% |
64.00% |
1851 |
6 |
Host |
EGL |
是 |
DISPLAY=:0 vglrun -d :0 glmark2 |
Host(:0) |
81% |
46% |
900% |
0.00% |
842 |
7 |
Host |
EGL |
是 |
DISPLAY=:1 vglrun -d :0 glmark2 |
Host(:1) |
39% |
104% |
4.00% |
69.00% |
2041 |
8 |
Host |
EGL |
是 |
DISPLAY=:0 vglrun -d egl glmark2 |
Host(:0) |
82% |
53% |
98.00% |
0.00% |
899 |
9 |
Host |
EGL |
是 |
DISPLAY=:1 vglrun -d egl glmark2 |
Host(:1) |
39% |
105% |
0.00% |
66.00% |
1844 |
10 |
Container |
/ |
否 |
DISPLAY=:0 glmark2 |
Host(:0) |
100% |
100% |
47.00% |
0.00% |
11204 |
11 |
Container |
GLX |
是 |
DISPLAY=:0 vglrun -d :0 glmark2 |
Host(:0) |
89% |
60% |
100% |
0% |
962 |
12 |
Container |
GLX |
是 |
DISPLAY=:1 vglrun -d :0 glmark2 |
Container(:1) |
39% |
105% |
4% |
68% |
2052 |
13 |
Container |
GLX |
是 |
DISPLAY=:0 vglrun -d egl glmark2 |
Host(:0) |
89% |
92% |
99% |
0% |
1522 |
14 |
Container |
GLX |
是 |
DISPLAY=:1 vglrun -d egl glmark2 |
Container(:1) |
39% |
106% |
0% |
62% |
1862 |
15 |
Container |
EGL |
是 |
DISPLAY=:0 vglrun -d :0 glmark2 |
Host(:0) |
89% |
61% |
98% |
0% |
951 |
16 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d :0 glmark2 |
Container(:1) |
39% |
105% |
4% |
64% |
2012 |
17 |
Container |
EGL |
是 |
DISPLAY=:0 vglrun -d egl glmark2 |
Host(:0) |
89% |
92% |
99% |
0% |
1519 |
18 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d egl glmark2 |
Container(:1) |
39% |
106% |
0% |
64% |
1837 |
GpuTest测试结果
编号 |
测试位置 |
Xfce4 Backend |
使用VirtualGL |
测试命令 |
画面输出 |
GPU总使用率 |
GpuTest CPU使用率 |
Host Xorg CPU使用率 |
Xvnc CPU使用率 |
得分 |
FPS |
19 |
Host |
/ |
否 |
DISPLAY=:0 ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Host(:0) |
100.00% |
100.00% |
88.00% |
0.00% |
15730 |
262 |
20 |
Host |
/ |
否 |
DISPLAY=:0 ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Host(:0) |
100.00% |
100.00% |
86.10% |
0.00% |
15540 |
259 |
21 |
Host |
/ |
否 |
DISPLAY=:0 ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Host(:0) |
100.00% |
100.00% |
87.10% |
0.00% |
15230 |
253 |
22 |
Container |
GLX |
是 |
DISPLAY=:1 vglrun -d egl ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
800% |
96.00% |
0.00% |
280% |
14816 |
246 |
23 |
Container |
GLX |
是 |
DISPLAY=:1 vglrun -d egl ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
800% |
97.00% |
0.00% |
280% |
14838 |
247 |
24 |
Container |
GLX |
是 |
DISPLAY=:1 vglrun -d egl ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
79.00% |
97.00% |
0.00% |
200% |
14788 |
246 |
25 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d egl ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
80.00% |
97.00% |
0.00% |
200% |
14814 |
246 |
26 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d egl ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
78.00% |
97.00% |
0.00% |
200% |
14828 |
247 |
27 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d egl ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
79.00% |
100.00% |
0.00% |
20.80% |
14819 |
246 |
28 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d :0 ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
78.00% |
99.00% |
0.00% |
24.80% |
14739 |
245 |
29 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d :0 ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
77.00% |
100.00% |
0.00% |
280% |
14699 |
244 |
30 |
Container |
EGL |
是 |
DISPLAY=:1 vglrun -d :0 ./GpuTest /test=gi /width=1600 /height=900 /benchmark |
Container(:1) |
79.00% |
100.00% |
0.00% |
24.80% |
14625 |
243 |
测试结果示例:
GravityMark测试结果
编号 |
测试位置 |
Xfce4 Backend |
使用VirtualGL |
API |
Asteroids |
GPU 使用率 |
GravityMark CPU使用率 |
Xorg CPU 使用率 |
Xvnc CPU 使用率 |
得分 |
FPS |
每帧时间(ms) |
31 |
Host |
/ |
否 |
Vulkan |
1000000 |
98.0% |
0% |
48.0% |
0.0% |
10408 |
63 |
16.051 |
32 |
Host |
/ |
否 |
Vulkan |
200000 |
90% |
7.0% |
36.0% |
0.0% |
29705 |
177.9 |
5.621 |
33 |
Host |
/ |
否 |
OpenGL |
1000000 |
100.0% |
100.0% |
28.7% |
0.0% |
2963 |
17.7 |
56.497 |
34 |
Host |
/ |
否 |
OpenGL |
200000 |
100.0% |
94.1% |
68.3% |
0.0% |
19659 |
117.7 |
8.496 |
35 |
Container |
EGL |
是 |
Vulkan |
1000000 |
87.0% |
97.0% |
0% |
19.8% |
10217 |
62 |
16.340 |
36 |
Container |
EGL |
是 |
Vulkan |
200000 |
70% |
90% |
0% |
29.7% |
24312 |
145.6 |
6.868 |
37 |
Container |
EGL |
是 |
OpenGL |
1000000 |
99.0% |
100.0% |
0% |
10.0% |
3046 |
18.2 |
54.945 |
38 |
Container |
EGL |
是 |
OpenGL |
200000 |
90% |
100% |
20.8% |
19.8% |
18659 |
117 |
8.953 |
GravityMark的其他设置如下:
∙ Render: Default
∙ Antialiasing: Default(Temporal)
∙ Resolution: 1600x900
∙ LOD Bias: Default
测试结果示例:
测试结果分析及结论
以下分别针对OpenGL和Vulkan测试结果进行分析。
OpenGL性能
1) 使用TurboVNC比使用Xorg作为2D X Server性能更好
测试2对比3、4对比5、6对比7、8对比9、11对比12、13对比14、15对比16、17对比18,可以得出结论,VirtualGL将画面输出到TurboVNC相比输出到Host上的Xorg,性能显著更好,GPU占用率也更低,这是得益于TurboVNC的优化;
2) 使用TurboVNC作为2D X Server时,EGL Backend和GLX Backend的性能差距非常小
测试25、26、27对比测试28、29、30显示,使用TurboVNC作为2D X Server时,EGL Backend和GLX Backend性能差距非常小,约为2%以内;
3) TurboVNC启动Xfce4时使用的Backend对性能几乎没有影响
测试3对比7、5对比9、12对比16、14对比18,可以得出结论,TurboVNC启动Xfce4时使用的Backend(即TVNC_VGLRUN环境变量设置的Backend)对性能几乎没有影响;
4) 当GPU测试软件测试过程中帧率非常高时,VirtualGL给测试软件带来的结果波动很大;当帧率接近实际使用场景时,VirtualGL带来的损耗非常小;
测试1、10对比其他测试,可以看到,使用VirtualGL时,最好的性能也只有不使用VirtualGL时的18%,对于这个性能损耗,VirtualGL作者在Github Issues(Performance loose?、Slow performance without ssh (same machine))中有解释,glmark2测试显示的性能损耗主要来自于VirtualGL引入的framebuffer read back。glxgears、glmark2等GPU测试软件的主要原理是,渲染大量的三角形,并测试GPU的极限渲染帧率,而VirtualGL需要在应用程序完成一帧渲染的时候,回读framebuffer,并(通过TurboVNC)传输给客户端显示,因此导致了极限帧率的巨大下降。glmark2测试过程中的部分日志如下:
在Host上直接运行glmark2时:
root@aliyun:/etc/X11# glmark2 ======================================================= glmark2 2014.03+git2015061fa71af2d ======================================================= OpenGL Information GL_VENDOR: NVIDIA Corporation GL_RENDERER: NVIDIA A10/PCIe/SSE2 GL_VERSION: 4.6.0 NVIDIA 470.801 ======================================================= [build] use-vbo=false: FPS: 9187 FrameTime: 0.109 ms … ======================================================= glmark2 Score: 11350 =======================================================
在Container中通过VirtualGL运行glmark2时:
root@desktop2-glx:/home# DISPLAY=:1 vglrun -d egl0 glmark2 ======================================================= glmark2 2014.03+git2015061fa71af2d ======================================================= OpenGL Information GL_VENDOR: NVIDIA Corporation GL_RENDERER: NVIDIA A10/PCIe/SSE2 GL_VERSION: 4.6.0 NVIDIA 470.801 ======================================================= [build] use-vbo=false: FPS: 1442 FrameTime: 0.693 ms … ======================================================= glmark2 Score: 1837 =======================================================
可以看到,VirtualGL导致每帧的时间从0.109ms增加到了0.693ms,因此引起了结果的巨大降低,但是,增加的时间对普通应用来说,是微不足道的,普通应用的刷新率通常为60Hz,每帧时间的最大值可以达到16.67ms,VirtualGL增加的这部分时间(0.584ms)相对于16.67ms是非常小的。
测试38对比34,可以看到,在FPS为110左右时,VirtualGL带来的损耗约为5%(1-117/117.7);测试37对比33,可以看到,当帧率非常低时,VirtualGL带来的性能损耗被淹没在帧率本身的波动中了,甚至出现了使用VirtualGL比不使用VirtualGL性能更好的情况;
Vulkan性能
测试35对比31显示,当FPS在60左右时,VirtualGL带来的Vulkan性能损耗在2%以内(1-62/63);测试36对比32显示,在FPS为150左右时,VirtualGL带来的Vulkan性能损耗约为18%(1-145.6/177.9)。
总体结论:
Multiseat方案配置复杂,受硬件限制较大,不适合作为产品方案。
Xephyr和Xpra方案由于没有GPU加速,也不适合作为产品方案。
使用VirtualGL方案,可以很好地在阿里云异构实例上实现Linux桌面多开,多开的桌面之间互不影响,多个用户可分别使用VNC客户端连接自己的桌面运行业务软件。VirtualGL会给渲染的每一帧增加耗时,但是,在通常使用场景(刷新率60Hz)下,VirtualGL带来的OpenGL和Vulkan开销均在5%以内。
VirtualGL使用EGL Backend时,还可以不依赖于X11 Server,Host上只需要安装显卡驱动,无需额外软件,部署非常方便。
此外需要注意的是,由于TurboVNC在启动的时候设置了独立的dbus session并自动拉起了启动桌面环境,虽然本文是在一个容器中启动一个桌面,并不意味着桌面和容器是一一对应的,用户如果对桌面以及业务软件之间的安全隔离性没有要求,完全可以在一个容器中,或者直接在Host环境上,多次运行以下命令来 开启多个独立的xfce桌面:
export TVNC_VGLRUN="vglrun -d egl0 +wm" /opt/TurboVNC/bin/vncserver -wm xfce -vgl -geometry 1920x1080 -depth 24
Linux桌面多开最佳实践
Linux桌面多开最佳方案为VirtualGL方案(配合使用TurboVNC)。
对于VirtualGL方案,由于使用GLX Backend需要将Host的X11 socket目录(/tmp/.X11-unix)映射到容器中,多个容器同时使用时,有潜在的冲突风险和安全风险,因此,建议参考5.2使用EGL Backend,Host上只需要安装NVIDIA驱动,相关设置都在容器中,方便备份和迁移。
如果用户业务软件在渲染时,不需要实时显示,软件会将最终结果输出到文件,那么,可以在运行软件的时候设置"VGL_READBACK=none"以获得最好的性能,命令示例:
DISPLAY=:1 VGL_READBACK=none vglrun -d egl0 glmark2
设置"VGL_READBACK=none"后,应用软件的窗口是黑屏,VirtualGL的framebuffer read back引入的性能影响将会被消除。