gpt4 book ai didi

c++ - OMP 并行还原

转载 作者:行者123 更新时间:2023-11-28 06:26:36 25 4
gpt4 key购买 nike

我正在尝试编写一个 k 均值聚类类。我想让我的函数并行。

void kMeans::findNearestCluster()
{
short closest;
int moves = 0;
#pragma omp parallel for reduction(+:moves)
for(int i = 0; i < n; i++)
{
float min_dist=FLT_MAX;
for(int k=0; k < clusters; k++)
{
float dist_sum = 0.0, dist2 = 0.0;
for(int j = 0; j < dim; j++)
{
dist_sum = centroids[k*dim+j] - data[i*dim+j];
dist2 += dist_sum * dist_sum;

}
if (dist2 < min_dist)
{
min_dist = dist2;
closest = k;

}

}

if (assignment[i] != closest)
{
assignment[i] = closest;
moves++;
}

}

this->moves = moves;

}

它应该是这样工作的:

  • 第 1 步:找到最近的集群

    • 遍历所有数据点,并比较所有质心之间的距离。

    • 找到最近的质心后,它会存储在名为closest 的变量中。

    • 检查这个点是否分配给了新发现的最近的集群。如果没有,请将其移动到新的。 (增量移动)

  • 第 2 步:根据新分配重新计算质心。 (功能未显示)

  • 重复步骤 1 和步骤 2,直到不再发生移动。

没有 #parallel moves 收敛到零。如果我有 #parallel 移动有随机值。我认为是因为并行循环在更新 move 时存在冲突。

也许更好的策略是让每个线程都有自己的移动变量,最后它们会向上。

最佳答案

您使用 closest并行循环内的变量,在增加 moves 之前写入它并使用它作为检查多变的。但是它是在循环外声明的,所以所有的迭代都使用同一个变量!由于所有迭代都是(理论上)并行执行的,因此您不能期望任何迭代都能看到任何其他迭代写入 closest 的内容。在分支条件if (assignment[i] != closest) .该变量通过竞速并行线程随机更新。因此你的moves评估为垃圾值。

移动 closest 的声明在外循环内或将其声明为 private(closest)在 OpenMP pragma 中可能会解决您的问题。

顺便说一下,closest可能未初始化,最好是与 k 相同的类型,即 int .

关于c++ - OMP 并行还原,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28411035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com