多核编程模型
执行并行任务
一个多核程序是由多个任务组成的。通常来讲,这些任务在程序开始时启动,并一直运行下去——尽管XCore架构也允许有临时的任务。 每个任务都是一个普通的函数。一个任务函数通常包含一些一次性的设置,然后是一个永不结束的循环,不断地处理来自一个或多个资源的事件。程序中的每个任务都在自己的核心上运行,这意味着在单个tile上可以执行的任务数量有一个硬性限制。当一个系统中有太多概念上的“事件监听器”而无法给每个都分配一个核心时,XCore架构允许对事件进行复用和解复用。这实际上是允许多个任务在单个核心上协作运行。
基于通道的通信
XCore架构和编程模型中的一个关键概念是基于通道的通信。在这种模型中,当两个任务需要通信时,它们通过一个通道连接起来。实际上这意味着每个任务控制一个chanend资源,代表它在通道中的一端。在交换任何信息之前,两个任务都必须进入一个交易状态——也就是说:发送操作会阻塞,直到接收端准备好;接收操作会阻塞,直到数据被发送。当一个通道端尝试向另一个发送数据时,会自动在网络中创建一条路由,并且通常在交易结束时“拆除”。
下图显示了如何将一组由通道连接的任务放置在一对tile上:
基于事件的编程
通常,一个任务会根据一个或多个外部事件来执行相应的操作,例如GPIO引脚上的值发生变化或者通过通道从另一个任务接收数据。事件在XCore架构的硬件层面得到了支持:它们由能够产生事件的资源生成,并且在概念上类似于中断。
- 每个能够产生事件的资源都有一个触发条件,而这个条件通常是可以配置的。当一个资源的触发条件发生时,一个事件就在这个资源上“变得可用”。
- 每个这样的资源都有一个“事件向量”,它类似于中断向量,是处理这个事件的代码的地址。
- 与中断不同的是,只有当核心进入一个明确的等待状态时,才会将控制权转移到事件处理程序。在这一点上,任何可用 的事件都可能被处理,但任何其他等待的事件仍然可用,以便下次核心进入等待状态时处理。如果在核心进入等待状态时没有事件可用,它就会暂停,直到有事件变得可用(同时这个事件会立即被处理)。
这种基于事件的模型简化了应用程序代码,因为它严格控制了可以运行事件处理代码的时间点。
中断的事件处理程序可能会在任何时候运行,所以与中断相比,这种模型使代码更容易理解和调试。我们知道事件处理程序只会在select进入等待状态时运行,因此可以专注于那个时间点。这也使得优化执行时间和提高性能变得更加简单。我们可以精确地知道事件处理程序需在多长时间内完成,以避免延迟对其他事件的响应。