Introduction
This Tip introduces how to use parallel_for_each which is introduced in Parallel Pattern Library ( PPL ).
Background
There is a very good online book on PPL on MSDN site "Parallel Programming with Microsoft Visual C++
Design Patterns for Decomposition and Coordination on Multicore Architectures", please refer it for more insight into writing high performance applications which uses multi core CPUs. The following code needs visual studio 2010.
The Online book link is...
http://msdn.microsoft.com/en-us/library/gg675934.aspx
Testing the parallel_for_each
I have written a small console snippet to test parallel_for_each which is in Concurrency namespace. parallel_for_each is useful in the case of data concurrency rather than task concurrency. In this example I have taken prime number checking over a random sequence of numbers and a leniar incremented sequence. I have compared that with sequential std::for_each. I have created two function objects one Increment and other CheckPrime
A brief description of how to use the article or code. The class names, the methods and properties, any tricks or tips.
Includes which nedded to be added is ppl.h in my example I have added few more for using other utilities
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<ppl.h>
using namespace std;
The Two function object classes I used to call from parallel_for_each, for_each and std::generate. Note that "operator ()(int n) const" is declared inside the CheckPrime since in the declaration of parallel_for_loop function template the function object it takes as third parameter is const function object.
class Increment
{
unsigned int count;
public:
Increment()
{
count = 0;
}
unsigned int operator()()
{
return ++count;
}
};
class CheckPrime
{
public:
bool operator ()(int n) const
{
if (n < 2)
{
cout<<"Not Prime:"<<n<<endl;
return false;
}
if (n < 4)
{
cout<<"Prime:"<<n<<endl;
return true;
}
if (n % 2 == 0)
{
cout<<"Not Prime:"<<n<<endl;
return false;
}
unsigned int iMax = (int)sqrt((double)n) + 1;
unsigned int i;
for (i = 3; i <= iMax; i += 2)
if (n % i == 0)
{
cout<<"Not Prime:"<<n<<endl;
return false;
}
cout<<"Prime:"<<n<<endl;
}
};
main function which uses parallel_for_each
int _tmain(int argc, _TCHAR* argv[])
{
CheckPrime funobj;
Increment incobj;
char ch;
vector<int> myrandints(4500);
vector<int> mysecints(4500);
generate(myrandints.begin(),myrandints.end(),rand);
generate(mysecints.begin(),mysecints.end(),incobj);
cout<<"Press any key to start sequential prime detection";
ch = getchar();
std::for_each(myrandints.begin(),myrandints.end(),funobj);
std::for_each(mysecints.begin(),mysecints.end(),funobj);
cout<<"Sequential processing of 9000 numbers done,enter any key for Parllel test...";
ch = getchar();
Concurrency::parallel_for_each(myrandints.begin(),myrandints.end(),funobj);
Concurrency::parallel_for_each(mysecints.begin(),mysecints.end(),funobj);
return 0;
}
Points of Interest
Not all for loops can be converted into parallel_for_loops, especially if the code running in the loop is very little or if the code statements are interdependent, please read the online book for more info.