c - OpenMP 中数组内容的并行更新 - 并发添加元素
问题描述
我有以下代码,我想让它并行(伪代码)
int na = 10000000;
int nb = na;
double A[na];
double B[2*na];
double a;
for(int j=0;j<nb;j++)
{
i = rand() % na;
A[i]+=5.0*i;
B[i+10]+=6.0*i*i;
}
当然,我不能使用#pragma omp parallel for
,因为有时(无法预测)同一个元素会被两个线程同时访问。这段代码如何并行化?谢谢
解决方案
有两种方法可以做到这一点:
对值使用原子更新
#pragma omp parallel for for(int j=0;j<nb;j++) { // make sure to declare i locally! int i = fun(); #pragma omp atomic A[i]+=5.0*i; }
这是最简单的方法。每次写入都是原子执行的,因此成本更高。您还需要考虑从多个线程访问相邻元素变得昂贵(错误共享)。如果
A
很大,并且每次更新都需要进行大量计算,请使用此选项。使用数组缩减
#pragma omp parallel for reduction(+:A) for(int j=0;j<nb;j++) { // make sure to declare i locally! int i = fun(); A[i]+=5.0*i; }
这将为每个线程创建一个本地副本,该副本在并行区域之后
A
一起添加到外部。A
这需要更多的内存和一些计算,但并行代码本身可以最有效地工作。如果A
很小,并且每次更新的计算量很小,请使用此选项。
顺便说一句:永远不要rand()
在并行应用程序中使用,它没有被定义为线程安全的,有时它是用锁实现的并且变得非常低效。
编辑:在您的示例中,B
您可以安全地应用omp atomic
或reduction
单独应用到语句,因为每个操作只需要原子独立地执行。
推荐阅读
- c# - 如何在 TreeListView 中绑定数据
- ionic-framework - Ionic:如何处理离线应用程序的自动更新?
- sql - QLSTATE[23000]:违反完整性约束
- c++ - C++中多线程的困惑
- git - 在本地创建新的拉取请求并提交给 master
- xamarin.forms - 如何在 Xamarin 表单中设置图标大小?]
- vue.js - 为什么我应该将事件传递给组件?
- python - Daylocator matplotlib 每天多次显示一天
- jquery - 循环使用产品并获得个人储蓄
- java - 如何将用户重定向到一个页面,然后 servlet 执行一个方法