NEON 指令集并行技术优化彩色图像转灰度图【Android】

简介: NEON 指令集并行技术优化彩色图像转灰度图【Android】

参考原文:


android平台的neon优化策略


Neon Intrinsics各函数介绍



目前市面上主流的旗舰android手机搭载的Soc都是64位的CPU,常见的armv7指令集的公版架构如Cortex-A8,Cortex-A9,Cortex-A15,常见的armv8指令集的公版架构如Cortex-A53,Cortex-A57,Cortex-A72,Cortex-A73。arm架构的CPU从armv7a开始已经支持neon(可选项),从而实现并行计算功能。armv8a还具备32个128neon寄存器,并且支持双精度浮点数。


image.png

image.png

下面为我添加的代码注释 (第一篇参考文章中错把 Android 的位图 RGBA 格式当做 ARGB 进行处理了):

image.png

如图,很明显 alpha 通道是最后一个,但是值得注意的是,当使用 u16 时,数据格式为 (20541=0x503D)(65463=0xFFB7) 对应 rgba 中的 GR 和 AB

void method_rgba2gray_neon(AndroidBitmapInfo info, void *pixels) {
    // Gray = (R*38 + G*75 + B*15) >> 7
    TickMeter tm3;
    tm3.start();
    unsigned short *dst = (unsigned short *) pixels; // 注意是 unsigned short
    unsigned char *src = (unsigned char *) pixels;
    uint8x8_t r = vdup_n_u8(38); // 将一个标量扩展城向量 8 bit * 8
    uint8x8_t g = vdup_n_u8(75);
    uint8x8_t b = vdup_n_u8(15);
    uint16x8_t alp = vdupq_n_u16(255 << 8);
    uint16x8_t temp;
    uint8x8_t gray;
    uint8x8x4_t rgba;
    uint16x8_t high;
    uint16x8_t low;
    uint16x8x2_t res;
    int i, size = info.height * info.width / 8;
    // 暂不考虑不能被 8 整除的情况
    for (i = 0; i < size; ++i) {
        // 获取r、g、b值,计算灰度值
        rgba = vld4_u8(src);  // 从内存中加载数据(以 AOS 存储)到 4 个向量(8 bit * 8)中(SOA)
        temp = vmull_u8(rgba.val[0], r); // vmul 指令
        temp = vmlal_u8(temp, rgba.val[1], g); // vmla 指令
        temp = vmlal_u8(temp, rgba.val[2], b);
        gray = vshrn_n_u16(temp, 7); // vshrn_n_u16 会在做右移 7 位的同时将2字节无符号型转成1字节无符号型
        src += 8 * 4; // src 移到下个位置
        // 赋值 4 通道 rgba(将 gray 扩展成 rgba)
        // 先用 vmovl_u8 (长指令)符号扩展或零扩展双字向量中的每个元素到其原始长度的两倍
        // vqmovn_* 为窄指令
        high = vorrq_u16(alp, vmovl_u8(gray)); // 再用 vorrq_u16 按位或运算
        low = vorrq_u16(vshlq_n_u16(vmovl_u8(gray), 8), vmovl_u8(gray)); // 注意这里是左移
        res = vzipq_u16(low, high); // 两个向量的元素交错打包成一个新向量
        vst1q_u16(dst, res.val[0]); // 存储一个向量(res 的前半部分)到内存(16bit*8)
        dst += 8;
        vst1q_u16(dst, res.val[1]);
        dst += 8;
    }
    tm3.stop();
    LOGI("method_rgba2gray_neon   time: %lf", tm3.getTimeMilli());
    LOGI(" \n");
}

vmovl_u8,vshlq_n_u16 函数的执行结果分别如下:

image.png

其中结果 16进制表示的形式为

86:0x0056

22016:0x5600

vzipq_u16 函数执行(low:GR, high:AB的格式)的结果如下:

image.png

可以看出 res[0] 和 res[1] 两个向量分别由 low, high 两个向量一前一后交错打包而成。

其中,

22102:0x5656

65366:0xFF56

程序运行效果如下:

image.png

