不同线程号openMP上的相同程序执行时间

Posted

技术标签:

【中文标题】不同线程号openMP上的相同程序执行时间【英文标题】:Same program execution time on different thread numbers 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您的帖子直接合并相关文本(最好使用复制+粘贴以避免转录错误)。 【参考方案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 是我的代码

以上是关于不同线程号openMP上的相同程序执行时间的主要内容,如果未能解决你的问题,请参考以下文章

OPENMP 在线程上运行相同的作业

在 OpenMP 中并行化嵌套循环并使用更多线程执行内部循环

如何获得在整个程序执行期间可能创建的最大 OpenMP 线程数?

在 MPICH 中执行混合 OpenMP/MPI 作业

在不同的线程下运行相同的代码有啥意义 - openMP?

执行时间取决于使用 OpenMP 库增加的线程数?