- PVSM.RU - https://www.pvsm.ru -
Совсем недавно мы рассматривали написание многопоточных приложений для магазина Windows [1] с помощью Intel® Threading Building Blocks(Intel® TBB [2]). Там утверждается, что использование кроссплатформенной библиотеки TBB позволяет легко переносить вычислительную часть на другие платформы. Android как раз сгодится для хорошего примера одной из «других платформ», подробности под катом.
В недавно вышедшем релизе библиотеки Intel® TBB tbb41_20121112oss, который доступен для загрузки на нашем сайте threadingbuildingblocks.org [3], добавлена экспериментальная поддержка приложений для Android, т.е. построение нативных библиотек для использования Android приложениями через JNI интерфейс.
Для построения библиотеки будем использовать Android SDK Tools Rev.21 и Android NDK Rev 8C. Но тут необходимо оговориться, что, как оказалось при подготовке материала, сказалась экспериментальность и построение самих библиотек в этом релизе. «Из коробки» работает только под NDK на Linux. Мы поправим это в одном из следующих обновлений. Я подпилил немного makefile для Windows и построил библиотеку там, но для простоты будем подразумевать, что сама библиотека была построена на Linux, а всё остальное сделано на Windows. В общем, налицо еще одно преимущество кроссплатформенной библиотеки.
Итак, что же необходимо сделать, чтобы собрать простое приложение с использованием Intel TBB.
Для начала необходимо распаковать и откомпилировать библиотеку, поскольку этот релиз распространяется только в исходниках. Подразумевается, что есть gnu make, в командной строке с выставленным окружением для NDK выполняем команду
gmake tbb tbbmalloc target=android
Со стороны библиотеки всё, переходим в Eclipse. При помощи шаблонов создаем простое приложение и, для простоты, как в предыдущем случае назовём его app1:
Activity выберем FullscreenActivity. На этом работа шаблона завершится. Обратите внимание, что com.example* приложения не приветствуются магазином гугл. Но для примера вполне сойдет.
Затем добавим пару кнопок на основной фрейм. После этого XML файл основного фрейма (app1/res/layout/activity_fullscreen.xml) будет выглядеть примерно так
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".FullscreenActivity" >
<TextView
android:id="@+id/fullscreen_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:keepScreenOn="true"
android:text="@string/dummy_content"
android:textColor="#33b5e5"
android:textSize="50sp"
android:textStyle="bold" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" >
<LinearLayout
android:id="@+id/fullscreen_content_controls"
style="?buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="74dp"
android:layout_gravity="bottom|center_horizontal"
android:background="@color/black_overlay"
android:orientation="horizontal"
tools:ignore="UselessParent" >
<Button
android:id="@+id/dummy_button1"
style="?buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/dummy_button1"
android:onClick="onClickSR" />
<Button
android:id="@+id/dummy_button2"
style="?buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/dummy_button2"
android:onClick="onClickDR" />
</LinearLayout>
</FrameLayout>
</FrameLayout>
А файл со строками (app1/res/values/strings.xml) будет выглядеть так:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Sample</string>
<string name="dummy_content">Reduce sample</string>
<string name="dummy_button1">Simple Reduce</string>
<string name="dummy_button2">Deterministic Reduce</string>
</resources>
Так же добавим обработчики кнопок
// JNI functions
private native float onClickDRCall();
private native float onClickSRCall();
public void onClickDR(View myView) {
TextView tv=(TextView)(this.findViewById(R.id.fullscreen_content));
float res=onClickDRCall();
tv.setText("Result DR is n" + res);
}
public void onClickSR(View myView) {
TextView tv=(TextView)(this.findViewById(R.id.fullscreen_content));
float res=onClickSRCall();
tv.setText("Result SR is n" + res);
}
И загрузку библиотек в FullscreenActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
…
System.loadLibrary("tbb");
System.loadLibrary("jni-engine");
}
Если с библиотекой «tbb» должно быть всё понятно, то на «jni-engine» нужно остановиться подробнее.
«jni-engine» — это С++ библиотека, которая реализует вычислительную часть и выставляет С-интерфейсы для JNI вызовов onClickSRCall() и onClickSRCall().
Согласно правилам разработки внутри проекта создаем каталог ‘jni’ и создаем там 3 файла, специфичные для нашей библиотеки «jni-engine». Это:
Android.mk (в <> скобках данные, в которые необходимо подставить актуальные значения)
LOCAL_PATH := $(call my-dir)
TBB_PATH := <path_to_the_package>
include $(CLEAR_VARS)
LOCAL_MODULE := jni-engine
LOCAL_SRC_FILES := jni-engine.cpp
LOCAL_CFLAGS += -DTBB_USE_GCC_BUILTINS -std=c++11 -I$(TBB_PATH)/include
LOCAL_LDLIBS := -ltbb -L./ -L$(TBB_PATH)/<path_to_libtbb_so>
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libtbb
LOCAL_SRC_FILES := libtbb.so
include $(PREBUILT_SHARED_LIBRARY)
Application.mk
APP_ABI := x86
APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti
APP_STL := system
jni-engine.cpp:
#include <jni.h>
#include "tbb/parallel_reduce.h"
#include "tbb/blocked_range.h"
float SR_Click()
{
int N=10000000;
float fr = 1.0f/(float)N;
float sum = tbb::parallel_reduce(
tbb::blocked_range<int>(0,N), 0.0f,
[=](const tbb::blocked_range<int>& r, float sum)->float {
for( int i=r.begin(); i!=r.end(); ++i )
sum += fr;
return sum;
},
[]( float x, float y )->float {
return x+y;
}
);
return sum;
}
float DR_Click()
{
int N=10000000;
float fr = 1.0f/(float)N;
float sum = tbb::parallel_deterministic_reduce(
tbb::blocked_range<int>(0,N), 0.0f,
[=](const tbb::blocked_range<int>& r, float sum)->float {
for( int i=r.begin(); i!=r.end(); ++i )
sum += fr;
return sum;
},
[]( float x, float y )->float {
return x+y;
}
);
return sum;
}
extern "C" JNIEXPORT jfloat JNICALL Java_com_example_app1_FullscreenActivity_onClickDRCall(JNIEnv *env, jobject obj)
{
return DR_Click();
}
extern "C" JNIEXPORT jfloat JNICALL Java_com_example_app1_FullscreenActivity_onClickSRCall(JNIEnv *env, jobject obj)
{
return SR_Click();
}
Как видно, используем те же алгоритмы, что и в предыдущем блоге.
При построении с помощью NDK он сам раскладывает библиотеки в нужные каталоги, в том числе libjni-engine.so и libtbb.so.
Теперь переходим обратно в eclipse и строим .apk файл. Приложение готово для установки на AVD или на устройство. Вот так это выглядит на AVD:
Вот и всё! Наше простое приложение написано! А для тех, кто использовал код предыдущего блога, приложение успешно перенесено на Android.
Для тех, кто заинтересовался, пробуйте:
Скачать библиотеку Intel® Threading Building Blocks (Версия с открытым исходным кодом):
threadingbuildingblocks.org [3]
Коммерческая версия Intel® TBB (функционально не отличается):
software.intel.com/en-us/intel-tbb [4]
Англоязычные и русскоязычные блоги об Intel® TBB
software.intel.com/en-us/tags/17207 [5]
software.intel.com/en-us/tags/17220 [6]
Ну и, конечно, наш форум,
software.intel.com/en-us/forums/intel-threading-building-blocks [7]
Автор: vpolin
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android-development/23229
Ссылки в тексте:
[1] написание многопоточных приложений для магазина Windows: http://habrahabr.ru/company/intel/blog/158263/
[2] Intel® TBB: http://threadingbuildingblocks.org/
[3] threadingbuildingblocks.org: http://threadingbuildingblocks.org
[4] software.intel.com/en-us/intel-tbb: http://software.intel.com/en-us/intel-tbb
[5] software.intel.com/en-us/tags/17207: http://software.intel.com/en-us/tags/17207
[6] software.intel.com/en-us/tags/17220: http://software.intel.com/en-us/tags/17220
[7] software.intel.com/en-us/forums/intel-threading-building-blocks: http://software.intel.com/en-us/forums/intel-threading-building-blocks
[8] Источник: http://habrahabr.ru/post/161527/
Нажмите здесь для печати.