美文网首页程序员
安卓系统应用程序纯命令行编译环境_第三个C程序neonTest.

安卓系统应用程序纯命令行编译环境_第三个C程序neonTest.

作者: 客昂康 | 来源:发表于2019-03-12 16:14 被阅读0次

    项目中的安卓APP不仅需要C语言来提高速度,还需要NEON指令进一步提高RemoteFX的解码速度,本笔记记录了安卓系统下C程序如何使用NEON指令。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <arm_neon.h>
    
    //neon指令运算
    void simd(unsigned short *output, unsigned short *input, int num){
        while(num >= 8){
            vst1q_u16(output, vshrq_n_u16(vmulq_n_u16(vshrq_n_u16(vmulq_n_u16(vld1q_u16(input), 17), 1), 19), 1));
            output += 8;
            input += 8;
            num -= 8;
        }
        
        while(num > 0){
            *output = ((((*input * 17) >> 1) * 19) >> 1);
            output += 1;
            input += 1;
            num -= 1;
        }
    }
    
    //非neon指令运算
    void sisd(unsigned short *output, unsigned short *input, int num){
        while(num > 0){
            *output = ((((*input * 17) >> 1) * 19) >> 1);
            output += 1;
            input += 1;
            num -= 1;
        }
    }
    
    void init(unsigned short *data){
        unsigned short i, j;
        for(i=0; i<100; i++){
            for(j=0; j<30; j++){
                *data = i+j;
                data += 1;
            }
        }
    }
    
    void dump(unsigned short *data){
        unsigned short i, j;
        for(i=0; i<100; i++){
            for(j=0; j<30; j++){
                printf("%5d", *data);
                data += 1;
            }
            putchar('\n');
        }
    }
    
    int main(int argc, char* argv[]){
        if(argc < 3) return 0;
        unsigned short buffer1[3000];
        unsigned short buffer2[3000];
        init(buffer1);
        if(strcmp(argv[1], "simd") == 0){
            int n = atoi(argv[2]);
            while(n-- > 0) simd(buffer2, buffer1, 3000);
        }
        else if(strcmp(argv[1], "sisd") == 0){
            int n = atoi(argv[2]);
            while(n-- > 0) sisd(buffer2, buffer1, 3000);
        }
        if(argc >= 4){
            dump(buffer1);
            putchar('\n');
            dump(buffer2);
        }
        return 0;
    }
    

    这个neon测试程序,根据第一个参数选择是用NEON指令还是非NEON指令来对3000个数做简单的乘法运算和移位运算,并根据第二个参数来决定这样的运算做多少遍。使用time命令来执行这个测试程序,根据运行时间粗略比较NEON指令的效率。

    • 新建Makefile文件,内容如下:
    ARG1=-ID:\Android\ndk64\sysroot\usr\include -ID:\Android\ndk64\sysroot\usr\include\arm-linux-androideabi -Wall -Wno-attributes
    ARG2=--sysroot=D:\Android\ndk64\platforms\android-19\arch-arm -Wall
    
    neonTest.out : neonTest.o
        arm-linux-androideabi-gcc.exe -o neonTest.out neonTest.o $(ARG2)
    
    neonTest.o : neonTest.c
        arm-linux-androideabi-gcc.exe -c -o neonTest.o neonTest.c $(ARG1)
    
    cls:
        del neonTest.o
        del neonTest.out
    
    • 打开批处理命令行,敲make命令编译:
      关于批处理命令行环境变量的配置方法,见《安卓系统应用程序纯命令行编译环境_第一个C程序hello.c》这篇笔记。

      编译失败。根据提示信息,需要让编译器启用NEON,见上图红框。
    • 编辑Makefile,添加编译选项-mfloat-abi=softfp -mfpu=neon并保存,再次敲make命令:

    • 编译成功,生成了可执行文件neonTest.out

    • 将可执行文件拷贝到开发板上运行试试:


      从运行结果可以看出,对3000个数做10万遍运算,采用NEON指令大约用时3.38秒,采用非NEON指令大约用时5.36秒。

    相关文章

      网友评论

        本文标题:安卓系统应用程序纯命令行编译环境_第三个C程序neonTest.

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