利用OpenCL对OpenCV并行化心得(3)

    上文提到由于ROI的问题,想在一个kernel中向量读写是有难度的,于是就用了很多mask操作,但是这些操作太复杂,不仅非常容易引入bug,而且带来了太多的额外操作,对于没有ROI的数据,那么多边界操作都是浪费的。

    在心得2中,简单的kernel只需要十几条汇编指令,而考虑到ROI的向量化需要几百条指令,多余的处理指令太多了,对于像add这样的简单函数,最终的处理效率也不是那么理想。这里可以有两种方法来处理,第一种是把有ROI和没有ROI的情况分开,有ROI用一个kernel,没有ROI用另外一个,在CPU端只是一个条件判断而已;第二种就是对数据进行截断,将非对齐的数据处理为对齐的,长度不是向量倍数的按向量倍数处理。

    对于第二种方法,举例来说,一个矩阵式100*100的,ROI设置在起点为(1,1),大小为80*80,也就是小一圈。这时可以先使用第一个kernel来处理中间的内容,起始(4,1),大小为80*76的区域,对这个区域由于已经对齐并且长度是4的倍数,不需要进行判断,可以直接使用向量化;处理完这个之后对左边和右边再用另外一个kernel处理,这个kernel可以不用考虑效率(因为边界数据量非常小),只用考虑简单。

    这样处理的好处就在于,如果数据没有ROI或者是对齐的,那么就只用一个kernel,不用有额外的判断,处理效率很高,如果有ROI,那么第一个效率很高(比处理那么多边界条件高),第二个由于数据量小,速度也会很快。

你可能感兴趣的:(利用OpenCL对OpenCV并行化心得(3))