程序员开发实例大全宝库

网站首页 > 编程文章 正文

软件和硬件中的调用(三)(软件和硬件怎么结合)

zazugpt 2024-10-19 16:30:34 编程文章 16 ℃ 0 评论

4 软硬件之间的调用

4.1 生产者消费者模型

生产者消费者问题(Producer-Consumer Problem)是多进程同步问题的经典案例之一,描述了共享固定大小缓冲区的两个进程,即所谓的“生产者”和“消费者”,在实际运行时如何处理交互的问题。

如图18所示,生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者不会在缓冲区中空时消耗数据。

图18 经典生产者消费者模型

解决问题的基本办法是:让生产者在缓冲区满时休眠,等到消费者消耗缓冲区中的数据,从而缓冲区有了空闲区域的时候,生产者才能被唤醒,开始继续往缓冲区添加数据;同样,也需要让消费者在缓冲区空时进入休眠,等到生产者往缓冲区添加数据之后,再唤醒消费者继续消耗数据。

4.2 软硬件的接口定义

粗略地说,软硬件接口是由驱动(Driver)和设备(Device)组成,驱动和设备的交互也即软件和硬件的交互。更确切一些地说,软硬件接口包括交互的驱动软件、硬件设备的接口部分逻辑,也包括内存中的共享队列,还包括传输控制和数据信息的总线。

图19 软硬件接口硬件架构示意模型

如图19所示,是软硬件接口硬件架构的示意模型。软硬件接口的组件详细介绍如下:

  • 驱动软件。驱动是提供一定的接口API,让上层的软件能够更加方便地与硬件交互。驱动负责硬件设备控制面的配置、运行控制以及设备数据面的数据传输控制等。驱动屏蔽硬件的接口细节,对上层软件提供标准的API函数接口。驱动屏蔽硬件细节,提供标准API给上层软件。通过不同版本的驱动,既可以屏蔽硬件细节,又可以跟不同的操作系统平台兼容。
  • 设备硬件接口子模块,包括DMA和内部缓冲。高速的设备一般都有专用的DMA,专门负责数据搬运。驱动会通知DMA共享队列状态信息,然后DMA会读取内存中的共享队列描述符,并根据描述符信息负责在CPU内存和内部缓冲之间搬运数据。
  • 共享队列。特定的跟硬件DMA格式兼容的共享队列数据结构,软件和硬件通过共享队列交互数据。每个共享队列包括队列的头和尾指针、组成队列的各个描述符项以及每个描述符项所指向的实际的数据块。
  • 传输的总线:软硬件交互可以说是上层功能,需要底层接口总线的承载。例如,在片内通常是通过AXI-Lite总线来实现软件对硬件的寄存器读写控制,而数据总线则是通过AXI实现硬件DMA对软件的CPU内存的读写访问。

4.3 软硬件接口演进

软硬件接口是在I/O接口基础上的扩展,结合I/O交互的四种模式,重新梳理一下软硬件接口的演进:

  • 第一阶段,使用软件轮询硬件状态。最开始是通过软件轮询,这时候软件和硬件的交互非常简单。发送的时候,软件会定期查询硬件的状态,当发送缓冲为空的时候,就把数据写入到硬件的缓存寄存器;接收的时候,软件会定期查询硬件的状态,当接收缓冲区有数据的时候,就把数据读取到软件。
  • 第二阶段,使用中断模式。随着CPU的性能快速提升,统计发现,轮询的失败次数很高,大量的CPU时间被浪费在硬件状态查询而不是数据传输,因此引入中断模式。只有当发送缓冲存在空闲区域可以让软件存放一定量待发送数据的时候,或者接收缓冲已经有一定量数据待软件接收的时候,硬件会发起中断,CPU收到中断后进入中断服务程序,在中断服务程序里处理数据的发送和接收。
  • 第三阶段,引入DMA。前面的两种情况下,都需要CPU来完成数据的传输,依然会有大量的CPU消耗。因此引入了专用的数据搬运模块DMA来完成CPU和硬件之间的数据传输,某种程度上,DMA可以看作用于代替CPU进行数据搬运的加速器。发送的时候,当数据在CPU内存准备好,CPU告诉DMA源地址和数据的大小,DMA收到这些信息后主动把数据从CPU内存搬到硬件内部。同样的,接收的时候,CPU开辟好一片内存空间并告知DMA目标地址和空间的长度,DMA负责把硬件内部的数据搬运到CPU内存。
  • 第四阶段,专门的共享队列。引入了DMA之后,如果只有一片空间用于软件和硬件之间的数据交换,则软件和硬件之间的数据交换则是同步的。例如在接收的时候,当DMA把数据搬运到CPU内存之后,CPU需要马上进行处理并释放内存,CPU处理的时候DMA则只能停止工作。后来引入了乒乓缓冲的机制,当一个内存缓冲区用于DMA传输数据的时候,另一个缓冲区的数据由CPU进行处理,实现DMA传输和CPU处理的并行。更进一步的,演变成更多缓冲区组成的循环缓冲队列。这样,CPU的数据处理和DMA的数据传输则完全异步的完成,并且CPU对数据的处理以及DMA对数据的搬运都可以批量操作完成后,再同步状态信息给对方。
  • 第五阶段,用户态的软件轮询共享队列驱动。进一步的,随着带宽和内存的增加,导致数据频繁的在用户态应用程序、内核的堆栈、驱动以及硬件之间交互,并且缓冲区也越来越大,这些都不可避免的增加系统消耗,并且带来更多的延迟;而且,数据交互频繁,导致的中断的开销也是非常庞大的。因此,通过用户态的PMD(Polling Mode Driver,轮询模式驱动)可以高效的在硬件和用户态的应用程序直接传递数据,不需要中断,完全绕开内核,以此来提升性能和降低延迟。
  • 第六阶段,支持多队列。随着硬件设计规模扩大,硬件资源越来越多,在单个设备里,可以通过多队列的支持,来提高并行性。驱动也需要加入对多队列的支持,这样我们甚至可以为每个应用程序配置专用的队列或队列组,通过多队列的并行性来提升性能和应用数据的安全性。

