Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带还原的三回路的开mp_C++_Openmp - Fatal编程技术网

C++ 带还原的三回路的开mp

C++ 带还原的三回路的开mp,c++,openmp,C++,Openmp,我需要用open mp乘以两个10x10矩阵。我决定将一个矩阵的行分为3行、3行和4行。如何修复前三行的代码 #pragma omg parallel for reduction(+:m[p][q]) { for (p = 0; p < 3; p++) for (q = 0; q < 10; q++) for (k = 0; k < 10; ++k)

我需要用open mp乘以两个10x10矩阵。我决定将一个矩阵的行分为3行、3行和4行。如何修复前三行的代码

#pragma omg parallel for reduction(+:m[p][q])
        {
            for (p = 0; p < 3; p++)
                for (q = 0; q < 10; q++)
                    for (k = 0; k < 10; ++k)
                    {
                        m[p][q] += l[p][k] * o[k][q];
                    }
        }
#pragma omg并行化简(+:m[p][q])
{
对于(p=0;p<3;p++)
对于(q=0;q<10;q++)
对于(k=0;k<10;++k)
{
m[p][q]+=l[p][k]*o[k][q];
}
}

首先-不要自己分割矩阵,但让OpenMP负责在循环中共享工作,例如

#pragma omg parallel for
{
    for (p = 0; p < 10; p++)
        for (q = 0; q < 10; q++)
            for (k = 0; k < 10; ++k)
            {
                m[p][q] += l[p][k] * o[k][q];
            }
}
#pragma omg并行
{
对于(p=0;p<10;p++)
对于(q=0;q<10;q++)
对于(k=0;k<10;++k)
{
m[p][q]+=l[p][k]*o[k][q];
}
}
在这段代码中不需要
缩减
,因为所有并发写操作都发生在
m
的不同元素上。即使您
collapse(2)
前两个循环,您在这方面仍然很好


也就是说,优化矩阵乘法在现代硬件上是一个极其复杂的话题。将其并行化更是如此。如果您想要获得性能,请使用针对您的体系结构优化的。如果您想学习,我建议您从串行实现开始,然后继续并行化它。这两种方法都有大量的教育材料。

您的方法从一开始就是错误的——编写代码,使OpenMP负责将工作分解到线程上。一个好的方法是首先编写串行代码,然后简单地用OpenMP
parallel for
pragma将最外层的循环包装起来,然后从那里获取。10x10矩阵很小。不要在OpenMP上浪费时间。您确实减少了内部循环,使用局部求和变量可能会更好地优化内部循环:使用如此短的循环,OpenMP将显著降低速度。@tim18,在回答中,我不是在讨论并行矩阵乘法的性能,所以-我关注的是正确性/有效性。实际上,你使用BLAS库,如果你想靠自己接近它,你可以写一篇硕士论文。@tim18,你最好交换q和k循环的顺序。看看
m[p][q]+=l[p][k]*o[k][q]若你们的最里面的循环超过了q,那个么很明显缓存的利用率要高得多。因此,使用局部和变量是一个坏主意。是的,如果循环长度变得足够大,可以从simd中获益,那么交换这些循环可以确保步长1,因此应该可以轻松地自动矢量化。根据编译器和命令行选项(甚至使用_restrict),交换可能会自动完成。通过减少内存流量,不交换和使用标量缩减变量可能效果更好,但可能需要更积极的优化。