YOLO:OpenCL评估 - zhonglong/TPV GitHub Wiki
Android Studio NDK编程指南 Android Studio 2.2起,默认采用CMake工具链,而非ndk-build,编译方式上有所差别,详见:
向您的项目添加 C 和 C++ 代码 https://developer.android.google.cn/studio/projects/add-native-code CMake https://developer.android.google.cn/ndk/guides/cmake
或从公共书架上浏览书籍:
Android C++高级编程——使用NDK 清华大学出版社,Onur Cinar著,于红 佘建伟 冯艳红译
从GitHub上找到一个Demo,
csarron/OpenCLDemo https://github.com/csarron/OpenCLDemo
导入Android Studio编译,尝试在X588手机上运行失败,经分析与libOpenCL.so有关。因为Android并未对OpenCL提供操作系统层面的支持,而是各芯片厂商自己实现,Demo中是高通的方案,需要先替换成MTK的实现方式。
先从X588源代码中编译出libOpenCL.so,替换Demo中的同名文件。
A common wrapper of OpenCL API for GPU drivers implementation. http://172.16.58.59:8080/source/xref/x588_o/alps/vendor/mediatek/proprietary/external/opencl_icd_loader/icd_loader/
替换libOpenCL.so后,在X588手机上还是运行失败,网上查找资料后推测X588手机(MT6750芯片)不支持libOpenCL.so。
判断一款芯片是否支持OpenCL,有两种方式,
- 使用OpenCL-Z软件检查,从豌豆荚官网安装OpenCL-Z软件,
OpenCL-Z http://www.wandoujia.com/com.robertwgh.opencl_z_android
- 访问Khronos Group官网查询
OpenCL https://www.khronos.org/conformance/adopters/conformant-products/opencl
针对X588手机(MT6750芯片),OpenCL-Z提示不支持OpenCL,
Possible reasons 1. The device may not support OpenCL 2. The OpenCL driver library was not found on the device
而在Khronos Group官网列表中也找不到MT6750芯片,对应GPU是Mali-T860。
X588(Mali-T860)
从Khronos Group官网也可以看出来,MTK只有早期少数几款芯片支持OpenCL(Android M及之前的版本),反而是高通芯片支持力度较好。于是拿X596手机(Adreno 505)做实验,果然可以运行OpenCLDemo,而且采用OpenCL相比纯C语言,性能有数百倍的提升,当然高通芯片的GPU本来就是业内领先的。
X596(Adreno 505)
由于Android并未对OpenCL提供操作系统层面的支持,而各家芯片厂商实现方式又不一致,导致OpenCL兼容性非常差。 从网上对OpenCL技术的一些讨论:
Why did Google choose RenderScript instead of OpenCL https://stackoverflow.com/questions/14385843/why-did-google-choose-renderscript-instead-of-opencl opencl的前景如何? https://www.zhihu.com/question/24890371
因为OpenCL是Apple公司提出的,市场竞争的关系Google并不采纳,而是推出RenderScript这个替代方案。
采用OpenCL编程面临的另一个问题是Android N起对非公开NDK库的限制,
NDK 应用链接至平台库 https://developer.android.google.cn/about/versions/nougat/android-7.0-changes#ndk
OpenCL编程需要编写额外的 cl 源码实现异构计算,cl源码采用C语言规范。
OpenCL异构并行计算:原理、机制与优化实践 机械工业出版社,刘文志 陈轶 吴长江著 https://yuedu.baidu.com/ebook/f188c8cddd36a32d72758126
网上也可以找到一些例子,如常见的矩阵乘法:
OpenCL之矩阵乘法实现 https://blog.csdn.net/c602273091/article/details/45418129
GitHub有个YOLO的例子(DeepSense)支持OpenCL,与纯C语言的DarknetDemoInAndroid来比较OpenCL可带来的性能提升。
DeepSense https://github.com/JC1DA/DeepSense DarknetDemoInAndroid https://github.com/chentyjpm/DarknetDemoInAndroid
由于目前只有高通的CPU能完美运行OpenCL,拿X596(Adreno 505)和锤子M1L(Adreno 530)两把手机做对比。
# | DeepSense | DarknetDemoInAndroid |
---|---|---|
X596 | 1.2秒多 | 3.6秒多 |
锤子M1L | 11秒多 | 1.1秒多 |
从结果来看,OpenCL并无明显优势,可能与代码自身优化有关。 而且,硬件对OpenCL的影响要大得多。高端和低端芯片,带OpenCL的例子性能可以相差9倍,不带OpenCL的例子性能只差3倍多。毕竟高端与低端芯片,GPU性能(单位时间浮点运算次数GFLOPS)差距有十几倍,CPU(架构,核心数量,主频)差异不会有那么大。