2012-07-12 63 views
0

我想在OpenMP的帮助下并行化这些代码,例如 #pragma omp parallel for,以将工作分成不同的线程。与SETS一起使用openMP

什么将是一种有效的方式?这里level是在多个线程之间共享的。

这里是一个集合。

for(iter=make.at(level).begin();iter!=make.at(level).end();iter++) 
{ 
    Function(*iter); 
} 

回答

2

如果make.at(level)返回的类型有持续访问时间如果你的编译器支持最新足够的OpenMP版本随机访问迭代器(读:这是 MSVC++),那么你可以直接使用parallel for工作共享指令:

obj = make.at(level); 
#pragma omp parallel for 
for (iter = obj.begin(); iter != obj.end(); iter++) 
{ 
    Function(*iter); 
} 

如果该类型不提供拉多姆访问迭代器,但仍然你的编译器支持OpenMP的3.0或更新版本,那么你可以使用OpenMP的任务:

#pragma omp parallel 
{ 
    #pragma omp single 
    { 
     obj = make.at(level); 
     for (iter = obj.begin(); iter != obj.end(); iter++) 
     { 
      #pragma omp task 
      Function(*iter); 
     } 
    } 
} 

这里一个线程执行for循环并创建许多OpenMP任务。每项任务将使用相应的值*iterFunction()进行一次调用。然后,每个空闲线程将开始从未完成的任务列表中选取。在并行区域的末尾存在一个隐含的障碍,所以主线程将在继续执行并行区域之前尽职地等待所有任务完成。

如果你不幸用微软的Visual C++,那么你就没有多少选择的余地,而不是创建对象的指针数组,并使用一个简单的整数循环迭代它:

obj = make.at(level); 
obj_type* elements = new obj_type*[obj.size()]; 
for (i = 0, iter = obj.begin(); i < obj.size(); i++) 
{ 
    elements[i] = &(*iter++); 
} 

#pragma omp parallel for 
for (i = 0; i < obj.size(); i++) 
{ 
    Function(*elements[i]); 
} 

delete [] elements; 

这不是最优雅的解决方案,但它应该工作。

编辑:如果我从你的问题的标题正确理解,你正在使用集合。这排除了第一个算法,因为集合不支持随机访问迭代器。取决于编译器对OpenMP任务的支持,使用第二种或第三种算法。

0

要使用使用OpenMP这个迭代器模式可能需要如何进行循环重新思考 - 你不能用#pragma omp for,因为你的循环不是一个简单的整数循环。我不知道下面将工作:

iter = make.at(level).begin(); 
end = make.at(level).end(); 

#pragma omp parallel private(iter) shared(make,level,end) 
{ 
    #pragma omp single 
    func(iter);      /* only one thread does the first item */ 

    while (1) 
    { 
     #pragma omp critical 
     iter = make.at(level).next(); /* each thread gets a different item */ 

     if (iter == end) 
      break; 

     func(iter); 
    } 
} /* end parallel block */ 

注意,我不得不改变你的iter++进入临界区一个next()调用,使其工作。原因是共享的对象需要记住哪些项目已经被处理。