7. AI Engine Kernel and Graph Programming
异步缓冲区端口访问
在某些情况下,如果您没有在每次调用内核时消耗相当于缓冲区端口的数据,或者如果您没有在每次调用时产生相当于缓冲区端口的数据,那么您可以通过在内核函数原型中使用BRAC声明BRAC缓冲区端口来声明内核端口来控制缓冲区同步。下面的例子说明了内核简单的使用:
· ifm:同步输入缓冲区端口。
· wts:异步输入缓冲器端口。
· ofm:异步输出缓冲器端口。
下面的声明通知编译器在进入内核时忽略名为wts的缓冲区的同步。在使用读/写迭代器/引用访问缓冲区端口之前,必须使用内核代码中显示的缓冲区端口同步成员函数,如下所示。
缓冲区对象wts的acquire()成员函数执行适当的同步和初始化,以确保缓冲区端口对象可用于读取或写入。此函数跟踪要在内部获取的适当缓冲区指针和锁,即使缓冲区端口在AI Engine处理器之间共享并且可以进行双缓冲。此函数可以在动态控制下无条件或有条件地调用,并且可能是一个阻塞操作。您有责任确保稍后执行相应的release()成员函数(甚至可能在随后的内核调用中),以释放与该缓冲区对象关联的锁。不正确的同步会导致代码中的死锁。
重要提示!对异步缓冲区的操作应在获得缓冲区后进行。例如,在acquire()API之后声明缓冲区迭代器。
在下面的示例中,位于tile 1中的内核在每次运行时请求三次锁获取(写访问)。位于瓦片2中的内核在每次运行时请求两次锁获取(读访问)。
锁的获取和释放是一个仅限内核的过程。主要功能不是处理缓冲区同步;缓冲区同步是用户的责任。瓦片1中的内核请求三次对乒乓缓冲区的访问,瓦片2中的内核仅请求两次。为了平衡访问次数,每个迭代中,区块1应该运行两次,区块2应该运行三次。
如图所示,锁定获取交替发生在ping缓冲区和pong缓冲区上。缓冲液选择是自动的。此时不需要用户决定。锁获取的最小延迟是内核停止的七个时钟周期。如果缓冲区不可用于获取,则内核将暂停更长时间(如图中红色所示),直到缓冲区可用。根据应用程序的不同,可能存在ping和/或pong缓冲区根本不锁定的时间间隔。
对于异步缓冲端口,内核的缓冲端口由获取和释放API显式获取和释放。异步输出缓冲区可以在内核内部的任何时候由释放API释放,无论内核将多少样本写入缓冲区。在端口被释放后,异步输出缓冲区可以由其消费者内核获取,也可以由DMA传输到其目的地,如PLIO。
缓冲区端口数据类型
从缓冲区端口访问数据
缓冲端口迭代器
对于缓冲区端口数据访问,支持迭代器来执行读或写操作。此外,基于向量的迭代器在缓冲区端口中得到支持。
迭代器是一个对象,它可以遍历缓冲区中的数据并提供对单个数据的访问。缓冲区端口对象支持多个迭代器对象,具体取决于缓冲区端口类型。
标量迭代器
·Iterator begin:双向标量迭代器,用于返回指向容器第一个样本的迭代器。
·Iterator cbegin:指向第一个const内容的双向标量迭代器。它不能用于修改它所指向的内容。
·Iterator begin_circular:与迭代器开始相同,但用于循环缓冲区端口。
·Iterator cbegin_circular:与迭代器开始_循环相同,但指向const内容。
·Iterator begin_random_circular:与开始_循环迭代器相同,并且可以用于访问相对于它们所指向的样本的任意偏移位置处的样本。
·Iterator cbegin_random_circular:与开始_random_circular迭代器相同,但不能用于修改它指向的内容。
向量迭代器
· Iterator begin_vector:双向向量迭代器,用于返回指向容器的第一个向量样本的迭代器。
·Iterator cbegin_vector:指向const内容的双向向量迭代器。它不能用来修改它所指向的内容。
·Iterator begin_vector_circular:与迭代器开始_向量相同,但用于循环缓冲区端口。
·Iterator cbegin_vector_circular:与begin_vector_circular相同,但指向'const'内容。
·Iteratorbegin_vector_random_circular:与begin_vector_circular相同,并且可以用于访问相对于它们所指向的样本的任意偏移位置处的样本。任意偏移以配置的向量大小为单位。
·Iterator cbegin_vector_random_circular:与begin_vector_random_circular相同,但不能用于修改它指向的内容。
Examples begin Iterator示例
begin_vector Iterator示例
cbegin Iterator示例
注意:cbegin迭代器是只读迭代器。如果pOut迭代器被声明为ccbegin迭代器,AI引擎编译器将出错。
cbegin_vector Iterator示例
begin_random_circular Iterator示例
begin_vector_random_circular Iterator示例
·循环缓冲区端口必须使用循环迭代器。线性缓冲区端口可以使用线性迭代器或循环迭代器。
·使用向量迭代器访问每次迭代的VECTOR_SIZE样本。其中,对于数据类型为cint16(32位)的该特定示例,VECTOR_SIZE为4(128位)、8(256位)、16(512位)和32(1024位)。
·当迭代器需要在任一方向上一次移动不止一步时,使用随机迭代器。
读和写数据
有几种方法可以阅读数据和将数据写入一维缓冲区端口。
·使用原始指针。请注意,此机制不能用于循环缓冲区端口。
·使用标量迭代器。
·使用向量迭代器。
文章来源:威视锐科技