zoukankan      html  css  js  c++  java
  • NEON优化之《简介》

    NDK支持NEON环境配置:https://blog.csdn.net/app_12062011/article/details/50462351
    一个很典型的例子:http://hilbert-space.de/?p=22
    neon android ndk:https://github.com/Lakers2005

    一、入门 

    1. 并行操作模式的模式[Mapping,Reduce,Scatter,Stencil]

    2. NEON指令使用举例,NEON指令提供的核心能力有数据的装载、存储以及数据的处理。NEON指令都是以V字母开头。

    VADD.I16 q0, q1, q2

    其中,V表示NEON指令头,ADD为加法运算,I表示整形,I16表示16位整形,q0,q1,q2都是128位寄存器。指令的意思是让q1,q2装载8个16位数据,然后执行加法操作,最后放倒q0寄存器中,一次指令完成了8此加法运算,也就性能提升了8倍。

    如果把RGB三个元素分别放到3个不同的寄存器中,每个寄存器的元素分别都是R、G、B,这样就可以进行并行晕算了。

     二、NDK中如何使用NEON

    1. 确认处理器是否支持NEON 

    cat /proc/cpuinfo | grep neon 

    2. 引入头文件arm_neon.h

    #include <arm_neon.h> 

    3. 修改CMakeList.txt

    # make a list of neon files and add neon compiling flags to them
    set(neon_SRCS helloneon-intrinsics.c)
    set_property(SOURCE ${neon_SRCS}  APPEND_STRING PROPERTY COMPILE_FLAGS " -mfpu=neon")
    add_library(hello-neon SHARED helloneon.c ${neon_SRCS})

    4. c代码

    void reference_convert(uint8_t *__restrict dest, uint8_t *__restrict src, int n) {
        int i;
        for (i = 0; i < n; i++) {
            int r = *src++; // load red
            int g = *src++; // load green
            int b = *src++; // load blue
    
            // build weighted average:
            int y = (r * 77) + (g * 151) + (b * 28);
    
            // undo the scale by 256 and write to memory:
            *dest++ = (y >> 8);
        }
    }
    
    //使用NEON Intrinsics优化
    void neon_convert(uint8_t *__restrict dest, uint8_t *__restrict src, int n) {
        int i;
        //读取8字节的预设值到64位寄存器
        uint8x8_t rfac = vdup_n_u8(77);// 转换权值 R
        uint8x8_t gfac = vdup_n_u8(151);// 转换权值 G
        uint8x8_t bfac = vdup_n_u8(28);// 转换权值 B
        n /= 8;
    
        for (i = 0; i < n; i++) {
            uint16x8_t temp;
            uint8x8x3_t rgb = vld3_u8 (src);//一次读取3个unit8x8到3个64位寄存器
            uint8x8_t result;
    
            temp = vmull_u8(rgb.val[0], rfac); // temp=rgb.val[0]*rfac
            temp = vmlal_u8(temp, rgb.val[1], gfac);// temp=temp+rgb.val[1]*gfac
            temp = vmlal_u8(temp, rgb.val[2], bfac);//temp=temp+rgb.val[2]*bfac
    
            result = vshrn_n_u16 (temp, 8); // 128位寄存器每16位右移第二个参数位
            vst1_u8 (dest, result); // 转存运算结果到dest
            src += 8 * 3;
            dest += 8;
        }
    }
  • 相关阅读:
    jenkins, docker-composer
    php pass-by-reference deprecated &$-->$
    showslow / YSlow for PhantomJS/slimerjs(gecko)/phantomas
    FW qunit introduction
    FW: AMD, CMD, CommonJS和UMD
    nodejs unit test related----faker-cli, sinonjs, mock/stub
    cs api测试
    CloudStack 4.3功能前瞻
    devcloud
    DevCloud for CloudStack Development
  • 原文地址:https://www.cnblogs.com/alanfang/p/8921855.html
Copyright © 2011-2022 走看看