美文网首页
浅析GPUImage的设计思想

浅析GPUImage的设计思想

作者: 码农苍耳 | 来源:发表于2017-12-07 22:58 被阅读212次

    在移动端图片处理时,往往因为大量的计算导致需要较长的时间,为了充分利用设备的潜能,所以产生了利用GPU来处理计算的方案。其中最有名的开源方案就是GPUImage

    结构

    GPUImage的设计思路参考了流式的结构,所有东西都被概括为input或者output,其中最重要的filter则既是input也是output。这样设计统一了整个流程,但让整个结构变的更加死板和复杂。大概的流程如下:

    Image >> Input >> Filter_1 >> Filter_2 >> Filter_x >> Output
    

    当存在多个Filter的时候,整个结构上就会变的比较难以理解,所以个人认为,需要分开的结构还是分开比较好:

    Image >>   Dispatch   >> Output
                /   \
               /     \
        Filter_1 ... Filter_x
    

    性能优化

    GPUImage自身在设计的时候就考虑到了优化,所以有些时候你可能会感觉某些结构上有些奇怪。

    比如GPU内存申请基本上是在输入端就创建好了,在Filter中是不会新申请内存的,都是重用了开始就申请好的内存,除非改变了画布大小。

    Filter最好进行重用,因为OpenGL es首先需要利用CPU将GLSL编译为GPU可执行的代码,最好的情况是能够重用这部分已经编译完成的代码。

    当我们利用GPUImage来处理图片时,一般不会有什么性能问题,但是如果我们利用他来处理视频时,就需要考虑到极限下的性能问题。我们来模拟下多个Filter情况下的GPU处理1帧的情景:

    Image >> Input >> Filter_1 >> Filter_x >> Output
                       /    \
            Prepare(CPU) >> Process(GPU)
    

    可以看到每个Filter之间是同步执行的,所以无法很好的利用CPU多线程的能力。理想状况下应该是这样:

    Image >> Input >> Filter_1     ...  Filter_x
                         |                  |
                    Prepare(CPU)    >>  Prepare(CPU)
                         |                  |
                    Progress(GPU)   >>  Processor(GPU)  >>  Output
    

    这样就可以将串行执行改为CPU和GPU并发执行,不过GPUImage目前无法改造为这样的结构。

    OpenGL es

    目前iOS平台支持的GPU平台编码主要有2种方式,一种是OpenGL es,另一种就是Metal。按照官方说法,Metal的性能会比OpenGL更好,好像是因为在编译期就进行了一次初期编码,将代码转化为一种类似于bitcode一样的中间码。

    OpenGL的基本流程如下:

    CPU: 创建FrameBuffer + GLSL
                    | draw
    GPU:         main()
                    | readPixel
    CPU        read to RAM
    

    GLSL

    想要了解GPUImage就必须先学会使用OpenGL,那么就离不开学习GLSL,如果你使用CIImage,你也可能会需要KISL,是GLSL的一种子集。

    GLSL并不复杂,是一种非常类似于C语言的DSL,但是要与程序进行交互则会变得麻烦。

    总结

    要实现自己的Filter,则首先需要学习OpenGL以及GLSL,这是一个比较大的障碍点。

    如果仅仅是为了图片处理,那么GPUImage已经足够了。如果你需要高分辨率高帧率的视频渲染,GPUImage可能就满足不了你,优化思路是并发和利用空间去换取时间。

    相关文章

      网友评论

          本文标题:浅析GPUImage的设计思想

          本文链接:https://www.haomeiwen.com/subject/pfksixtx.html