OpenMP - “#pragma omp critical”重要性
OpenMP - "#pragma omp critical" importance
所以我开始使用 OpenMP(多线程)来提高我的矩阵乘法的速度,我目睹了一些奇怪的事情:当我关闭 OpenMP 支持时(在 Visual Studio 2019) 我的嵌套 for 循环完成速度提高了 2 倍。 所以我删除了“#pragma omp critical”以测试它是否显着减慢了进程,进程速度提高了 4 倍比以前(支持 OpenMP 开启)。
这是我的问题:“#pragma omp critical”在嵌套循环中重要吗?不能跳过吗?
#pragma omp parallel for collapse(3)
for (int i = 0; i < this->I; i++)
{
for (int j = 0; j < A.J; j++)
{
m.matrix[i][j] = 0;
for (int k = 0; k < A.I; k++)
{
#pragma omp critical
m.matrix[i][j] += this->matrix[i][k] * A.matrix[k][j];
}
}
}
#pragma omp critical
在这里是必需的,因为有(远程)机会两个线程可以写入特定的 m.matrix[i][j]
值。这会损害性能,因为一次只有一个线程可以访问受保护的赋值语句。
没有 collapse
部分可能会更好(然后您可以删除 #pragma omp critical
)。将总和累加到一个临时局部变量,然后在 k
循环完成后将其存储在 m.matrix[i][j]
中。
Here's my question: is "#pragma omp critical" important in nested
loop? Can't I just skip it?
如果矩阵 m
、this
和 A
不同,则不需要任何临界区。相反,您需要确保每个线程将写入矩阵 m
的不同位置,如下所示:
#pragma omp parallel for collapse(2)
for (int i = 0; i < this->I; i++)
{
for (int j = 0; j < A.J; j++)
{
m.matrix[i][j] = 0;
for (int k = 0; k < A.I; k++)
{
m.matrix[i][j] += this->matrix[i][k] * A.matrix[k][j];
}
}
}
collapse
子句将为每个线程分配不同的一对 (i, j)
因此不会有多个线程写入矩阵的相同位置 m
(即竞争条件)。
所以我开始使用 OpenMP(多线程)来提高我的矩阵乘法的速度,我目睹了一些奇怪的事情:当我关闭 OpenMP 支持时(在 Visual Studio 2019) 我的嵌套 for 循环完成速度提高了 2 倍。 所以我删除了“#pragma omp critical”以测试它是否显着减慢了进程,进程速度提高了 4 倍比以前(支持 OpenMP 开启)。
这是我的问题:“#pragma omp critical”在嵌套循环中重要吗?不能跳过吗?
#pragma omp parallel for collapse(3)
for (int i = 0; i < this->I; i++)
{
for (int j = 0; j < A.J; j++)
{
m.matrix[i][j] = 0;
for (int k = 0; k < A.I; k++)
{
#pragma omp critical
m.matrix[i][j] += this->matrix[i][k] * A.matrix[k][j];
}
}
}
#pragma omp critical
在这里是必需的,因为有(远程)机会两个线程可以写入特定的 m.matrix[i][j]
值。这会损害性能,因为一次只有一个线程可以访问受保护的赋值语句。
没有 collapse
部分可能会更好(然后您可以删除 #pragma omp critical
)。将总和累加到一个临时局部变量,然后在 k
循环完成后将其存储在 m.matrix[i][j]
中。
Here's my question: is "#pragma omp critical" important in nested loop? Can't I just skip it?
如果矩阵 m
、this
和 A
不同,则不需要任何临界区。相反,您需要确保每个线程将写入矩阵 m
的不同位置,如下所示:
#pragma omp parallel for collapse(2)
for (int i = 0; i < this->I; i++)
{
for (int j = 0; j < A.J; j++)
{
m.matrix[i][j] = 0;
for (int k = 0; k < A.I; k++)
{
m.matrix[i][j] += this->matrix[i][k] * A.matrix[k][j];
}
}
}
collapse
子句将为每个线程分配不同的一对 (i, j)
因此不会有多个线程写入矩阵的相同位置 m
(即竞争条件)。