我在 debug/release 模式下分别进行了测试,发现作者原来的方法竟然还不如 c 原生实现的高效。。。一度怀疑我自己的手机是不是坏了(S8+),我自己实现的都有将近 30% 的性能提升。。。另外可以看出 OpenCV 的优化还是非常优秀的!

image.png

最后,可以将 Build Variants 设置为 release(默认为 debug)

image.png

目录
相关文章
|
15天前
|
安全 Android开发 iOS开发
安卓与iOS的较量:技术特性与用户体验的深度解析
在移动操作系统的战场上,安卓和iOS一直占据着主导地位。本文将深入探讨这两大平台的核心技术特性,以及它们如何影响用户的体验。我们将从系统架构、应用生态、安全性能和创新功能四个方面进行比较,帮助读者更好地理解这两个系统的异同。
45 3
|
5天前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
37 20
Android经典面试题之图片Bitmap怎么做优化
|
6天前
|
API Android开发 iOS开发
掌握安卓与iOS应用开发中的依赖注入技术
本文探讨了在安卓和iOS应用开发中,如何有效利用依赖注入技术来提升代码的模块化、可测试性和可维护性。通过对比分析两种平台下依赖注入的实现方式与工具,本文旨在为开发者提供一套清晰、实用的依赖管理策略,助力打造高质量软件产品。
|
8天前
|
Java Android开发 UED
安卓应用开发中的内存管理优化技巧
在安卓开发的广阔天地里,内存管理是一块让开发者既爱又恨的领域。它如同一位严苛的考官,时刻考验着开发者的智慧与耐心。然而,只要我们掌握了正确的优化技巧,就能够驯服这位考官,让我们的应用在性能和用户体验上更上一层楼。本文将带你走进内存管理的迷宫,用通俗易懂的语言解读那些看似复杂的优化策略,让你的开发之路更加顺畅。
16 2
|
9天前
|
Java Android开发 开发者
安卓应用开发中的线程管理优化技巧
【9月更文挑战第10天】在安卓开发的海洋里,线程管理犹如航行的风帆,掌握好它,能让应用乘风破浪,反之则可能遭遇性能的暗礁。本文将通过浅显易懂的语言和生动的比喻,带你探索如何优雅地处理安卓中的线程问题,从基础的线程创建到高级的线程池运用,让你的应用运行更加流畅。
|
14天前
|
安全 Android开发 iOS开发
安卓与iOS的较量:技术特性与用户体验的深度剖析
在移动操作系统的战场上,安卓和iOS一直是两个重量级选手。本文将深入探讨两者的技术架构、安全性、应用生态以及用户体验等方面的差异,并尝试从用户和开发者的角度出发,分析这两个系统的优势与不足。通过比较,我们不仅能更好地理解各自的特点,还能洞察未来移动技术的发展趋势。
|
2天前
|
Android开发 Swift iOS开发
掌握安卓与iOS应用开发:关键技术与市场趋势
本文深入探讨了安卓和iOS平台的应用开发,通过分析关键技术如Kotlin、Swift及Flutter,并结合当前市场趋势,为开发者提供全面的技术指南。同时,比较了两大平台的优劣势,帮助开发者做出更明智的决策。
|
6天前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
17 0
|
19天前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
80 0
|
20天前
|
iOS开发 Android开发 MacOS
从零到全能开发者:解锁Uno Platform,一键跨越多平台应用开发的神奇之旅,让你的代码飞遍Windows、iOS、Android、macOS及Web,技术小白也能秒变跨平台大神!
【8月更文挑战第31天】从零开始,踏上使用Uno Platform开发跨平台应用的旅程。只需编写一次代码,即可轻松部署到Windows、iOS、macOS、Android及Web(通过WASM)等多个平台。Uno Platform为.NET生态带来前所未有的灵活性和效率,简化跨平台开发。首先确保安装了Visual Studio或VS Code及.NET SDK,然后选择合适的项目模板创建新项目。项目结构类似传统.NET MAUI或WPF项目,包含核心NuGet包。通过简单的按钮示例,你可以快速上手并构建应用。Uno Platform让你的技术探索之旅充满无限可能。
23 0