c - OpenMP 任务和 while 循环
问题描述
我很难理解以下代码中发生的事情:
/*runs with 4 threads*/
int count_good(item_t* item){
int n=0;
int pn[num_thr];
#pragma omp parallel
{
pn[omp_get_thread_num()]=0;
#pragma omp single nowait
{
while(item){
#pragma omp task firstprivate(item)
{
if(is_good(item))pn[omp_get_thread_num( )]++;
}
item = item ->next;
}
}
#pragma omp atomic
n+=pn[omp_get_thread_num()];
}
return n;
}
首先打开一个并行区域,一个线程进入 while 循环。每次循环再次开始时,这个线程都会挂起一个任务。线程将任务推送到任务队列。其他线程可以从队列中获取任务并执行它。它是否正确?还是我理解错了?
解决方案
您对任务如何工作以及此代码试图做什么的模型是正确的。单个线程正在创建任务(然后,当它完成时也会执行它们),而其他线程只是在执行它们。
该代码通过计算每个线程看到的“好”项目的数量来执行总和减少。(在 OpenMP 5.0 中,它可以使用任务缩减)。
尽管我之前说过(对此我深表歉意),但这段代码是正确的,因为在单个语句的末尾有一个隐含的障碍。因此,除了执行单个语句的线程之外的所有线程都在那里等待,并拾取并执行任务。一旦执行单个语句的线程耗尽了列表(并生成了所有任务),它也会到达屏障并开始执行任务。一旦所有任务都执行完毕,屏障就可以完成。此时线程将继续(原子地)将它们的贡献添加到全局总和中。
我忘记的是与单个语句相关的隐含障碍(这有点令人困惑,因为看起来类似的主语句没有一个!)。但是,由于有一个,因此此代码很好。(除了每个线程的累加器会受到很多错误共享的性能问题。为了避免每个都应该填充到缓存行的大小[x86 上的 64 字节])。
推荐阅读
- matplotlib - Seaborn kdeplot 更改标题
- javascript - 如果对象 id 在其他对象 id 中有自己的属性,则更改数组中的对象值
- css - 使线性模糊对卡片做出反应
- ksh - 如何在使用 KSH 脚本开发的应用程序中将请求从 GET 转换为 POST?
- django-modeladmin - 从 ModelAdmin 操作访问相关模型字段以导出到 excel
- amazon-web-services - 如何在“ifelse”聚合中使用 sum 或 sumif
- c# - ASP.NET Core MVC 中的重定向 404 和 500 错误
- neo4j - 在neo4j中,我可以根据查询结果直接创建另一个数据库吗?
- javascript - 对 Vue 真的很陌生,你能帮我算一笔吗?
- typescript - Map - ts 中的嵌套泛型类型