4.4 软硬件接口的范例:NVMe

NVMe(Non-Volatile Memory Express)是经过优化的、高性能的、可扩展的主机控制器接口,专为非易失性存储器(NVM)技术而设计。NVMe解决了如下一些性能问题:

  • 带宽:通过支持PCIe和诸如RDMA和光纤之类的通道,NVMe可以支持比SATA或SAS高很多的带宽。
  • IOPS:例如,串行ATA可能的最大IOPS为20万,而NVMe设备已被证明超过100万IOPS。
  • 延迟:NVM以及未来的存储技术具有一微秒以内的访问延迟,需要一种更简洁的软件协议,能够实现包括软件堆栈在内的不超过10毫秒的端到端延迟。

NVMe协议支持多个深度队列,这是对传统SAS和SATA协议的改进。典型的SAS设备在单个队列中最多支持256个命令,而SATA设备最多支持32个命令。这些队列深度对于传统的硬盘驱动器技术已经足够,但不能充分利用NVM技术的性能。

相比之下,图20所示的NVMe多队列,每个队列支持64K命令,最多支持64K队列。这些队列的设计使得I/O命令和对命令的处理不仅可以在同一处理器内核上运行,也可以充分利用多核处理器的并行处理能力。每个应用程序或线程可以有自己的独立队列,因此不需要I/O锁定。NVMe还支持MSI-X和中断控制,避免了CPU中断处理的瓶颈,实现了系统扩展的可伸缩性。NVMe采用简化的命令集,相比SAS或SATA,NVMe命令集使用的处理I/O请求的指令数量减少了一半,从而在单位CPU指令周期内可以提供更高的IOPS,并且降低主机中I/O软件堆栈的处理延迟。

图20 NVMe多队列

NVMe的驱动和设备交互跟Virtio不同:Virtio是在通过一个队列完成双向通知交互;而NVMe则采用提交队列和完成队列配合完成双向交互的方式。

如图21所示,NVMe队列处理流程如下(其中主机为软件驱动,控制器为硬件设备):

  1. 主机写命令到提交队列项中。
  2. 主机写DB(Doorbell)寄存器,通知控制器有新命令待处理。
  3. 控制器从内存中的提交队列中读取命令。
  4. 控制器执行命令。
  5. 控制器更新完成队列,表示当前的SQ项已经处理。
  6. 控制器发MSI-x中断到主机CPU。
  7. 主机处理完成队列,同步更新提交队列中的已处理项。
  8. 主机写完成队列Db到控制器,告知完成队列项已释放。

图21 NVMe队列处理流程

NVMe是为了高速非易失性存储定制的存储接口访问协议,定向优化了存储的主要性能指标:带宽、延迟和IOPS。NVMe最重要的特征体现在:

  • 面向高速存储场景定制:NVMe是专门面向高速存储场景定制的协议,因此充分考虑了块存储的特点,重点解决存储性能的关键问题。
  • 多队列支持:多队列不仅仅充分利用了硬件的并行处理能力,同时,也充分的利用了多核系统多线程并行的特点,最大化的优化了NVMe的性能。
  • 标准化:NVMe是得到广泛应用的PCIe SSD接口标准,各大主流操作系统支持统一的标准NVMe驱动。

4.5 基于接口的调用

我们以分层的任务之间调用为例,分层的部分任务是在硬件中完成,构建任务分层软硬件执行的模型,要求其相互之间的调用关系和接口保持不变。

图22 把任务卸载到硬件的简化模型

如图22所示,为分层任务调用的系统。通过把部分任务卸载(相对于在软件执行)到硬件中,来加速系统的运行。其中,双向箭头的上方为调用方,箭头的下方为被调用方。这样,系统任务在软硬件执行,涉及到的调用有四类:

  • 软件对软件的调用,任务0调用任务1,软件调用在第2章进行了讲解;
  • 硬件对硬件的调用:任务2调用任务3,硬件调用在第3章进行了讲解;
  • 软件对硬件的调用:任务1调用任务2,这部分即本章软硬件接口的讲解,通过驱动和设备接口共同组成软硬件接口,然后在此之上再封装软件API接口层驱动,保证任务调用接口的一致性。
  • 硬件对软件的调用:任务3调用任务4,技术原理跟软件对硬件调用相同,区别在于谁主谁从的问题。

5 总结

一个复杂的系统,通过分解成简单的模块或层次(软件实现或硬件实现),再通过基于各种连接的调用把他们重新连接成一个整体。

软件中有调用,硬件中也有调用,软件和硬件之间也需要通过调用来进行通信和交互。

调用无处不在!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表