OpenMP是否支持查找数组中的最大或最小值?

bigbigknife 2007-11-19 11:43:21
例如下列写法是否正确?
#pragma omp parallel for
for (long j=0; j<n; j++)
{
if (b> a[j])
{
idx = j;
b= a[j];
}
}
我Google和Baidu了几天,都没有找到依据。

另外,对于下列代码是否能OpenMP并行?
#pragma omp parallel for
for (long j=0; j<n; j++)
{
v[ a[j] ][ b[j] ] += w[j];
}
后面加 reduction(+: v) 编译就通不过。
不加,好像也不行。

OpenMP的资料太少了,尤其是中文的。
请各位仁兄指点一二!
...全文
724 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
snow_tengwl 2007-11-22
  • 打赏
  • 举报
回复
加上互斥后的语句如下:
#pragma omp parallel for
for (long j=0; j <n; j++)
{
#pragma omp critical
v[ a[j] ][ b[j] ] += w[j];
}

至于 “怎么保证不能有多个线程同时取道V的同一个元素? ”是由编程人员来保证的。
如果编程人员不能保证,那就最好使用critical。
或者使用V[NUM_THREADS][][]这样的存储,以使的每个线程操作的内存不相冲突。

snow_tengwl 2007-11-22
  • 打赏
  • 举报
回复
本来应该一个线程操纵一块内存,
现在两个线程,按理说应该提供两块内存以供其使用。
当两个线程同时操作一个数组(循环间没有数据依赖)这是比较理想的情况。
现实的应用程序一般都要提供两块内存(根据我自己的实践经验)。
bigbigknife 2007-11-22
  • 打赏
  • 举报
回复
使用#pragma omp critical
据说效率会大大降低,有时候还不如串行。

使用使用V[NUM_THREADS][][]是个好办法,
就是如果V占用的内存比较大,就必须占用非常大的内存。
bigbigknife 2007-11-21
  • 打赏
  • 举报
回复
那么请问,对于
#pragma omp parallel for
for (long j=0; j<n; j++)
{
v[ a[j] ][ b[j] ] += w[j];
}


怎么保证不能有多个线程同时取道V的同一个元素?
或者怎么加上互斥?

谢谢!
snow_tengwl 2007-11-21
  • 打赏
  • 举报
回复
这个问题有两种方法:
1,
#pragma omp parallel for
for (long j=0; j <n; j++)
{
if (b> a[j])
{
#pragam omp critical
{
idx = j;
b= a[j];
}
}
}
因为b和idx都是共享变量,为了让所有线程都可见。所以要加上互斥访问。
2,

int b[NUM_THREADS];
int idx[NUM_THREADS];

#pragma omp parallel for
for (long j=0; j <n; j++)
{
int id = omp_get_thread_num();
if (b[id]> a[j])
{
idx[id] = j;
b[id]= a[j];
}
}
这样每个线程(所对应的迭代区间)对应的最小值和对应的下标就保存在b和idx数组中。
然后在b中找最小值就行了。


一般情况下,2方法的速度比1的快。尽量少用或不用critical。

至于:

#pragma omp parallel for
for (long j=0; j <n; j++)
{
v[ a[j] ][ b[j] ] += w[j];
}

首先reduction(+:v)中的变量必须是scalar变量,不能是序列。
另外必须保证不能有多个线程同时取道V的同一个元素。
否则,应该加上互斥。

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