性能优化-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编程进行更深入的编程实战详解!

相关推荐
长亭外的少年21 分钟前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
Yang.991 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
熬夜学编程的小王1 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
zz40_1 小时前
C++自己写类 和 运算符重载函数
c++
六月的翅膀1 小时前
C++:实例访问静态成员函数和类访问静态成员函数有什么区别
开发语言·c++
liujjjiyun2 小时前
小R的随机播放顺序
数据结构·c++·算法
¥ 多多¥2 小时前
c++中mystring运算符重载
开发语言·c++·算法
建群新人小猿3 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
天若有情6733 小时前
c++框架设计展示---提高开发效率!
java·c++·算法