性能优化-OpenMP基础教程(三)-Android上运行OpenMP

news2024/11/26 16:26:29

本文主要介绍如何在一个常规的Android手机上调试OpenMP程序,包括Android NDK的环境配置和使用JNI编写一个OpenMP程序运行在Android手机中。

🎬个人简介:一个全栈工程师的升级之路!
📋个人专栏:高性能(HPC)开发基础教程
🎀CSDN主页 发狂的小花
🌄人生秘诀:学习的本质就是极致重复!

目录

一、前言

1 Android NDK

2 Android NDK 环境配置

2.1 Android NDK下载

2.2 Android NDK 环境变量配置

二、项目实战

1 使用JNI配置C/C++项目编写OpenMP程序

2 OpenMP 环境引入

3 项目执行

4 运行结果


一、前言

        OpenMP是一个支持多平台的共享内存的并行编程接口,现在绝大多数的Android都支持OpenMP并行编程。基于移动边缘计算设备的并行计算有着重要的意义,受限于体积、功耗、算力,在移动设备上进行并行编程有很大的商业价值。

1 Android NDK

        Android NDK,全称Native Development Kit,是一套专为Android平台设计的工具开发包。它主要用于帮助开发者使用C、C++等语言编写本地代码,实现部分应用的功能,同时也支持代码库的复用。例如,一些性能要求较高的功能,如图形处理、音频处理和视频处理等,就可以通过NDK来实现,以提高运行效率。

除此之外,NDK还具备将动态链接库(so)和应用一起打包成APK的功能,从而使得应用程序更加紧凑,减少对设备存储空间的占用。

        NDK提供了众多平台库,开发者可以使用这些库来管理原生Activity和访问实体设备组件,例如传感器和触控输入。这对于在特定情况下提高性能,特别是像游戏这种计算密集型应用的情况特别有用。

