简单将 OpenMp Parallel for 转换为 C# Parallel for
本文关键字:for Parallel 转换 简单 OpenMp | 更新日期: 2023-09-27 18:31:26
嗨,我正在将此C ++(openmp)并行转换为C#并行,但它说:
错误 1 并非所有代码路径都返回类型的 lambda 表达式中的值 '
System.Func<int,System.Threading.Tasks.ParallelLoopState,int,int>
'
这是我的代码:
C++
void floyd_warshall(int NumOfThreads) {
int i, j, k;
omp_set_num_threads(NumOfThreads);
for (k = 0; k < n; ++k)
#pragma omp parallel for private(i,j)
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
/* If i and j are different nodes and if
the paths between i and k and between
k and j exist, do */
if ((dist[i][k] * dist[k][j] != 0) && (i != j))
/* See if you can't get a shorter path
between i and j by interspacing
k somewhere along the current
path */
if ((dist[i][k] + dist[k][j] < dist[i][j]) || (dist[i][j] == 0))
dist[i][j] = dist[i][k] + dist[k][j];
}
C#
void floyd_warshall(int NumOfThreads)
{
int k;
ParallelOptions pOp;
pOp.MaxDegreeOfParallelism = NumOfThreads;
for (k = 0; k < n; ++k)
Parallel.For<int>(0, n, pOp , () => 0, (i, loop, j) =>
{ // for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
/* If i and j are different nodes and if
the paths between i and k and between
k and j exist, do */
if ((dist[i, k] * dist[k, j] != 0) && (i != j))
/* See if you can't get a shorter path
between i and j by interspacing
k somewhere along the current
path */
if ((dist[i, k] + dist[k, j] < dist[i, j]) || (dist[i, j] == 0))
dist[i, j] = dist[i, k] + dist[k, j];
}, (j) => 0);
}
您可以使用更简单的 Parallel.For
方法重载,该方法不需要委托具有返回 vale。
var pOp = new ParallelOptions { MaxDegreeOfParallelism = NumOfThreads };
for (int k = 0; k < n; ++k)
Parallel.For(0, n, pOp, i =>
{ // for (i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
/* If i and j are different nodes and if
the paths between i and k and between
k and j exist, do */
if ((dist[i, k] * dist[k, j] != 0) && (i != j))
/* See if you can't get a shorter path
between i and j by interspacing
k somewhere along the current
path */
if ((dist[i, k] + dist[k, j] < dist[i, j]) || (dist[i, j] == 0))
dist[i, j] = dist[i, k] + dist[k, j];
});
我
遇到了和你一样的问题,并设法解决了它。 事实证明,我们的代码正在与 Parallel.For 做非常相似的事情。 您可以从此链接中看到我的解决方案。 最大的区别似乎是您使用值类型(int)进行线程本地存储,而我使用的是引用类型。
第一个问题是你需要一个返回语句。 例如,就在这一行之前:
}, (j) => 0);
添加类似以下内容:
return 0;
您可能要做的第二件事是替换此行:
}, (j) => 0);
像这样:
}, (j) => j = 0);
这是 Parallel.For 函数的第 5 个参数,由每个线程在其工作完成后调用。 如果需要值不变,您也可以通过执行类似 j = j 的操作来执行 no op。 但是,这将生成自分配警告,您必须使用 #pragma 来禁用警告。