Windows* 8 Tutorial: Writing a Multithreaded Application for the Windows Store* using Intel® Threading Building Blocks.

It is known that the Windows Store apps API is missing some commonly used thread functions, such as function CreateThread() and those that work with TLS keys. This is yet another great opportunity to move your application development from thread-based parallelism to task-based parallelism. This post shows step-by-step instructions for writing an  example that uses parallelism and that can pass validation by the Windows App Certification Kit (WACK). This example can be expanded upon to support clients for online games and more. Moreover since Intel® Threading Building Blocks (Intel® TBB, threadingbuildingblocks.org) is used to implement the parallelism, the parallel calculation engine can be easily ported to other mobile or desktop platforms.

In a recently posted development release of Intel TBB, tbb41_20121112oss, we have added experimental support for Windows 8 Store applications.  This release of the library uses APIs that will pass Windows App Certification.  You can download this release from threadingbuildingblocks.org.  

So, what is required to build a simple application for the windows store using Intel TBB?

To start, unpack the Intel TBB source distribution and build the library.  This is necessary because development releases are distributed in source form only.

Assuming that gnu make 3.81 is available in the %PATH% we need to issue the following command in the Visual Studio* 2012 command prompt

 gnumake tbb tbbmalloc target_ui=win8ui target_ui_mode=production 

This command will build the Intel TBB library for Windows Store Apps.   That’s it from the library side; we can now move to the Visual Studio 2012 IDE.

Create new project  «Blank App (XAML)» using a default template «Visual C++» ->«Windows Store». For simplicity, keep the default project name «App1».

Next, add the folder <TBB_folder>/include to the project properties «Additional Include Directories» and add the folder that contains the tbb.lib library file to «Additional Library Directories».  Visual Studio should now be able to find the Intel TBB headers and the library.

To create a simple app, add a couple of buttons to the main page (App1.MainPage class). After adding these, the XAML file of the page will look like


<Page

    x:Class="App1.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:App1"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

        <Button Name="SR" Margin="167,262,0,406" Height="100" Width="300" 

         Content="Press to run Simple Reduction"></Button>

        <Button Name="DR" Margin="559,262,0,406" Height="100" Width="300" 

         Content="Press to run Deterministic Reduction"></Button>

    </Grid>

</Page>

Before going further, it’s a good idea to check that there’s nothing wrong in the setup and that all of the required permissions and developer licenses are available. To check this, build and launch the application.  Then check that the 2 buttons work as expected and there are no crashes. If everything works, then the setup is correct, and you can now add the library.

Next, add Intel TBB library functions in the handlers for the buttons. As an example, let’s use reduction (tbb::parallel_reduce) and deterministic reduction (tbb::parallel_deterministic_reduce) algorithms.  To do so, add the following code to the main page source file MainPage.xaml.cpp: 


#include "tbb/tbb.h"

 

void App1::MainPage::SR_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)

{

    int N=1000000;

    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;

    }

    );  

    SR->Content="Press to run Simple ReductionnThe result is " + sum.ToString();

}

 

void App1::MainPage::DR_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)

{

    int N=1000000;

    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;

    }

    );  

    DR->Content="Press to run Deterministic ReductionnThe result is " + sum.ToString();

}

The XAML file for the main page should now look like:
<!--[if !supportLineBreakNewLine]-->

 <!--[endif]-->

<Page

    x:Class="App1.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:App1"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

        <Button Name="SR" Margin="167,262,0,406" Height="100" Width="300" 

         Content="Press to run Simple Reduction" Click="SR_Click"></Button>

        <Button Name="DR" Margin="559,262,0,406" Height="100" Width="300" 

         Content="Press to run Deterministic Reduction" Click="DR_Click"></Button>

    </Grid>

</Page>

Next add the tbb.dll and tbbmalloc.dll libraries to the application container. In order to do this add files to the project via “project->add existing item” and set the “Content” property to «Yes». In this case, the files will be copied to container (AppX) and then can be loaded during application launch as well as on demand.

The application is ready. Now you can launch a simulator and see how nice the curves of CPU load are when you press the buttons:

Finally, the last step is to launch WACK and check that application successfully passes validation:

That’s it! This simple application is ready and should be a good start towards writing a more complex parallel application for the Windows Store using Intel® Threading Building Blocks.

 

* Other names and brands may be claimed as the property of others.

Tags:
For more complete information about compiler optimizations, see our Optimization Notice.