📜 ⬆️ ⬇️

Calculate Pi using Intel Threading Building Blocks

Many Android devices use processors with multiple processing cores, so the ability to create multi-threaded programs is becoming increasingly important in the mobile application development industry. Intel offers valuable tools for developing “parallel” applications — it's called Intel Threading Building Blocks (Intel TBB). Essentially, Intel TBB is a cross-platform template library for creating parallel programs. It allows you to create and synchronize data streams, leaving behind details of the architecture and allowing you to work at a high level of abstraction. Intel TBB supports all architectures. As for the Android OS, you should use version 4.3 and higher.

image

Create Intel TBB


  1. Download Intel TBB, you can find it here: www.threadingbuildingblocks.org .

  2. Add NDK to PATH. For Windows:
    ')
    $ SET PATH=%PATH%; 

    For Linux:

     $ export PATH=$PATH: 

  3. Unzip TBB and go to the source directory and the src folder.

     $ cd /src/ 

  4. Run TBB for Android:

     $ /ndk-build –C /src/ arch=intel64 compiler=gcc target=android clean tbb tbbmalloc –j 

    This command creates TBB for the 64-bit version of Android 64. To form the TBB for the 32-bit version of Android, replace arch = intel64 with arch = ia32.

  5. Library is created. In the corresponding directory (/ build /) you will find subdirectories with libraries: libgnustl_shared.so, libtbbmalloc_proxy.so, libtbbmallolo.so and libtbb.so. libtbb.so and libgnustl_shared. Now they can be used in our application.

Calculate Pi


To calculate Pi, you can choose in Wikipedia any formula with a definite integral . I chose the following formula:

image

For this program, I modified this formula:

image

To calculate the integral, I used the rectangle method. The integrable function is divided into N = 10 7 equal subintervals of length h = 2 · 10 -7 . Then, the approximation of the integral is calculated by adding the areas (base x height) of N rectangles using the formula:

image

Create application


Create a new Android application:

image

Create a “Main Activity” (Main Activity). Copy the following code into res / layout / activity_main.xml:

 <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="intel.example.pitbbcalc.MainActivity" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/title" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/startButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/start" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/pi_equally" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pi_equally" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/pi_val" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> </LinearLayout> </RelativeLayout> 

And in res / values ​​/ strings.xml, this code:

 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">PiTBBCalc</string> <string name="action_settings">Settings</string> <string name="start">Start</string> <string name="title">Calculation of π</string> <string name="pi_equally">π = </string> </resources> 

Now the Main Activity looks like this:

image

Next, we need to implement a Java interface for our activity. Add the following code to the src / intel.example.pitbbcalc / MainActivity.java file:

 package intel.example.pitbbcalc; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private native double onClickCalc(); private TextView piEqually; private TextView piVal; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button startButton = (Button) findViewById(R.id.startButton); piEqually = (TextView) findViewById(R.id.pi_equally); piVal = (TextView) findViewById(R.id.pi_val); piEqually.setVisibility(View.INVISIBLE); piVal.setVisibility(View.INVISIBLE); startButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO    double val = onClickCalc(); piVal.setText(String.valueOf(val)); piEqually.setVisibility(View.VISIBLE); piVal.setVisibility(View.VISIBLE); } }); System.loadLibrary("PiTBBCalc"); System.loadLibrary("tbb"); } @Override public boolean onCreateOptionsMenu(Menu menu) { //  ;     ,  . getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { //    .   //      Home/Up,  //  AndroidManifest.xml   . int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } 

In Project Explorer -> Android Tools -> Add Native Support, you can specify native support for right-clicking on our project. In the next window, enter the name of the library of our project and click on Finish.

image

So, we have implemented the native code to calculate the integral in one stream. Add the following code to the jni / PiTBBCalc.cpp file:

 #include <jni.h> #include <math.h> double piIntFunc (const double x) { return sqrt(1 - pow(x, 2.0)); } double calcPi() { const unsigned int n = pow(10.0, 7); double a(-1), b(1); double h = (b - a) / n; double x (a); for (unsigned int i (0); i < n; ++i) { sum += piIntFunc(x); x += h; } sum *= h; return 2 * sum; } extern "C" JNIEXPORT jdouble JNICALL Java_intel_example_pitbbcalc_MainActivity_onClickCalc(JNIEnv *env, jobject obj) { return calcPi(); } 

Let's try to run our application and calculate the pi number in single-threaded mode:

image

To add parallel computations to the project using Intel TBB, jni / Android.mk needs to be edited. Android.mk is the Makefile for our project, and you need to add the Intel TBB libraries to it:

 LOCAL_PATH := $(call my-dir) TBB_PATH := <tbb_sources> TBB_BUILD_PATH := /build/linux_intel64_gcc_android_cc4.9_NDKr10b_version_android-L_release include $(CLEAR_VARS) LOCAL_MODULE := PiTBBCalc LOCAL_SRC_FILES := PiTBBCalc.cpp LOCAL_CFLAGS += -DTBB_USE_GCC_BUILTINS -std=c++11 -fexceptions -Wdeprecated-declarations -I$(TBB_PATH)/include -I$(TBB_PATH)$(TBB_BUILD_PATH) LOCAL_LDLIBS := -llog -ltbb -L./ -L$(TBB_PATH)$(TBB_BUILD_PATH) LOCAL_SHARED_LIBRARIES += libtbb include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := libtbb LOCAL_SRC_FILES := $(TBB_PATH)$(TBB_BUILD_PATH)/libtbb.so include $(PREBUILT_SHARED_LIBRARY) 

In the jni / directory, create the Application.mk file and add the following lines to it:

 APP_ABI := x86_64 APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti APP_STL := gnustl_shared 

Here, the purpose of Application.mk is to describe the native modules that we need for our application (that is, static / shared libraries). In the line APP_ABI: = x86_64, we define our target architecture.

Now we will try to start the application. If you see the main screen of the application, the Intel TBB libraries are linked successfully, and we can start developing our application.

To add concurrency, we need to include the Intel TBB header: #include "tbb / tbb.h", remove the loop, and add the following code:

 double sum = tbb::parallel_reduce( tbb::blocked_range<unsigned int>(0,n), double(0), //    [&](const tbb::blocked_range<unsigned int>& r, double sum)->double { for( int i=r.begin(); i!=r.end(); ++i ) { sum += piIntFunc(x); x += h; } return sum; //       }, []( double x, double y )->double { return x+y; //     } ); 

And now, if you run the application, it will work in multi-threaded mode.

The end


As you can see, the development of parallel applications is very simple. Using the calculation of Pi as an example, we were able to successfully demonstrate how the concepts of single-threaded code are applied in multi-threaded code.

Mistress note:

" Threading Building Blocks - the basic elements of multithreading
» Creating parallel Android applications for a 64-bit architecture using Intel TBB
» Android tutorial: writing multi-threaded applications with Intel Threading Building Blocks

Source: https://habr.com/ru/post/260083/


All Articles