C ++ OpenMP在矩阵向量产品上的工作速度非常慢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++ OpenMP在矩阵向量产品上的工作速度非常慢相关的知识,希望对你有一定的参考价值。

所以,我正在使用openMP制作矩阵矢量产品,但我注意到它的工作速度很慢。经过一段时间试图弄清楚什么是错的,我只是删除了并行部分中的所有代码,它仍然是SLOW。这可能有什么问题? (n = 1000)

这是1,2和4核心的时间结果。

seq_method time = 0.001047194215062

parrallel_method(1)time = 0.001050273191140 seq - by = -0.000003078976079 seq / by = 0.997068404578433

parrallel_method(2)time = 0.001961992426004 seq - by = -0.000914798210943 seq / by = 0.533740192460558

parrallel_method(4)time = 0.004448095121916 seq - by = -0.003400900906854 seq / by = 0.235425319459132

即使我从并行部分删除代码 - 它也没有太大变化。

void parallel_method(float A[n][n], float B[n], float C[n], int thr_num)
{
    double t1, t2;
    float tmp = 0;
    int i, j;
    t1 = omp_get_wtime();


    omp_set_dynamic(0);
    omp_set_num_threads(thr_num);
#pragma omp parallel for private(tmp, j, i)
    for (i = 0; i < n; i++) {
        tmp = 0;
        for (j = 0; j < n; j++) {
            tmp += A[i][j] * B[j];
        }
#pragma omp atomic
        C[i] += tmp;
    }

    //////
    t2 = omp_get_wtime();
    if (show_c) print_vector(C);
    par = t2 - t1;
    printf("
parrallel_method (%d) time = %.15f", thr_num, par);
    printf("
seq - par = %.15f", seq - par);
    printf("
seq/par = %.15f
", seq / par);
}

代码:https://pastebin.com/Q20t5DLk

答案

我试图重现你的问题而无法做到这一点。我有一个完全连贯的行为。

n=100
sequential_method (0) time = 0.000023339001928
parallel_method (1) time = 0.000023508997401
parallel_method (2) time = 0.000013864002540
parallel_method (4) time = 0.000008979986887

n=1000
sequential_method (0) time = 0.001439775005565
parallel_method (1) time = 0.001437967992388
parallel_method (2) time = 0.000701391996699
parallel_method (4) time = 0.000372130998080

n=10000
sequential_method (0) time = 0.140988592000213
parallel_method (1) time = 0.133375317003811
parallel_method (2) time = 0.077803490007180
parallel_method (4) time = 0.044142695999355

除了小尺寸,线程开销很大,结果或多或少都是预期的。

我做了什么:

  • 所有措施都在同一次运行中完成
  • 我运行所有函数一次没有时间来预热缓存

在实际代码估计中,我也会

  • 时间连续几次执行相同的功能,特别是如果时间短,以减少小的变化
  • 进行几次实验并保持最小的实验以抑制异常值。 (我更喜欢最小,但你也可以计算平均值)。

您应该已经发布了所有代码,我不知道您的方法是什么。但我认为你的估计是在不同的运行中完成的,并且没有预热缓存。对于此代码,缓存影响非常重要,核心必须存储相同的信息(B)。并且问题不足以从更大的L1 / L2缓存中受益。这些倍数负载可以解释并行代码的较差性能。

关于你的代码的最后一点评论。每个线程都有自己的i值。因此C [i]只能由一个线程访问,而原子编译指示是无用的。

以上是关于C ++ OpenMP在矩阵向量产品上的工作速度非常慢的主要内容,如果未能解决你的问题,请参考以下文章

OpenMP 矩阵向量乘法仅在一个线程上执行

OpenMP 中的 C++ 动态内存分配速度较慢,即使对于非并行代码段也是如此

什么可以阻止多处理提高速度 - OpenMP?

c_cpp 对称矩阵和非对称矩阵的特征值/向量

用于矩阵乘法的 OpenMP

openMP 的多线程崩溃