我正在尝试使用OpenMP任务将两个矩阵相乘。这是一个基本代码:
long i, j, k;
for (i = 0; i < N; i ++)
for (j = 0; j < N; j ++)
for (k = 0; k < N; k ++)
c[i * N + j] += a[i * N + k] * b[k * N + j];
所以,我想在列级别上使用任务,然后我修改了这样的代码:
long i, j, k;
#pragma omp parallel
{
#pragma omp single
{
for (i = 0; i < N; i ++)
#pragma omp task private(i, j, k)
{
for (j = 0; j < N; j ++)
for (k = 0; k < N; k ++)
c[i * N + j] += a[i * N + k] * b[k * N + j];
}
}
}
当我运行程序时,我得到这样的消息:
分段错误(核心转储)
现在,我知道我错过了一些,但无法弄清楚是什么。有什么想法吗?
答案 0 :(得分:1)
private
变量未初始化且具有随机初始值。当任务执行时,i
将具有随机值,因此可能导致对c[]
和a[]
的越界访问。
firstprivate
变量与private
类似,但其初始值设置为引用变量在输入构造时的值。在您的情况下,i
必须是firstprivate
而不是private
。
同样建议i
在并行区域中private
,以提高性能。因此,最终代码应如下所示(所有变量共享类都是显式编写的,私有变量在其使用范围内声明):
#pragma omp parallel shared(a, b, c)
{
#pragma omp single
{
long i;
for (i = 0; i < N; i++)
#pragma omp task shared(a, b, c) firstprivate(i)
{
int j, k;
for (j = 0; j < N; j++)
for (k = 0; k < N; k++)
c[i * N + j] += a[i * N + k] * b[k * N + j];
}
}
}