ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c-OpenMP并行线程

2019-10-09 16:17:02  阅读:179  来源: 互联网

标签:c performance parallel-processing openmp


我需要并行处理此循环,尽管我想使用它是一个好主意,但我以前从未研究过它们.

 #pragma omp parallel for

for(std::set<size_t>::const_iterator it=mesh->NEList[vid].begin();
        it!=mesh->NEList[vid].end(); ++it){

    worst_q = std::min(worst_q, mesh->element_quality(*it));
}

在这种情况下,循环不会并行化,因为它使用迭代器,并且编译器无法
了解如何拆分.

你能帮助我吗?

解决方法:

OpenMP要求for循环的并行控制谓词具有以下关系运算符之一:&lt ;、< =,>或> =.只有随机访问迭代器才提供这些运算符,因此OpenMP并行循环仅适用于提供随机访问迭代器的容器. std :: set仅提供双向迭代器.您可以使用显式任务来克服该限制.减少可以通过首先部分减少每个线程变量的私有值,然后全局减少部分值来执行.

double *t_worst_q;
// Cache size on x86/x64 in number of t_worst_q[] elements
const int cb = 64 / sizeof(*t_worst_q);

#pragma omp parallel
{
   #pragma omp single
   {
      t_worst_q = new double[omp_get_num_threads() * cb];
      for (int i = 0; i < omp_get_num_threads(); i++)
         t_worst_q[i * cb] = worst_q;
   }

   // Perform partial min reduction using tasks
   #pragma omp single
   {
      for(std::set<size_t>::const_iterator it=mesh->NEList[vid].begin();
          it!=mesh->NEList[vid].end(); ++it) {
         size_t elem = *it;
         #pragma omp task
         {
            int tid = omp_get_thread_num();
            t_worst_q[tid * cb] = std::min(t_worst_q[tid * cb],
                                           mesh->element_quality(elem));
         }
      }
   }

   // Perform global reduction
   #pragma omp critical
   {
      int tid = omp_get_thread_num();
      worst_q = std::min(worst_q, t_worst_q[tid * cb]);
   }
}

delete [] t_worst_q;

(我假设mesh-> element_quality()返回双精度值)

一些关键点:

>循环仅由一个线程串行执行,但是每次迭代都会创建一个新任务.这些很可能由空闲线程排队等待执行.
>在单个构造的隐式屏障处等待的空闲线程一开始创建就开始消耗任务.
>它所指向的值在任务主体之前被取消引用.如果在任务主体中取消引用,它将是firstprivate,并且将为每个任务(即在每次迭代中)创建迭代器的副本.这不是您想要的.
>每个线程在其t_worst_q []的私有部分中执行部分缩减.
>为了防止由于错误共享而导致的性能下降,每个线程访问的t_worst_q []元素被分隔开,从而以单独的缓存行结尾.在x86 / x64上,高速缓存行为64字节,因此线程号乘以cb = 64 / sizeof(double).
>全局最小化减少是在关键构造内部执行的,以防止badest_q被多个线程一次访问.这仅出于说明目的,因为减少也可以通过并行区域之后的主线程中的循环来执行.

请注意,显式任务需要支持OpenMP 3.0或3.1的编译器.这排除了所有版本的Microsoft C/C++编译器(仅支持OpenMP 2.0).

标签:c,performance,parallel-processing,openmp
来源: https://codeday.me/bug/20191009/1880413.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有