`        Android NDK 官网 Android NDK 官网 。

2 Android NDK 环境配置

2.1 Android NDK下载

        本文仅仅介绍在Ubuntu18 上进行OpenMP包含Android NDK的安装编程,Ubuntu18以上应该都支持。笔者使用NDK21进行编译,下载地址为NDK21 ,下载后解压。

2.2 Android NDK 环境变量配置

        找到ndk-build 路径将其添加到bashrc中

export NDK=/home/hubery/Downloads/android-ndk-r21e-linux-x86_64/android-ndk-r21e

        这样NDK环境就配置好了,使用时仅仅需要使用如下代码将NDK添加到环境变量中

source ~/.bashrc

二、项目实战

1 使用JNI配置C/C++项目编写OpenMP程序

        (1)项目结构

                

                项目名称:openmp_hu

                demo文件夹:存放OpenMP程序文件,支持C语言和C++

                jni文件夹:Android JNI项目文件夹,内部含有Android.mk和Application.mk 用来构建整个适配JNI的项目。

                thirdParty文件夹:第三方库,适配Android 的OpenMP库,我这里手机是64位的ARM,直接去下载解压后的Android NDK文件夹寻找,使用64位的aarch64架构,将其复制到thirdParty文件夹下,如下:

                其他文件是将编译生成的可执行文件和库push到Android系统中和运行可执行程序、清理生成的过程文件的。

         (2)文件介绍

                openmpDemo.c

#include <stdio.h>
#include <omp.h>


int main()
{


    #pragma omp parallel for
    for (int i = 0;i < 8;i++)
    {
        printf("ThreadID: %d i: % d \n",omp_get_thread_num(),i);
    }

    return 0;

}

          Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 第三方库的引用
LOCAL_MODULE := omp
LOCAL_SRC_FILES := ../thirdParty/libomp.so
include $(PREBUILT_SHARED_LIBRARY)


include $(CLEAR_VARS)
# ARM 平台
LOCAL_ARM_MODE := arm
# C++引入openmp
LOCAL_CXXFLAGS := -fopenmp
# C引入openmp
LOCAL_CFLAGS +=  -fopenmp
# 一些其他库
LOCAL_LDLIBS    := -llog -landroid
# 链接openmp
LOCAL_LDFLAGS += -fopenmp

LOCAL_MODULE := openmpDemo
LOCAL_SRC_FILES := ../demo/openmpDemo.c
LOCAL_MULTILIB := 64
include $(BUILD_EXECUTABLE)

        Application.mk

APP_ABI := arm64-v8a 
APP_STL := c++_static   # for using STL
APP_PLATFORM := android-29

        clean.sh


rm -rf libs/ obj/ output/

            openmpDemo.sh

LOCAL_ROOT_PATH=${PWD}
${NDK}/ndk-build clean
${NDK}/ndk-build

adb devices

adb shell rm -f /data/local/tmp/openmpDemo /data/local/tmp/libomp.so /data/local/tmp/runOpenMP.sh

adb push libs/arm64-v8a/libomp.so /data/local/tmp/
adb push libs/arm64-v8a/openmpDemo /data/local/tmp/
adb push ./runOpenMP.sh /data/local/tmp
adb shell chmod +x /data/local/tmp/openmpDemo
adb shell chmod +x /data/local/tmp/libomp.so
adb shell chmod +x /data/local/tmp/runOpenMP.sh
adb shell /data/local/tmp/runOpenMP.sh
sh ${LOCAL_ROOT_PATH}/clean.sh

        runOpenMP.sh

export LD_LIBRARY_PATH=/data/local/tmp
./data/local/tmp/openmpDemo

2 OpenMP 环境引入

        Android.mk中引入分为两步:

        (1)找到适配ARM64位架构的libomp.so ,引入编译成共享库

         (2)链接库和编译选项

include $(CLEAR_VARS)
LOCAL_MODULE := omp
LOCAL_SRC_FILES := ../thirdParty/libomp.so
include $(PREBUILT_SHARED_LIBRARY)


LOCAL_CXXFLAGS := -fopenmp
LOCAL_CFLAGS +=  -fopenmp
LOCAL_LDFLAGS += -fopenmp

3 项目执行

       执行前记得将Android手机设置为开发者模式,允许adb的使用。如下指令编译运行程序:

source ~/.bashrc

sh openmpDemo.sh

4 运行结果

        ​           

        分析运行结果,可以看出执行成功,有7个线程,但是笔者有是8核手机,很奇怪,不知道另一个核为什么一直用不上。

🌈我的分享也就到此结束啦🌈
如果我的分享也能对你有帮助,那就太好了!
若有不足,还请大家多多指正,我们一起学习交流!
📢未来的富豪们:点赞👍→收藏⭐→关注🔍,如果能评论下就太惊喜了!
感谢大家的观看和支持!最后,☺祝愿大家每天有钱赚!!!

下一节将对OpenMP编程进行更深入的编程实战详解!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1357491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js——json对象相互转化——js基础积累

js——json对象相互转化——js基础积累 需求场景解决步骤1&#xff1a;定义一个变量接收此字段&#xff0c;方便处理解决步骤2&#xff1a; { 外面的双引号要去掉解决步骤3&#xff1a;使用正则去除参数中的\\解决步骤4&#xff1a;如果此参数必须以{开头&#xff0c;以}结尾解…

Java学校教务管理系统源码带微信小程序

运行环境&#xff1a;jdk8mysql5.7IntelliJ IDEAmaven 技术&#xff1a;springbootmybatislayuishirojquery 教务管理系统是一个基于网络的在线管理平台, 帮助学校管理教务系统&#xff0c;用一个帐号解决学校教务教学管理&#xff0c; 灵活的定制符合学校自己实际情况的教务系…

Eclipse下安装GDB

主要参考资料&#xff1a; 链接: https://blog.csdn.net/u013609041/article/details/18967837 目录 简介Eclipse中安装和配置GDB错误 简介 Eclipse是一款开发软件。 GDB是一个调试软件&#xff0c;但是GDB通常是运行在linux下的&#xff0c;无法直接在windows下运行&#xff…

RabbitMQ安装与应用

文章目录 1. RabbitMQ1.1. 同步通讯与异步通讯1.2. 异步通讯的优缺点1.3. 几种MQ的对比1.4. docker安装运行RabbitMQ 流程1.5. RabbitMQ的几个概念1.6. 五种模型1.6.1. 基本消息队列 1.7. 基本使用1.7.1. 1建立连接时会出现以下界面![在这里插入图片描述](https://img-blog.csd…

Redis第四讲——Redis的数据库结构、删除策略及淘汰策略

一、redis中的数据库 redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中。db数组的每项都是一个redis.h/redisDb结构&#xff0c;而每个redisDb结构就代表一个数据库。在初始化服务器时&#xff0c;程序会根据服务器状态的dbnum属性来决定应该创建多…

python+selenium爬虫笔记

本文只是做例子&#xff0c;具体网站路径麻烦你们换下&#xff0c;还有xpath路径也换下 一、安装所需要的组件&#xff08;此处采用谷歌&#xff09; 1、安装驱动 查看你的浏览器版本&#xff0c;去安装对应的版本 下载驱动 下载驱动路径 之前版本的 输入这个路径下载下来解压…

CTF-PWN-栈溢出-高级ROP-【SROP】

文章目录 linux信息处理2017 360春秋杯 smallest检查源码思路第一次要执行ret时的栈执行write函数时修改rsp到泄露的栈地址上去 输入/bin/sh并sigreturn调用系统调用回忆exp注意一个离离原上谱的地方 参考链接 SROP(Sigreturn Oriented Programming) 于 2014 年被 Vrije Univer…

系列十、Spring Cloud Gateway

一、Spring Cloud Gateway 1.1、概述 Spring Cloud全家桶中有个很重要的组件就是网关&#xff0c;在1.x版本中采用的是Zuul网关&#xff0c;但是在2.x版本中&#xff0c;由于Zuul的升级一直跳票&#xff0c;Spring Cloud最后自己研发了一个网关替代Zuul&#xff0c;即&#xf…

优雅实现微信小程序动态tabBar,根据不同用户角色显示不同底部导航——更新版(支持自由组合总数超过5个tabBar菜单)

背景 在开发小程序过程中&#xff0c;有个需求是&#xff0c;小程序底部的tabBar需要根据不同用户角色显示不同底部导航。此时就需要用到自定义底部导航 custom-tab-bar。 上次发文是组合显示4个底部tabBar导航&#xff0c;很多小伙伴评论说组合超过5个怎么办。他们的需求总数…

Android中的Intent

一.显式Intent 显示Intent是明确目标Activity的类名 1. 通过Intent(Context packageContext, Class<?> cls)构造方法 2.通过Intent的setComponent()方法 3.通过Intent的setClass/setClassName方法 通过Intent(Context packageContext, Class<?> cls)构造方法 通…

JVM之对象创建

对象创建的流程 1.类加载检查 虚拟机遇到一条new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应的类加载过程。new指令对…

Callback Hook

一、Callback Hook 函数名&#xff1a;useCallback 用于得到一个固定引用值的函数&#xff0c;通常用它进行性能优化。 useCallback: 该函数只需要传入两个参数&#xff1a;一个回调函数和一个依赖数组即可。 1.函数&#xff0c;useCallback会固定该函数的引用&#xff0c;…

【Rust日报】Piccolo - 用纯Rust实现的无栈Lua虚拟机

Piccolo - 用纯Rust实现的无栈Lua虚拟机 Piccolo&#xff0c;原名luster&#xff0c;在经过数年的中断后&#xff0c;于2023年4月悄然恢复了开发。曾经开发过 rlua 的 kyren&#xff0c;在底层 gc-arena crate 取得突破后&#xff0c;回到了 piccolo 项目。这两个项目现在已经&…

Python:界面开发,wx入门篇

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/3Yb_YAKiMte_f5HanetXiA 本文大概 3617 个字&#xff0c;阅读需花 10 分钟 内容不多&#xff0c;但也花了一些精力 如要交流&#xff0c;欢迎评…

极速 JavaScript 打包器:esbuild

文章目录 引言什么是esbuild&#xff1f;esbuild的特点esbuild如何实现如此出色的性能&#xff1f;esbuild缺点基本配置入口文件输出文件模块格式targetplatformexternalbanner和footer 高级配置插件系统自定义插件压缩代码调试代码 结论&#x1f636; 写在结尾 引言 esbuild是…

leetcode:724. 寻找数组的中心下标

一、题目 二、函数原型 int pivotIndex(int* nums, int numsSize) 三、思路 首先要理解正确中心下标&#xff0c;中心下标左侧元素之和等于右侧元素之和&#xff0c;比较时是不包含中心下标所指元素的。 先将数组和求出来记为sum&#xff0c;再遍历数组&#xff0c;遍历到…

快速批量运行命令

Ansible 是 redhat 提供的自动化运维工具&#xff0c;它是 Python编写&#xff0c;可以通过 pip 安装。 pip install ansible 它通过任务(task)、角色(role)、剧本(playbook) 组织工作项目&#xff0c;适用于批量化系统配置、软件部署等需要复杂操作的工作。 但对于批量运行命…

pytorch集智-1安装与简单使用

1 安装 1.1 简介 pytorch可用gpu加速&#xff0c;也可以不加速。gpu加速是通过cuda来实现&#xff0c;cuda是nvidia推出的一款运算平台&#xff0c;它可以利用gpu提升运算性能。 所以如果要装带加速的pytorch&#xff0c;需要先装cuda&#xff0c;再装pytorch&#xff0c;如…

【重点】【BFS】542.01矩阵

题目 法1&#xff1a;经典BFS 下图中就展示了我们方法&#xff1a; class Solution {public int[][] updateMatrix(int[][] mat) {int m mat.length, n mat[0].length;int[][] dist new int[m][n];boolean[][] used new boolean[m][n];Queue<int[]> queue new Li…

excel中解决多行文本自动调整行高后打印预览还是显示不全情况

注意&#xff1a;此方法对于多行合并后单元格行高调整不适用&#xff0c;需要手动调整&#xff0c;如大家有简便方法&#xff0c;欢迎评论。 一、调整表格为自动调整行高 1&#xff09;点击此处全选表格 2&#xff09;在第一行序号单元格的下端&#xff0c;鼠标成黑十字时&am…