【问题标题】:Same program execution time on different thread numbers openMP不同线程号openMP上的相同程序执行时间
【发布时间】:2017-10-30 11:52:07
【问题描述】:

我有一个将 2 个矩阵相乘的 c++ 程序。我必须使用openMP。这就是我到目前为止所拥有的。 https://pastebin.com/wn0AXFBG

#include <stdlib.h>
#include <time.h>
#include <omp.h>
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    int n = 1;

    int Matrix1[1000][100];
    int Matrix2[100][2];
    int Matrix3[1000][2];
    int sum = 0;
    ofstream fr("rez.txt");

    double t1 = omp_get_wtime();

    omp_set_num_threads(n);
#pragma omp parallel for  collapse(2) num_threads(n)
    for ( int i = 0; i < 10; i++) {
        for ( int j = 0; j < 10; j++) {
            Matrix1[i][j] = i * j;
        }
    }


#pragma omp simd
    for (int i = 0; i < 100; i++) {
        for (int j = 0; j < 2; j++) {
            int t = rand() % 100;
            if (t < 50) Matrix2[i][j] = -1;
            if (t >= 50) Matrix2[i][j] = 1;
        }
    }

#pragma omp parallel for  collapse(3) num_threads(n)
    for (int ci = 0; ci < 1000; ci++) {
        for (int cj = 0; cj < 2; cj++) {
            for (int i = 0; i < 100; i++) {
                if(i==0) Matrix3[ci][cj] = 0;
                Matrix3[ci][cj] += Matrix1[ci][i] * Matrix2[i][cj];
            }
        }
    }

    double t2 = omp_get_wtime();

    double time = t2 - t1;

    fr << time;


    return 0;
}

问题在于,无论我使用 1 个线程还是 8 个线程,我都会得到相同的执行时间。添加了时序图片。

我必须证明时间减少了近 8 倍。我正在使用打开了 openMP 的 Intel C++ 编译器。请指教。

【问题讨论】:

  • 您的文字图片isn't very helpful。它无法大声朗读或复制到编辑器中,并且索引不是很好,这意味着有相同问题的其他用户不太可能在这里找到答案。请edit您的帖子直接合并相关文本(最好使用复制+粘贴以避免转录错误)。

标签: c++ multithreading openmp


【解决方案1】:

首先,我认为,当您将矩阵 1 中的条目初始化为 Matrix1[i][j] = i * j 时,您的程序中有一个小错误。 ij 分别不会达到 1000 和 100。

另外,我不确定您的计算机是否真的支持 8 个逻辑核心, 如果没有 8 个逻辑核心,那么您的计算机将创建 8 个线程,一个逻辑核心将上下文切换多个线程,因此会降低性能,从而延长执行时间。因此,请确定有多少实际逻辑核心可用,并将小于或等于该数量的核心指定为num_threads()

现在问题来了,collapse 子句将所有循环融合为一个,并尝试在p 处理器之间动态调度该融合循环。我不确定它如何处理竞争条件处理,但如果您尝试在不融合所有 3 个循环的情况下并行化最内层循环,则会出现竞争条件,因为每个线程都会尝试同时更新 Matrix3[ci][cj] 和某种同步机制可能需要原子或归约子句来确保正确性。

我很确定您可以在没有任何竞争条件的情况下并行化外循环,并且还可以在您使用的处理器数量附近获得加速(同样,只要处理器数量小于或等于逻辑数量核心),我建议如下更改您的代码段。

// You can also use this function to set number of threads:
// omp_set_num_threads(n);
#pragma omp parallel for num_threads(n)
    for (int ci = 0; ci < 1000; ci++) {
        for (int cj = 0; cj < 2; cj++) {
            for (int i = 0; i < 100; i++) {
                if(i==0) Matrix3[ci][cj] = 0;
                Matrix3[ci][cj] += Matrix1[ci][i] * Matrix2[i][cj];
            }
        }
    }

【讨论】:

  • 感谢您的回答。修复了关于 Matrix1 的错误。但是,无论 n 是 1 还是 4,我仍然得到相同的执行时间 (double time = t2 - t1)。我有一个四核处理器。
  • @AugustinasMakevičius 您是否尝试过我删除折叠子句的建议?如果是,那么我将分享我的代码,我已经编写好了代码。
  • 我已尝试删除该子句。不工作。我会很感激你的代码。
  • Here 是我的代码
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2021-12-17
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多