Using the Intel® Threading Building Blocks (Intel® TBB) Library with the Intel AppUp(TM) SDK Suite for MeeGo*
Intel® Threading Building Blocks for MeeGo* is a runtime-based parallel programming model for C++ code that uses threads. It consists of a template-based runtime library to help you harness the latent performance of multicore processors. Use Intel® Threading Building Blocks to write scalable applications that:
- Specify logical parallel structure instead of threads
- Emphasize data parallel programming
- Take advantage of concurrent collections and parallel algorithms
This guide provides a complete example that uses Intel® Threading Building Blocks to write, compile, link, and run a parallel application for MeeGo* using the Intel AppUp™ SDK Suite for MeeGo*. The example shows you how to explore a key feature of the library and to successfully build, link, and deploy an application for a MeeGo* target. After completing this guide, you should be ready to write and build your own code using Intel® Threading Building Blocks.
Locations of Files
Before you begin, make sure you have successfully installed Intel® Threading Building Blocks on your development system/host machine by Installing The Intel® AppUp™ SDK Suite for MeeGo* which includes the Intel® C++ Compiler for MeeGo.
See the “Intel® C++ Compiler for MeeGo* Release Notes” at http://appdeveloper.intel.com/en-us/article/intel-appup-sdk-suite-meego-support-articles for your particular host on how to install.
Also make sure you have installed the MeeGo* SDK 1.1 or MeeGo SDK 1.2.
The default installation locations for the lib and include directories used in this document are shown in the following table:
|
Platform |
Default Directories |
|
Linux* OS Host |
/opt/intel/appup-meego-tools/icc-meego-<version>/tbb/[lib|include] |
|
Windows* OS Host |
C:\AppUp-MeeGo-Tools\ICC-MeeGo-host-<version>\tbb\[lib|include] |
Creating an Application in Qt* Creator.
If you prefer you can skip the next 3 sections of the document and instead download the Sample Code provided with this article.
If you are new to Qt* Creator and Building Applications With Qt Creator you may want to see: “Building a MeeGo App for Linux*|Windows*” at http://appdeveloper.intel.com/en-us/article/intel-appup-sdk-suite-meego-support-articles
- Launch Qt Creator
- Create a Qt Creator Console Application:
- In Qt Creator from the “File” menu click “File”: “New File or Project”
- In the New window under “Choose a template” select: “Qt C++ Project”:”Qt Console Application”
- Then click the “Choose...” button
- In the “Qt Console Application” window under “Introduction and Project Location”, fill in the “Name” of the Project (i.e: SubStringFinder), then click the “Next” button
- If more than one MeeGo* SDK target is installed, click the box beside the desired target device
- In the “Qt Console Application” window under “Project Management”, click the “Finish” button.
Qt* Creator will now have created an application that has a single source file (main.cpp) and a project file “<Project_name>.pro”.
Note: If you are using the MeeGo SDK 1.2 for Windows you will need to turn off Shadow Build.
Setting up the Project File
Before you can start building our Intel® TBB application for MeeGo*, you will need to instruct Qt* Creator how to Compile, Link and Package Intel TBB Libraries. Intel® Threading Building Blocks only ships with shared object libraries for MeeGo*. You need to consider the following extra issues when using a shared object library in MeeGo.
- How the application will find the shared object library on the MeeGo Device.
- Placing the shared object library into the rpm so that the shared object will be copied to the proper location on the MeeGo* Target Device.
There are at least 3 major approaches to addressing these issues:
- Put shared object libraries in /usr/lib
- Define LD_LIBRARY_PATH
- Use the linker to add an “rpath” to the binary
Each of these approaches has advantages and disadvantages. In considering which of these approaches to use, you should make sure the approach you ultimately use meets the compliance requirements of MeeGo*. See http://wiki.meego.com/Quality/Compliance for further information on compliance requirements for MeeGo*.
This section of the document describes the easiest method to use (/usr/lib) during the initial development and debugging cycle. But you “may” need to use a more complicated approach to meet MeeGo* Compliance Requirements. I will describe another more complicated method later in this guide.
Setup Project to Compile and Link using Intel TBB Libraries
Open the project file by clicking on “Edit” on the left side of the screen, then on the project file itself ( “<Project_name>.pro” ).
- Add the Following helper lines to the project file to make it easier to use tbb:
# TBB uses the underlying OS’ thread library
CONFIG += thread
#Path to the root of the tbb Directory
#NOTE: Only one of the "TBB_INSTALL_DIR" lines below should be uncommented #NOTE: This path works from Windows* no matter how you launch Qt Creator. # Modify this to point to the location you installed TBB: #TBB_INSTALL_DIR = "C:\AppUp-MeeGo-Tools\ICC-MeeGo-host-12.0.0.010\tbb" #NOTE: This path works from Windows* if you launch Qt Creator # from the Intel(R) AppUp SDK for MeeGo* under the start menu. #TBB_INSTALL_DIR = "$$(TBB30_MEEGO_INSTALL_DIR)" #NOTE: This path works from Linux* only if you launch Qt Creator using the # launch_sdk.sh or launch_sdk.csh scripts from Intel(R) AppUp SDK for MeeGo* #TBB_INSTALL_DIR = "$$(TBB30_INSTALL_DIR)" #Path to the TBB libraries the TBB_INSTALL_DIR directory defined above TBB_LIB_DIR = lib/ia32/cc4.1.0_libc2.4_kernel2.6.16.21 #Use libtbb_debug.so for debug builds or libtbb.so for release builds CONFIG(debug, debug|release) { TBB_LIB_BASE = tbb_debug TBB_LIB_NAME = libtbb_debug.so.2 } else { TBB_LIB_BASE = tbb TBB_LIB_NAME = libtbb.so.2 }
- Add the following basics to the project file to tell the compiler and linker how to compile and link in TBB:
#This tells the compiler wfere the TBB headers is are located on Windows*:
INCLUDEPATH += "$$TBB_INSTALL_DIR/include" #This tells the linker which library to link to: #uncomment one of the LIBS lines below #from a Linux* host machine, add extra "../" sequences until it works, # having too many “../” just makes it start at root #LIBS += -L"../../../../../../../../../../../..$$TBB_INSTALL_DIR/$$TBB_LIB_DIR" #from a Windows* host machine: #LIBS += -L"$$TBB_INSTALL_DIR/$$TBB_LIB_DIR" LIBS += -l$$TBB_LIB_BASE
Note: This particular application only uses libtbb.so – Other applications may use other shared object libraries provided by Intel® threading Building Blocks. See the TBB reference manual for more information.
- Now add the following lines to the .pro to put libtbb.so into the rpm which will be placed onto the target system.
#specify target install path and files to install
tbb_2.path = /usr/lib tbb_2.files = "$$TBB_INSTALL_DIR/$$TBB_LIB_DIR/$$TBB_LIB_NAME"
- Now edit the install line
INSTALLS=target tbb_2
Develop an Application Using TBB
This section presents a basic example that uses the parallel_for template of TBB in a substring matching program. For each position in a string, the program displays the length and location of the largest matching substring elsewhere in the string.
Consider the string “babba” as an example. Starting at position 0, “ba” is the largest substring with a match elsewhere in the string (position 3).
In this section, new code that is added in each step is shown in blue. Code that is carried over from a previous step is shown in black. Lines are numbered in the order they appear in the final completed example.
To develop the example code:
1. The using statement imports the namespace tbb, in which all of the TBB classes and functions are found.
|
29: |
using namespace tbb; |
|
|
|
|
60: |
int main(int argc, char *argv[]) { |
|
61: |
QCoreApplication a(argc, argv)
|
|
78: |
return 0; |
|
79: |
} |
2. Create the example string that is transformed by the program) and the arrays for holding the lengths of the largest matched substrings and their locations.
The example generates a Fibonacci string consisting of a series of ‘a’ and ‘b’ characters. Add statements to output the lengths and locations of the largest substring matches for each position.
|
23: |
#include <iostream> |
|
24: |
#include <string> |
|
|
|
|
29: |
using namespace tbb; |
|
29: |
using namespace std; |
|
31: |
static const size_t N = 11; |
|
|
|
|
60: |
int main(int argc, char *argv[]) { |
|
|
|
|
62: |
string str[N] = { string("a"), string("b") }; |
|
63: |
for (size_t i = 2; i < N; ++i) str[i] = str[i-1]+str[i-2]; |
|
64: |
string &to_scan = str[N-1]; |
|
65: |
size_t num_elem = to_scan.size(); |
|
|
|
|
67: |
size_t *max = new size_t[num_elem]; |
|
68: |
size_t *pos = new size_t[num_elem]; |
|
|
|
|
70—71: |
// will add code to populate max and pos here |
|
|
|
|
73: |
for (size_t i = 0; i < num_elem; ++i) |
|
74: |
cout << " " << max[i] << "(" << pos[i] << ")" << endl; |
|
75: |
delete[] pos; |
|
76: |
delete[] max; |
|
78: |
return 0; |
|
51: |
} |
3. Add a call to the parallel_for function.
The first parameter of the call is a blocked_range object that describes the iteration space.
blocked_range is a template class provided by the Intel® Threading Building Blocks library. The constructor takes two arguments:
¾ The lower bound of the range.
¾ The upper bound of the range.
The second parameter to the parallel_for function is the function object to be applied to each subrange: “SubStringFinder()”.
|
23: |
#include <iostream> |
|
24: |
#include <string> |
|
26: |
#include "tbb/parallel_for.h" |
|
27: |
#include "tbb/blocked_range.h" |
|
|
|
|
29: |
using namespace tbb; |
|
30: |
using namespace std; |
|
31: |
static const size_t N = 11; |
|
|
|
|
60: |
int main(int argc, char *argv[]) { |
|
|
|
|
62: |
string str[N] = { string("a"), string("b") }; |
|
63: |
for (size_t i = 2; i < N; ++i) str[i] = str[i-1]+str[i-2]; |
|
64: |
string &to_scan = str[N-1]; |
|
|
|
|
65: |
size_t num_elem = to_scan.size(); |
|
|
|
|
67: |
size_t *max = new size_t[num_elem]; |
|
68: |
size_t *pos = new size_t[num_elem]; |
|
|
|
|
70: |
parallel_for(blocked_range<size_t>(0, num_elem ), |
|
71: |
SubStringFinder( to_scan, max, pos ) ); |
|
|
|
|
73: |
for (size_t i = 0; i < num_elem; ++i) |
|
74: |
cout << " " << max[i] << "(" << pos[i] << ")" << endl; |
|
75: |
delete[] pos; |
|
76: |
delete[] max; |
|
78: |
return 0; |
|
79: |
} |
4. Implement the body of the parallel_for loop.
At runtime, the TBB function parallel_for automatically divides the range into subranges and invokes the SubStringFinder operator on each subrange.
5. Define the class SubStringFinder to populate the max and pos array elements found within the given subrange.
The r.begin() method returns the start of the subrange and the r.end() method returns the end of the subrange.
|
23: |
#include <iostream> |
|
24: |
#include <string> |
|
24: |
#include <algorithm> |
|
26: |
#include "tbb/parallel_for.h" |
|
27: |
#include "tbb/blocked_range.h" |
|
|
|
|
29: |
using namespace tbb; |
|
30: |
using namespace std; |
|
31: |
static const size_t N = 23; |
|
|
|
|
33: |
class SubStringFinder { |
|
34: |
const string str; |
|
35: |
size_t *max_array; |
|
36: |
size_t *pos_array; |
|
37: |
public: |
|
38: |
void operator() ( const blocked_range<size_t>& r ) const { |
|
39: |
for ( size_t i = r.begin(); i != r.end(); ++i ) { |
|
40: |
size_t max_size = 0, max_pos = 0; |
|
41: |
for (size_t j = 0; j < str.size(); ++j) |
|
42: |
if (j != i) { |
|
43: |
size_t limit = str.size()-max(i,j); |
|
44: |
for (size_t k = 0; k < limit; ++k) { |
|
45: |
if (str[i + k] != str[j + k]) break; |
|
46: |
if (k > max_size) { |
|
47: |
max_size = k; |
|
48: |
max_pos = j; |
|
49: |
} |
|
50: |
} |
|
51: |
} |
|
52: |
max_array[i] = max_size; |
|
53: |
pos_array[i] = max_pos; |
|
54: |
} |
|
55: |
} |
|
56: |
SubStringFinder(string &s, size_t *m, size_t *p) : |
|
57: |
str(s), max_array(m), pos_array(p) { } |
|
58: |
}; |
|
|
|
|
60—81: |
// The function main starting at line 60 goes here |
Build the TBB Application
Intel® Threading Building Blocks for MeeGo* works with both GCC* and the Intel® C/C++ Compiler for MeeGo*. To Compile Applications with the Intel® C/C++ Compiler for MeeGo*, see: “How to use Intel(R) C++ Compiler in Qt Creator” at http://appdeveloper.intel.com/en-us/article/intel-appup-sdk-suite-meego-support-articles
Building Code via the Included Sample
If you did not create the example described in the previous chapters, build from the completed source code provided with this article here.
Start Nokia’s QT Creator
- From the Menu Choose “File”: “Open File or Project”
- Open the File “Sub_Sting_Finder\Sub_String_Finder.pro”
- In the “Project Setup Dialogue”
- Open the .pro file
- Uncomment (delete the #) for the appropriate TBB_INSTALL_DIR = to specify the location in which Intel® Threading Building Blocks is installed, depending on the conditions in the comments.
- Uncomment (delete the #) for the appropriate LIBS+=-L”[location]” based on the conditions in the comments.
Note: If using MeeGo SDK 1.2 for Windows you will need to turn Shadow Builds off.
Building/Linking and Packaging the Sample
- From within Nokia’s QT Creator choose “Build”: “Rebuild All” from the Menu Bar.
Note: For trouble-shooting make sure to look in the output window of “Compile Output” – check the commands/paths given for building, linking and packaging.
Run the Application
Running the application involves setting up QT Creator* for your device or emulator, and setting up the device or the emulator to connect to the development platform. For instructions on how to set those up please see the corresponding documentation at: “Building a MeeGo* App for Linux*|Windows*” at http://appdeveloper.intel.com/en-us/article/intel-appup-sdk-suite-meego-support-articles.
You should now be able to select “Build”: “Run” from the Nokia QT Creator Menu and run your application. QT Creator will copy your new application and the TBB library over to the MeeGo* Target, install it, and run the application.
In the QT Creator Output Window you should get something that looks like:
Cleaning up remote leftovers first ...
Initial cleanup done.
Files to deploy: C:/DEV/projects/MeeGo/sub_string_finder/rrpmbuild\sub_string_finder-0.0.1-1.i586.rpm.
Deployment finished.
Starting remote application.
52(34)
51(35)
50(36)
[... and so on to 0]
Next Steps
To get the most out of Intel® Threading Building Blocks, explore the following additional resources.
1. Tutorial is a document that walks you through the major classes, algorithms and concepts used by Intel® Threading Building Blocks.
2. Design Patterns is a “cookbook” of some common parallel programming patterns using Intel® Threading Building Blocks.
3. Reference is a complete, detailed reference manual for all the functions and interfaces provided by Intel® Threading Building Blocks.
| Optimization Notice |
|---|
|
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice. Notice revision #20110804 |