多个传感器如何连接到一个中断口,两个传感器网断了怎么连在一起

首页 > 实用技巧 > 作者:YD1662023-11-27 11:09:48

当处理器发起一次地址虚实转换请求,内存管理单元会在内部的TLB缓存和Table Walk缓存查找最终页表项和中间表项。如果在内部缓存没找到,那就需要去系统缓存或者内存读取。在最差情况下,每一阶的4层中间表可能都是未命中,4x4 4=20,最终会需要20次内存读取。对于系统内存管理器,情况可能更糟。如上图所示,由于SMMU本身还需引入多级描述符来映射多个页表,最极端情况需要36次的访存才能找到最终页表项。如果所有访问都是这个延迟,显然无法接受。

Arm传统的设计是添加足够大的多级TLB缓存和table walk缓存,效果如下:

多个传感器如何连接到一个中断口,两个传感器网断了怎么连在一起(5)

这是启用2阶地址映射后的实测结果,其各项缓存大小均配置成较大,然后把两个主设备连到接口,进行地址较为随机的访问。可以看到,主设备的5万次访问,在经过SMMU后,产生了近5万次未命中。这意味着访问的平均延迟等于访存延迟,150ns以上。另一方面,处理器开了虚拟机后,它的随机访存效率,和未开虚拟机比,却能做到80%以上,这是为什么呢?答案很简单,处理器内部的MMU,会把中间页表的物理地址继续发到二级或者三级缓存,利用缓存来减少平均延迟。而SMMU就没有这么幸运,在Arm先前的手机处理器参考设计中,并没有系统缓存。这种情况下,即使对于延迟不太敏感的主设备,比如图形处理器,打开虚拟化也会造成性能损失,可能高达9%,这不是一个小数目。

怎么解决这个问题?在Arm服务器以及下一代手机芯片参考设计中,会引入网状结构总线,而不是之前的crossbar结构的一致性总线。网状结构总线的好处,主要是提升了频率和带宽,并且,在提供多核一致性的同时,也可以把系统缓存交给各个主设备使用。不需要缓存的主设备还是可以和以前一样发出非缓存的的数据传输,避免额外占用缓存,引起频繁的缓存替换;同时,SMMU可以把页表和中间页表项放在缓存,从而缩短延迟。

Arm的SMMU600还做了一点改进,可以把TLB缓存贴近各个主设备做布局,在命中的情况下,一个时钟周期就可以完成翻译;同时,把table walk缓存放到另一个地方,TLB缓存和table walk缓存通过内部总线互联。几个主设备可以同时使用一个table walk缓存,减少面积,便于布线的同时,又不失效率。其结构如下图:

多个传感器如何连接到一个中断口,两个传感器网断了怎么连在一起(6)

如果我们读一下Arm的SMMU3.x协议,会发现它是支持双向页表维护信息广播的,这意味着除了缓存数据一致性外,所有的主设备,只要遵循SMMU3.x协议,可以和处理器同时使用一张页表。在辅助驾驶芯片设计时,如果需要,把重要的加速器加入同一张页表,可以避免软件页表更新操作,进一步提高异构计算的效率。不过就SMU600而言,它仅仅支持单向的广播,接了SMU600的主设备,本身的缓存和页表操作并不能广播到处理器,反过来是可以的。

对于当前的汽车芯片,如果没有系统缓存,那如何减少设备虚拟化延迟呢?办法也是有的。汽车的虚拟机应用较为特殊,目前8个虚拟机足够应付所有的分屏和多系统需求,并且一旦分配,运行阶段无需反复删除和生成。我们完全可以利用这点,把二阶段的SMMU页表变大,比如1GB,固定分配给某个虚拟机。这样,设备在进行二阶段地址映射时,只需少数几项TLB表项,就可以做到一直命中,极大降低延迟。需要注意的是,一旦把二阶映射的物理空间分配给某设备,就不能再收回并分给其他设备。不然,多次回收后,就会出现物理地址离散化,无法找到连续的大物理地址了。

SMMU接受的是从主设备发过来的物理地址,那它是怎么来区分虚拟机呢?靠的是同样从主设备发送过来的vmid/streamid。如果主设备本身并不支持虚拟化,那就需要对它进行时分复用,让软件来写入vmid/streamid。当然,这个软件必须运行在hypervisor或者是secure monitor,不然会有安全漏洞。具体的做法,是在虚拟机切换的时候,hypervisor修改寄存器化的vmid/streamid,提供输入给SMMU即可。如果访问时的id和预设的不符,SMMU会报异常给hypervisor。

如果主设备要实现硬件的方式支持虚拟化,那本身需要根据多组寄存器设置,主动发出不同的vmid/streamid。为了对软件兼容,可以把不同组按照4KB边界分开,这样在二阶地址映射时,可以让相同的实地址访问不同组的寄存器,而对驱动透明。同时,对于内部的资源也要做区分,不能让数据互相影响。如果用到缓存,那缓存还必须对vmid敏感,相同地址不同vmid的情况,必须识别为未命中。

如果主设备本身不支持虚拟化,并且本身特别复杂,那还需要定制驱动。以Arm的图形处理器为例,到目前为止,硬件上还没有正式支持虚拟化,如果软件要支持,可能会有以下几种方案:

假设我们用的Hypervisor是Xen,它运行于Arm处理器的EL2,虚拟机运行于EL0/1。正常的图形处理器驱动会分成用户空间与核心空间两部分。要实现虚拟化,时分复用图形处理器,Xen上本身不可能跑驱动,因为目前驱动只支持Linux。所以就只能让虚拟机来跑原先的驱动,而没有办法在hypervisor上再运行一个驱动来进行访问控制。同时,重映射图形处理器在CPU上的二阶段地址,让寄存器访问和数据通路处于‘穿透’的模式,不引起异常,提高效率。相应的,让虚拟机直接访问寄存器,那访问控制就实现不了了。为了实现多虚拟机的调度,我们可以在hypervisor里面实现一个调度器,并且在核心态的驱动部分开放接口,让hypervisor可以主动调度。示意图如下:

多个传感器如何连接到一个中断口,两个传感器网断了怎么连在一起(7)

这个实现的优点很明显,改动较少,实现简单,无论是Xen和KVM都可以适配。缺点是主动权并不掌握在hypervisor,如果某个虚拟机上渲染任务过于繁重,一直不把控制权交给调度器,那只有强制重启。另一个明显的缺点是,无法在图形处理器同时运行两个虚拟机上的任务。这就需要另一种虚拟机的实现方式,如下图:

多个传感器如何连接到一个中断口,两个传感器网断了怎么连在一起(8)

上一页12345下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.