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

本文主要介绍如何在一个常规的Android手机上调试OpenMP程序,包括Android NDK的环境配置和使用JNI编写一个OpenMP程序运行在Android手机中。
🎬个人简介:一个全栈工程师的升级之路!

📋个人专栏:高性能(HPC)开发基础教程

🎀CSDN主页 发狂的小花

🌄人生秘诀:学习的本质就是极致重复!

目录

一、前言

[1 Android NDK](#1 Android NDK)

[2 Android NDK 环境配置](#2 Android NDK 环境配置)

[2.1 Android NDK下载](#2.1 Android NDK下载)

[2.2 Android NDK 环境变量配置](#2.2 Android NDK 环境变量配置)

二、项目实战

[1 使用JNI配置C/C++项目编写OpenMP程序](#1 使用JNI配置C/C++项目编写OpenMP程序)

[2 OpenMP 环境引入](#2 OpenMP 环境引入)

[3 项目执行](#3 项目执行)

[4 运行结果](#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中

cpp 复制代码
export NDK=/home/hubery/Downloads/android-ndk-r21e-linux-x86_64/android-ndk-r21e

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

cpp 复制代码
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

cpp 复制代码
#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

cpp 复制代码
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

cpp 复制代码
APP_ABI := arm64-v8a 
APP_STL := c++_static   # for using STL
APP_PLATFORM := android-29

clean.sh

python 复制代码
rm -rf libs/ obj/ output/

openmpDemo.sh

cpp 复制代码
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

cpp 复制代码
export LD_LIBRARY_PATH=/data/local/tmp
./data/local/tmp/openmpDemo

2 OpenMP 环境引入

Android.mk中引入分为两步:

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

(2)链接库和编译选项

cpp 复制代码
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的使用。如下指令编译运行程序:

cpp 复制代码
source ~/.bashrc

sh openmpDemo.sh

4 运行结果

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

🌈我的分享也就到此结束啦🌈

如果我的分享也能对你有帮助,那就太好了!

若有不足,还请大家多多指正,我们一起学习交流!

📢未来的富豪们:点赞👍→收藏⭐→关注🔍,如果能评论下就太惊喜了!

感谢大家的观看和支持!最后,☺祝愿大家每天有钱赚!!!

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

相关推荐
Mr Lee_25 分钟前
android 配置鼠标右键快捷对apk进行反编译
android
顾北川_野1 小时前
Android CALL关于电话音频和紧急电话设置和获取
android·音视频
&岁月不待人&1 小时前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
羊小猪~~1 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
脉牛杂德2 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz2 小时前
STL--哈希
c++·算法·哈希算法
CSUC2 小时前
【C++】父类参数有默认值时子类构造函数列表中可以省略该参数
c++
Vanranrr2 小时前
C++ QT
java·c++·qt
鸿儒5173 小时前
C++ lambda 匿名函数
开发语言·c++
Winston Wood3 小时前
Android Parcelable和Serializable的区别与联系
android·序列化