编译器会把VIP7000的程序优化好后,放在DDR位置.
写GPU程序,只需要写一个线程,代码量很小.
GPU的运行,同一时间运行的是相同的代码.
编译器把优化好后的程序,放在DDR位置后,驱动会自动调度. 当前时间点,运行kernel这条代码,它就会把程序加载到cache里面,cache足够存放下. 由于只处理一个线程,代码不会太大,运行的时候,功能单元直接从cache里面取就好了.
多kernel的串联,执行图的概念。里面的数据传递,VIP7000直接访问,都在DDR.
openvx是以group为单位的.
假设一个线程处理x方向1个像素点,处理y方向1个人像素点. x方向4个线程,y方向1个线程为一个group. 假设读取每个像素点需要100条指令(100个周期). 每个group里的每条线程是串联的,但是可认为是并行的. 第一个group,四个线程同时读取每一块的load指令,这条指令需要耗费100个周期. 第一个周期过去了,group自动切换到第二个group, group之间的切换是0开销. 如果其中一个group里的数据得到,则切换到下一条指令. 按组切换.
workdim = 2; 维度
global work offset : 图像处理起始位置
global work scale: 每个线程处理多少个像素, 处理像素的偏移量(行>列, 防止访存并发, x*y*sizeof() = 128, 若是128的倍数效率会低)
local work size: 多少个线程绑定为一个group(根据core来定,VIP7000有2个core,8个线程,最好相互乘积是8或8的倍数,最好能被图像的高宽整除)
global work size: 线程划分为多少组(根据整个图像来划分)
比如:一幅宽1000高500的图像,如何读取数据最快呢?
workdim = 2;
global work offset = {0, 0 , 0}; //图像起始位置
global work scale = {16, 1, 0}; //单个线程一次处理多少个像素,每个寄存器最多允许128bit的数据,假设是uchar数据类型,所以128/8 = 16(行>列,防止内存并发, x*y*sizeof()=128)
//x方向16, y方向1, ,为何不是4,2原因是行优先,寄存器从cache里获取数据的是一行一行的获取.
local work size = {4, 2, 0}; //多少个线程绑定为一个group(调度方向),最好能被图像的高宽整除, 两者的乘积是8的倍数
//为什么是8的倍数,因为VIP7000有2个shader core, 每个shader core有4个线程并发,所以同一时
//刻有2个线程同时运行.(线程并发表示线程切换的非常快), 所以最好是8或8的倍数线程绑定为一个
//group. 一个group里一定是2个线程并行处理.
global work size ={}; //线程能划多少个组,这个需要跟图像的高宽结合,global work size 一定是local work size的整数倍
图像的宽1000 除 16 = 62.5 = 63, 但是63+多少可以被local work size 4整除, 故为64
图像的高500 除 1 = 500, 500可以被local work size 1整除,故为500
此时 global work size = {64,500,0}
1个线程------1个kernel.
1个线程占用多少个寄存器,看kernel里.
读数据,gpu加载128bit的数据,== gpu加载1个寄存器里面的数据.
1个线程1次执行1个人kernel, 如果1个线程占寄存器多,则另外的线程占寄存器也多, 则1个group所占寄存器多.
通过id处理哪个图像块.
线程调度,程序会自己做.
Openvx标准制定的目的,是为了实现跨平台加速处理.
基本的加速原理:其实图像处理就是对图片矩阵数组进行一系列操作,然后从结果中找到我们想要的信息. 每一次对图像的基本
操作都可以看成整个流程中的一个节点(node), 这个节点通过自己处理前和处理后的图像和其它节点相连,形
成一个网络,这里叫做graph. 硬件开发商需要做的之一,就是想办法针对自己的硬件实现node代码,使之符
合openvx的标准且能在自己的硬件上得到优化. 接下来,开发商只需要把这些node连成graph, 实现自己的功
能. 最后开发商再针对自己的硬件对graph进行优化加速.
这样一来,开发者的工作量就被大大消减了. 可以缩短开发周期,提高代码可移植性. 如果厂家实现的这些
node满足不了需要,这时openvx提供了一种自定义node的机制, 它使得用户可以根据自己的需要编写node,
并最终和graph相融合, 还能通过opencl和gpu进行加速. 但是不管怎样,都是放在openvx这个框架中的.
openvx和opencv并不冲突,它们可以互补. openvx在嵌入式和实时性系统中可以更好的发挥它的优势,在某
些场合配合opencv的强大功能可以实现更好的效果.