如何并行化此结构
How to parallelize this structure?
我正试图在C++中使用OpenMP并行化以下结构:
x1,x2,y1,y2,k1,k2 = 0;
a1,a2,b1,b2; //initialized to some value
vec1,vec2;
for (i=0;i<N;++i) {
for (j=0;j<M;++j) {
x2 = j - a2;
y2 = i - b2;
func(x1,y1,x2,y2); // the function changes x1,y1 values
x2 = x1;
y2 = y1;
func2(x1,y1,x2,y2); // the function changes x1,y1 values
x1 += a1;
y1 += b1;
k1 = func3(x1,y1);
vec2[k2] = vec1[k1];
vec2[k2+1] = vec1[k1+1];
k2 += 2;
}
}
你能帮我吗?。我真的很感激你能提供的任何帮助。
编辑:
我尝试过的最后一个解决方案是:
x1,x2,y1,y2,k1,k2 = 0;
a1,a2,b1,b2; //initialized to some value
vec1,vec2;
#pragma omp parallel for ordered schedule(dynamic,1) collapse(2)
for (i=0;i<N;++i) {
for (j=0;j<M;++j) {
x2 = j - a2;
y2 = i - b2;
func(x1,y1,x2,y2); // the function changes x1,y1 values
x2 = x1;
y2 = y1;
func2(x1,y1,x2,y2); // the function changes x1,y1 values
#pragma omp critical
{
x1 += a1;
y1 += b1;
}
k1 = func3(x1,y1);
#pragma omp ordered
{
vec2[k2] = vec1[k1];
vec2[k2+1] = vec1[k1+1];
}
#pragma omp atomic
k2 += 2;
}
}
导致分段故障。
我阅读了你与@Guiroux的聊天,并确定你的循环是独立的。当前从一次迭代到另一次迭代的唯一东西是k2
,它可以直接从i
和j
计算出来(k2 = 2*j+2*M*i
)。
因此,您的并行代码可以简单地为
int k1, k2;
double x1,x2,y1,y2;
double a1,a2,b1,b2; //initialized to some values
double vec1[2*M*N],vec2[2*M*N]; // vec1 is read-only past this point
/*
NOTE: private(var) means that it may no longer have same value it had previously.
In your case, these were all set to 0 before. After reading chat, it seems that
they were never actually used as input anyway. As long as they are written to
before being read from (i.e. x1,y1 in func), no seg fault will occur.
*/
#pragma omp parallel for private(x2,y2,x1,y1,k1,k2)
for (int i=0; i<N; ++i) { // I defined i,j here
for (int j=0; j<M; ++j) { // If you define them outside parallel for,
// they must also be made private
// variables set below are all private, so no threads will overwrite
// work that other threads have done
x2 = j - a2;
y2 = i - b2;
func(x1,y1,x2,y2); // the function sets x1,y1 values
x2 = x1;
y2 = y1;
func2(x1,y1,x2,y2); // the function sets x1,y1 values
x1 += a1;
y1 += b1;
k1 = func3(x1,y1);
// k2 is never the same for 2 different values of i,
// so different threads will never clobber each other here:
k2 = 2*j+2*M*i;
vec2[k2] = vec1[k1];
vec2[k2+1] = vec1[k1+1];
}
}
您不必同时折叠两个循环。只要N > nCoresOnYourComputer
,就可以看到工作将如何在所有处理器之间平均分配。
希望这一切都有意义。试着在我的代码中弄清楚为什么我必须定义某些变量private
(而不是默认的shared
),以及为什么k2
必须像我那样重新定义。
留给读者的练习:除此之外,如何设置k2
(也可以安全地避免竞争条件),但主要保留您最初使用的逻辑(即每次迭代k2 += 2
)?
相关文章:
- 多成员Constexpr结构初始化
- 为什么用结构初始化数组需要指定结构名称
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 使用指定的初始值设定项聚合匿名结构初始化
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 如何使用 OpenMP 并行化最近邻搜索
- 不同的类或结构初始化方法之间的性能差异是什么?
- Malloc 在使用线程并行化 SSH 调用时存在问题
- 如何在结构初始化中获取成员C++
- C++正确的结构初始化
- 使用大括号进行结构初始化
- 内部结构初始化不起作用 - C++
- 如何使用 OpenMP 正确并行化 for 循环?
- 如何将矩阵的行随机复制到内存中的另一个矩阵的过程并行化?
- 如何使用 Pthreads 并行化图像翻转?
- MPI:反复并行化缓冲区
- 使用嵌套结构初始化并集
- 是否可以使用OpenMP并行化一个列表,该列表可以在每次迭代中添加新元素
- 如何并行化此结构