原文:http://blog.csdn.net/silentob/article/details/72954618 

ARM NEON 编程简单入门1

NEON简介

NEON是适用于ARM Cortex-A系列处理器的一种128位SIMD(Single Instruction, Multiple Data,单指令、多数据)扩展结构。从智能手机和移动计算

设备到HDTV,它已被公认为是多媒体应用领域中最为优越的处理器之一。它采用专门设计,简化了软件在不同平台之间的移植,为类似DolbyMobile的

密集型多媒体应用提供了低能耗和灵活的加速功能。

ARM CPU最开始只有普通的寄存器,可以进行基本数据类型的基本运算。自ARMv5开始引入了VFP(Vector Floating Point)指令,该指令用于向量化加速浮点运算。自ARMv7开始正式引入NEON指令,NEON性能远超VFP,因此VFP指令被废弃。

NEON类似于Intel CPU下的MMX/SSE/AVX/FMA指令,ARM CPU的NEON指令同样是通过向量化计算来进行速度优化,通常应用于图像处理、音视频处理等等需要大量计算的场景。

简单实例

下面给一个最基本的例子来说明NEON的作用:

//填充随机数
static void fill_random_value(std::vector<float>& vec_data)
{std::uniform_real_distribution<float> distribution(std::numeric_limits<float>::min(),std::numeric_limits<float>::max());std::default_random_engine generator;std::generate(vec_data.begin(), vec_data.end(), [&]() { return distribution(generator); });
}
//判断两个vector是否相等
static bool is_equals_vector(const std::vector<float>& vec_a,const std::vector<float>& vec_b)
{if (vec_a.size() != vec_b.size()){return false;}for (size_t i = 0; i < vec_a.size(); i++){if (vec_a[i] != vec_b[i]){return false;}}return true;
}
//正常的vector相乘 (注意:需要关闭编译器的自动向量化优化)
static void normal_vector_mul(const std::vector<float>& vec_a,const std::vector<float>& vec_b,std::vector<float>& vec_result)
{assert(vec_a.size() == vec_b.size());assert(vec_a.size() == vec_result.size());//compiler may optimized auto tree vectorize (test this diabled -ftree-vectorize)for (size_t i = 0; i < vec_result.size();i++){vec_result[i] = vec_a[i] * vec_b[i];}
}
//NRON优化的vector相乘
static void neon_vector_mul(const std::vector<float>& vec_a,const std::vector<float>& vec_b,std::vector<float>& vec_result)
{assert(vec_a.size() == vec_b.size());assert(vec_a.size() == vec_result.size());int i = 0;//neon processfor (; i < (int)vec_result.size() - 3 ; i+=4){const auto data_a = vld1q_f32(&vec_a[i]);const auto data_b = vld1q_f32(&vec_b[i]);float* dst_ptr = &vec_result[i];const auto data_res = vmulq_f32(data_a, data_b);vst1q_f32(dst_ptr, data_res);}//normal processfor (; i < (int)vec_result.size(); i++){vec_result[i] = vec_a[i] * vec_b[i];}
}
//测试函数
//FuncCostTimeHelper是一个计算时间消耗的helper类
static int test_neon()
{const int test_round = 1000;const int data_len = 10000;std::vector<float> vec_a(data_len);std::vector<float> vec_b(data_len);std::vector<float> vec_result(data_len);std::vector<float> vec_result2(data_len);//fill random value in vecA & vecBfill_random_value(vec_a);fill_random_value(vec_b);//check the result is same{normal_vector_mul(vec_a, vec_b, vec_result);neon_vector_mul(vec_a, vec_b, vec_result2);if (!is_equals_vector(vec_result,vec_result2)){std::cerr << "result vector is not equals!" << std::endl;return -1;}}//test normal_vector_mul{FuncCostTimeHelper time_helper("normal_vector_mul");for (int i = 0; i < test_round;i++){normal_vector_mul(vec_a, vec_b, vec_result);}}//test neon_vector_mul{FuncCostTimeHelper time_helper("neon_vector_mul");for (int i = 0; i < test_round; i++){neon_vector_mul(vec_a, vec_b, vec_result2);}}return 0;
}int main(int, char*[])
{return test_neon();
}

说明:

  • 这段代码在关闭编译器的自动向量化优化之后,neon_vector_mul大约比normal_vector_mul速度快3倍左右。
  • 这段代码中使用了3条NEON指令:vld1q_f32,vmulq_f32,vst1q_f32。
  • 此处仅作演示。

