一个使用TBB Lambda 表达式实现并行执行的例子

#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <mmsystem.h>
#include <time.h>
#include <omp.h>

#include "tbb/task_scheduler_init.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/spin_mutex.h"
#include "tbb/tick_count.h"

using namespace tbb;
using namespace std;

const int num_steps = 100000000;
const int num_threads = 4; // My laptop is T61
double step = 0.0, pi = 0.0;

static tbb::spin_mutex myMutex;
static CRITICAL_SECTION cs;

void Serial_Pi()
{
   double x, sum = 0.0;
   int i;

   for (i=0; i< num_steps; i++){
      x = (i+0.5)*step;
      sum = sum + 4.0/(1.0 + x*x);
   }
   pi = step * sum;
}

DWORD WINAPI threadFunction(LPVOID pArg)
{

 double partialSum = 0.0, x;  // local to each thread
 int myNum = *((int *)pArg);

 for ( int i=myNum; i<num_steps; i+=num_threads )  // use every num_threads step
 {
  x = (i + 0.5)*step;
  partialSum += 4.0 / (1.0 + x*x);  //compute partial sums at each thread
 }

 EnterCriticalSection(&cs);
   pi += partialSum * step;  // add partial to global final answer

 LeaveCriticalSection(&cs);

 return 0;
}

void WinThread_Pi()
{
 HANDLE threadHandles[num_threads];
 int tNum[num_threads];

 InitializeCriticalSection(&cs);
 for ( int i=0; i<num_threads; ++i )
 {
  tNum[i] = i;
  threadHandles[i] = CreateThread( NULL,            // Security attributes
                                   0,               // Stack size
                                   threadFunction,  // Thread function
                                   (LPVOID)&tNum[i],// Data for thread func()
                                   0,               // Thread start mode
                                   NULL);           // Returned thread ID
 }
 WaitForMultipleObjects(num_threads, threadHandles, TRUE, INFINITE);

}

void OpenMP_Pi()
{
double x, sum=0.0;
int i;

omp_set_num_threads(4/*omp_get_thread_num()*/);
#pragma omp parallel for private (x) reduction(+:sum) //schedule(static,4)

 for (i=0; i<num_steps; i++)
 {
  x = (i + 0.5)*step;
  sum = sum + 4.0/(1. + x*x);
 }

 pi = sum*step;
}

class ParallelPi {
 
public:

 void operator() (tbb::blocked_range<int>& range) const {
  double x, sum = 0.0;
  for (int i = range.begin(); i < range.end(); ++i) {
   x = (i+0.5)*step;
   sum = sum + 4.0/(1.0 + x*x);
  }
  tbb::spin_mutex::scoped_lock lock(myMutex);
  pi += step * sum;
 }
};

void TBB_Pi ()
{
 parallel_for (tbb::blocked_range<int> (0, num_steps), ParallelPi(), tbb::auto_partitioner());
}

void TBB_Lambda_Pi()
{
 parallel_for(blocked_range<int>(0, num_steps, 5000 /*grain_size*/),
  [](const blocked_range<int> &r){
   double x, sum = 0.0;
   for (int i = r.begin(); i!=r.end(); ++i){
    x = (i + 0.5)*step;
    sum = sum + 4.0/(1. + x*x);
   };
   tbb::spin_mutex::scoped_lock lock(myMutex);
   pi += step *sum;
 });
 
}

int main()
{

 clock_t start, stop;

 // Coputing pi by using serial code
 pi = 0.0;
 step = 1.0/(double) num_steps;
 start = clock();
 Serial_Pi();
 stop = clock();
 printf ("Computed value of Pi by using serial code: %12.9f/n", pi);
 printf ("Elapsed time: %.2f seconds/n", (double)(stop-start)/1000.0);

 // Computing pi by using Windows Threads
 pi = 0.0;
 step = 1.0 / (double)num_steps;
 start = clock();
 WinThread_Pi();
 stop = clock();
 printf ("Computed value of Pi by using WinThreads: %12.9f/n", pi);
 printf ("Elapsed time: %.2f seconds/n", (double)(stop-start)/1000.0);
 
 // Computing pi by using OpenMP
 pi = 0.0;
 step = 1.0 / (double)num_steps;
 start = clock();
 OpenMP_Pi();
 stop = clock();
 printf ("Computed value of Pi by using OpenMP: %12.9f/n", pi);
 printf ("Elapsed time: %.2f seconds/n", (double)(stop-start)/1000.0);

 // Computing pi by using TBB
 pi = 0.0;
 step = 1.0 / (double)num_steps;
 start = clock();
 tbb::task_scheduler_init tbb_init;
 TBB_Pi();
 stop = clock();
 printf ("Computed value of Pi by using TBB: %12.9f/n", pi);
 printf ("Elapsed time: %.2f seconds/n", (double)(stop-start)/1000.0);

 // Computing pi by using TBB's Lambda
 pi = 0.0;
 step = 1.0 / (double)num_steps;
 start = clock();
// tbb::task_scheduler_init tbb_init;
 TBB_Lambda_Pi();
 stop = clock();
 printf ("Computed value of Pi by using TBB's Lambda: %12.9f/n", pi);
 printf ("Elapsed time: %.2f seconds/n", (double)(stop-start)/1000.0);
 
 return 0;
}

Here are results:

Computed value of Pi by using serial code:  3.141592654

Elapsed time: 0.78 seconds

Computed value of Pi by using WinThreads:  3.141592654

Elapsed time: 0.55 seconds

Computed value of Pi by using OpenMP:  3.141592654

Elapsed time: 0.42 seconds

Computed value of Pi by using TBB:  3.141592654

Elapsed time: 0.44 seconds

转自http://software.intel.com/zh-cn/blogs/2009/06/10/tbb-lambda/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值