【问题标题】:OpenMP parallelize for construct performanceOpenMP 并行化以提高构造性能
【发布时间】:2013-01-02 13:33:00
【问题描述】:

第一种方法(并行化内循环):

for(j=0; j<LATTICE_VW; ++j) {
    x = j*DX + LATTICE_W;
    #pragma omp parallel for ordered private(y, prob)
        for(i=0; i<LATTICE_VH; ++i) {
            y = i*DY + LATTICE_S;
            prob = psi[i][j].norm();

            #pragma omp ordered
                out << x << " " << y << " " << prob << endl;
        }
}

第二种方法(并行化外循环):

#pragma omp parallel for ordered private(x, y, prob)
    for(j=0; j<LATTICE_VW; ++j) {
        x = j*DX + LATTICE_W;
        for(i=0; i<LATTICE_VH; ++i) {
            y = i*DY + LATTICE_S;
            prob = psi[i][j].norm();

            #pragma omp ordered
                out << x << " " << y << " " << prob << endl;
        }
    }

第三种方法(并行折叠循环)

#pragma omp parallel for collapse(2) ordered private(x, y, prob)
    for(j=0; j<LATTICE_VW; ++j) {
        for(i=0; i<LATTICE_VH; ++i) {
            x = j*DX + LATTICE_W;
            y = i*DY + LATTICE_S;
            prob = psi[i][j].norm();

            #pragma omp ordered
                out << x << " " << y << " " << prob << endl;
        }
    }

如果我猜的话,我会说方法 3 应该是最快的。

但是方法 1 是最快的,而第二种和第三种方法都需要大约相同的时间,就好像没有并行化一样。为什么会发生这种情况?

【问题讨论】:

  • 您是否从方法 2 中获得了正确的输出?变量yprob 也应该是私有的。
  • 对不起,他们在那里是私人的。刚刚编辑过
  • 内环和外环的行程次数是多少?
  • 如果省略ordered 指令和它所涵盖的代码行,你会得到什么样的时间?
  • 如果翻转内循环和外循环会怎样?我看到您正在访问 psi[i][j] 并迭代 j 然后 i

标签: c++ for-loop parallel-processing openmp collapse


【解决方案1】:

看看这个:

for(int x = 0; x < 4; ++x)
  #pragma omp parallel for ordered
  for(int y = 0; y < 4; ++y)
    #pragma omp ordered
    cout << x << ',' << y << " (by thread " << omp_get_thread_num() << ')' << endl;

你有:

0,0 (by thread 0)
0,1 (by thread 1)
0,2 (by thread 2)
0,3 (by thread 3)
1,0 (by thread 0)
1,1 (by thread 1)
1,2 (by thread 2)
1,3 (by thread 3)

每个线程只需要等待一些cout 之前的所有工作就可以并行完成。 但是:

#pragma omp parallel for ordered
for(int x = 0; x < 4; ++x)
  for(int y = 0; y < 4; ++y)
    #pragma omp ordered
    cout << x << ',' << y << " (by thread " << omp_get_thread_num() << ')' << endl;

#pragma omp parallel for collapse(2) ordered
for(int x = 0; x < 4; ++x)
  for(int y = 0; y < 4; ++y)
    #pragma omp ordered
    cout << x << ',' << y << " (by thread " << omp_get_thread_num() << ')' << endl;

情况是:

0,0 (by thread 0)
0,1 (by thread 0)
0,2 (by thread 0)
0,3 (by thread 0)
1,0 (by thread 1)
1,1 (by thread 1)
1,2 (by thread 1)
1,3 (by thread 1)
2,0 (by thread 2)
2,1 (by thread 2)
2,2 (by thread 2)
2,3 (by thread 2)
3,0 (by thread 3)
3,1 (by thread 3)
3,2 (by thread 3)
3,3 (by thread 3)

所以thread 1 必须等待thread 0 完成所有工作,然后才能第一次cout,并且几乎没有什么可以并行完成。

尝试将schedule(static,1) 添加到collapse-version 中,它的性能应该至少与第一个版本一样好。

【讨论】:

    猜你喜欢
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 2014-12-17
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多