ARM NEON 编程简单入门1相关推荐

  1. ARM NEON编程

    下午终于把串口的任务完成的差不多了,同时老板有给安排了一个新的任务:看一下ARM NEON,一脸懵逼,这是个什么玩意!!! 我原本想做CUDA下的GPU加速的,结果这给我弄了个ARM的,这可咋整,不管 ...

  2. ARM Neon 编程笔记一(ARM NEON Intrinsics, SIMD运算, 优化心得)

    1. ARM Neon Intrinsics 编程 1.入门:基本能上手写Intrinsics 1.1 Neon介绍.简明案例与编程惯例 1.2 如何检索Intrinsics 1.3 优化效果案例 1 ...

  3. 【博学谷学习记录】超强总结,用心分享 | 狂野大数据shell编程—简单入门

    目录 前言 一.shell简介 二.入门案例 1.编写shell脚本 2.shell的运行方式 3.shell的数据类型 4.shell的变量 5.shell的字符串 6.shell的运算符 7.sh ...

  4. 网络编程简单入门,基础知识需先掌握

    文章目录 网络编程入门 网络编程概述 网络编程三要素 ==IP地址== IP地址分类 通过控制台,获取IP的方法 InetAddress 三个常用方法 ==端口== 端口号 ==协议== UDP协议 ...

  5. 51单片机编程简单入门——点亮实验板上的LED灯

    1.使用uVision4创建项目 2.选择MCU的型号:Atmel->AT89C52 3.是否创建C51启动文件,选否.启动文件以前汇编常用,现在少用了. 4.新建文件,需指定命名为.c文件 5 ...

  6. CUDA 编程简单入门 Advance CUDA 编程基础 (C++ programming)

    Advance CUDA编程基础 (C++ programming) GPU 架构 CUDA 编程基础 基本代码框架 CUDA Execution Model Case Study : Vector ...

  7. ARM学习系列 ---- ARM NEON

    ARM学习系列 ---- ARM NEON 1 NEON概述 1.1 简介 NEON是指适用于Arm Cortex-A系列处理器的一种高级SIMD(单指令多数据)扩展指令集,可执行并行数据处理. 1. ...

  8. ARM NEON指令集优化理论与实践

    ARM NEON指令集优化理论与实践 一.简介 NEON就是一种基于SIMD思想的ARM技术,相比于ARMv6或之前的架构,NEON结合了64-bit和128-bit的SIMD指令集,提供128-bi ...

  9. 《Python编程从入门到实践》记录之第2章 变量和简单数据类型总结(思维导图)

    <Python编程从入门到实践>第2章变量和简单数据类型知识总结:

最新文章

  1. jstatd,VisualVM使用和报错解决:Could not create remote object--java.security.AccessControlException
  2. rm -fr后的恢复
  3. 用python实现结构体数组
  4. 本地kubectl客户端连接远程K8S集群
  5. 初始化稀疏矩阵 matlab,访问稀疏矩阵 - MATLAB Simulink - MathWorks 中国
  6. 物联网安全威胁及应对措施
  7. es6基础0x012:Map
  8. Atom编辑器有一个LF、CRLF的切换
  9. Java POI 读取Excel-从开始到实例
  10. unicode编码java_JAVA转化Unicode编码
  11. WIN10使用 NetSpeedMonitor
  12. mysql 触发器 实例
  13. 程序员到CTO的Java技术路线图
  14. 微电影宣传片制作步骤分享。
  15. matlab半小提琴图,不会编程,也可以画小提琴图啦!
  16. 为什么软件开发周期总是预估的2~3倍?
  17. 健身环1536级小结:相当适合码农的锻炼方式
  18. BurpSuite 基本使用之暴力破解
  19. TIM定时中断(定时器介绍)
  20. 微信小程序调试webview_微信小程序内嵌webview相关知识点整理

热门文章

  1. 计算机cmd shutdown,cmd里面shutdown命令的原因是什么?什么时候显示的?
  2. java日历表打印_Java打印日历表
  3. linux joe复制一行,Linux joe命令
  4. redis 生成dump.rdb文件
  5. java 数据结构实例_数据结构(Java)——栈的实例
  6. mvp的全称_现役最强外援,总决赛MVP,来到CBA之后赚了多少钱?
  7. python线性整数规划求解_实例详解:用Python解决整数规划问题!
  8. Spring Boot 2.5.0 重新设计的spring.sql.init 配置有啥用?
  9. Spring Cloud Stream消费失败后的处理策略(二):自定义错误处理逻辑
  10. 1024,千家公司程序员幸福指数大比拼!最“幸福”的程序员是你吗?