ARM NEON 编程简单入门1
来源:互联网 发布:酷乐视q6装软件 编辑:程序博客网 时间:2024/06/10 09:29
原文: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 process for (; 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 process for (; 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 & vecB fill_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。
- 此处仅作演示。
阅读全文
0 0
- ARM NEON 编程简单入门1
- ARM NEON 编程简单入门1
- ARM NEON编程
- ARM NEON 编程系列8——ARM NEON 优化
- ARM NEON 编程系列1——导论
- ARM NEON 编程系列5——neon编程参考手册
- ARM-NEON
- ARM NEON 编程系列3——使用ARM NEON Intrinsics加速Video Codec
- ARM NEON 编程系列6——ARM Neon 指令 解释
- ARM NEON的中文优化实例(简单例子)
- ARM NEON 编程系列2——基本指令集
- (NEON实例一)ARM处理器NEON编程及优化技巧——数据加载和存储
- (NEON实例一)ARM处理器NEON编程及优化技巧——数据加载和存储
- ARM NEON 编程系列4——如何将neon用来优化我们的程序
- ARM NEON 编程系列7——NEON gcc编译器intrinsics函数对应的汇编指令
- NEON 编程
- ARM NEON 编程系列9——ARM C语言编程优化策略(神文)
- ARM NEON test 函数
- OC runtime 机制消除UIButton重复点击问题
- Referer详解
- 荆棘之路【3】角色差异
- Intellij idea 免费破解
- 定时任务的分布调度
- ARM NEON 编程简单入门1
- 【Algorithm】Keyboards
- leetcode 695. Max Area of Island(未解决)
- ajax的执行流程
- Redis 集群安装详细步骤
- spring-shiro实现角色(roles)自定义Filter----配置多个角色的或关系
- LeetCode 64
- char 判断字符是否为大小写
- HTTPOXY漏洞说明