Android* 教程:使用英特爾® 線程構建模組編寫多線程應用

來源:互聯網
上載者:User

作者:Vladimir Polin

近來,我們發布了“Windows* 8 教程: 使用英特爾 線程構建模組為 Windows 市集* 編寫多線程應用”。 其中我們提到,並行計算引擎很容易匯入其他移動或台式機平台。 Android 是這種移動平台的一個典型的例子。

在最新發行的英特爾 線程構建模組(英特爾 TBB)的穩定版本中,我們為 Android 應用增加了實驗支援,即構建英特爾 TBB 庫,通過 JNI 介面在 Android 應用中使用。您可以從threadingbuildingblocks.org中下載 該版本。

如要在 Linux* 主機上啟動流程,請開啟英特爾 TBB 源發布,找到<unpacked_dir>/build/android_setup.csh 指令碼 並構建庫。您必須構建庫,因為開發版本僅可在源形式下發布。 <unpacked_dir>/build/index.android.html 檔案中包括在 Linux 上配置環境和構建庫的說明。

假定 %PATH%(在 Microsoft Windows* 主機平台上)和 $PATH (在 Linux 平台上)中 gnu make 3.81 可用,我們需要在 NDK 環境中執行下列命令來為 Android 構建英特爾 TBB 庫:
gmake tbb tbbmalloc target=android

上述是構建庫所需的操作;我們現在可以使用 Eclipse* 來構建樣本。 對於下列的樣本,我將使用 Windows* 的 Android SDK 工具 Rev.21 和 Android NDK Rev 8C 來說明跨平台開發的流程。

使用預設範本《New Android Application》建立新對象。 為簡單起見,我們將其命名為“app1”,與上述的發布相同:

選擇 FullscreenActivity 作為“活動”。 有關該模板的內容到此為止。 請注意不可以使用 com.example* 為 Google Play* 命名,但是它可以很好地協助我們理解。 

然後向主幀中添加幾個按鈕。 添加後,主幀的 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 functionsprivate 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("gnustl_shared");            System.loadLibrary("tbb");            System.loadLibrary("jni-engine");             }

在使用 "tbb" 庫時應清除所有內容,且需要使用 "gnustl_shared" 庫來支援 TBB 的 C++ 語言特性。但是,對於 "jni-engine" 庫,我們需要獲得更多內容。

"jni-engine" 是 С++ 庫,可執行計算引擎並為名為 onClickSRCall() 和 onClickSRCall() 的 JNI 調用輸出 C 介面。

根據 NDK 開發規則,在工作區內建立檔案夾 “jni” 並在該檔案夾下專門針對 "jni-engine" 庫建立 3 個檔案。

這些檔案是:

Android.mk ( <> 括弧中的文本應使用實際的值替換)

LOCAL_PATH := $(call my-dir)TBB_PATH := <path_to_the_package>include $(CLEAR_VARS)LOCAL_MODULE    := jni-engineLOCAL_SRC_FILES := jni-engine.cpp LOCAL_CFLAGS += -DTBB_USE_GCC_BUILTINS -std=c++11 -I$(TBB_PATH)/includeLOCAL_LDLIBS := -ltbb -L./ -L$(TBB_PATH)/<path_to_libtbb_so>include $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE    := libtbbLOCAL_SRC_FILES := libtbb.soinclude $(PREBUILT_SHARED_LIBRARY)

 

Application.mk

APP_ABI := x86APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rttiAPP_STL := gnustl_shared

 

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、libgnustl_shared.so 和 libtbb.so 庫。

接下來,切換回 Eclipse 並構建 app1.apk 檔案。 現在,可將應用安裝至 AVD 或實際的硬體上。 在 AVD 上時,它應如所示

操作到此結束! 這一簡單應用現可使用,且可以作為基礎為 Android 編寫更複雜的並行應用。 對於使用上一篇部落格中的代碼的使用者, 應用已成功移植到 Android。

*其他的名稱和品牌可能是其他所有者的資產。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.