Page 335 - 《软件学报》2020年第10期
P. 335
高珑 等:并行帧缓存设备:基于多核 CPU 的 Xorg 并行显示优化 3311
主事件循环中的客户端请求还没有处理完,X 就难以及时处理用户在下一个循环中的交互输入并做出响应.在
CPU 单核性能较弱或者系统重负载的情况下,这种串行处理方式将会使 X 的交互体验变得很差.如果在军事指
挥控制等领域出现这种情况,将可能导致严重的后果.
针对这种问题的并行化优化的思路主要有两个方向.
(1) 在步骤③中让 X 尽快并行处理完客户端程序的请求,如图形绘制请求等,本文主要按此方向展开讨论
和研究;
(2) 多个子线程同时并行处理主事件循环,该方向思路将在第 5.3 节中简要地加以讨论.
1.2 帧缓存设备
帧缓存设备是从 Linux 内核 2.2 版本开始引入的,被广泛应用在嵌入式领域 [7−13] .帧缓存设备对应内存或者
GPU 显存的一部分存储空间,如图 4(a)中阴影部分所示.这部分空间内放置的数据恰好对应于屏幕上显示的图
像,Xorg 通过向帧缓存设备写入数据完成绘制操作,进而画出各种图形,大量绘制时 CPU 负载较重.与之相对应,
在 GPU 硬件加速模式中,CPU 则仅完成 GPU 指令和数据在内存的设置工作,随后由 GPU 完成剩余的图形绘制,
CPU 负载较轻,如图 4(b)所示.
CPU CPU GPU
GPU
显存
内存 显存 内存
(a) 帧缓存设备 (b) GPU 硬件加速
Fig.4 Frame buffer device and hardware accelerated
图 4 帧缓存设备和 GPU 硬件加速
由于 CPU 性能的不断提高,帧缓存设备的性能也不断提高.同时,由于很多现代 CPU 指令集中也逐步加入
了支持多媒体和图形图像处理的 SIMD 指令 [14−19] ,例如 Intel 指令集中的 MMX 指令和 SSE 指令 [20−22] 、AMD
指令集中的 3DNow!指令 [23,24] 、ARM 指令集中的 NEON 指令 [25,26] 等,使得很多现代 CPU 在图形图像处理方面
也有长足进步,CPU 逐步获得较高的图形绘制能力.例如:SSE 指令在 Geometry Processing 中可以获得接近 4 倍
的性能提升 [22] ;使用 ARM 的 NEON 指令优化后,不少应用的性能可以提高 4~8 倍 [27] ,包括 X 的绘制函数
fbCompositeSolidMask 的速度也提高了 8 倍 [27] .由于在 pixman 函数库中通常已经包含对于 SSE 和 NEON 等
SIMD 指令的汇编指令级优化,所以 X 一般通过直接调用优化过的 pixman 图形函数库来利用这些 CPU 的 SIMD
指令.另外,一般由于业界的 GPU 大厂商,如 AMD、Nvidia、ARM 等都不完全开放 GPU 驱动源码和硬件接口
协议,导致 Linux桌面上的 GPU 驱动发展相对滞后,性能相对 Windows 的商业闭源 GPU 驱动低很多,在国产 CPU
领域尤其如此.所以在某些嵌入式场景中,X 使用帧缓存设备获得的性能甚至超过 X 使用开源 GPU 驱动所获得
的性能 [28,29] .
在多核 CPU 上进一步提升帧缓存设备的性能,需在多核 CPU 上针对帧缓存设备开发线程级并行处理
(thread level parallelism,简称 TLP) [30,31] .即:在多核之间同时并行处理数千条以上规模的指令序列 [32] ,才能有效
弥补核间通信与同步的开销.
1.3 矩形填充
图形上下文 GC(graphics context)是 X 中所有绘制操作的核心数据结构,所有的基本图形绘制都要通过 GC
来完成.与文件系统读写操作类似,每一个 GC 都有一组相对应的 GCOps 函数指针来完成图形绘制.GCOps 包含
画点、画线、画矩形、画椭圆、传输拷贝等 20 余种绘制操作函数指针.对于帧缓存设备来说,所有的绘制操作,
都是通过 CPU 逐个改变像素点来实现的.对于其中任意一种绘制操作的并行优化,原理上对于其他绘制操作都
是适用的.本文主要针对矩形填充操作进行优化,其他绘制操作可以用类似的方法来实现.