gpt4 book ai didi

c++ - 滥用 OpenMP?

转载 作者:太空狗 更新时间:2023-10-29 21:08:54 27 4
gpt4 key购买 nike

我有一个使用 OpenMP 并行化 for 循环的程序。在循环内部,线程将写入共享变量,因此我需要同步它们。但是,我有时会遇到段错误或双重释放或损坏错误。任何人都知道会发生什么?感谢致敬!这是代码:

void KNNClassifier::classify_various_k(int dim, double *feature, int label, int *ks, double * errors, int nb_ks, int k_max) {   
ANNpoint queryPt = 0;
ANNidxArray nnIdx = 0;
ANNdistArray dists = 0;

queryPt = feature;
nnIdx = new ANNidx[k_max];
dists = new ANNdist[k_max];

if(strcmp(_search_neighbors, "brutal") == 0) {// search
_search_struct->annkSearch(queryPt, k_max, nnIdx, dists, _eps);
}else if(strcmp(_search_neighbors, "kdtree") == 0) {
_search_struct->annkSearch(queryPt, k_max, nnIdx, dists, _eps); // double free or corruption
}

for (int j = 0; j < nb_ks; j++)
{
scalar_t result = 0.0;
for (int i = 0; i < ks[j]; i++) {
result+=_labels[ nnIdx[i] ]; // Segmentation fault
}
if (result*label<0)
{
#pragma omp critical
{
errors[j]++;
}
}

}

delete [] nnIdx;
delete [] dists;

}

void KNNClassifier::tune_complexity(int nb_examples, int dim, double **features, int *labels, int fold, char *method, int nb_examples_test, double **features_test, int *labels_test) {
int nb_try = (_k_max - _k_min) / scalar_t(_k_step);
scalar_t *error_validation = new scalar_t [nb_try];
int *ks = new int [nb_try];

for(int i=0; i < nb_try; i ++){
ks[i] = _k_min + _k_step * i;
}

if (strcmp(method, "ct")==0)
{

train(nb_examples, dim, features, labels );// train once for all nb of nbs in ks

for(int i=0; i < nb_try; i ++){
if (ks[i] > nb_examples){nb_try=i; break;}
error_validation[i] = 0;
}

int i = 0;
#pragma omp parallel shared(nb_examples_test, error_validation,features_test, labels_test, nb_try, ks) private(i)
{
#pragma omp for schedule(dynamic) nowait
for (i=0; i < nb_examples_test; i++)
{
classify_various_k(dim, features_test[i], labels_test[i], ks, error_validation, nb_try, ks[nb_try - 1]); // where error occurs
}
}
for (i=0; i < nb_try; i++)
{
error_validation[i]/=nb_examples_test;
}
}

......
}

更新:

在我上一篇文章中 double free or corruption ,代码在单线程下运行良好,但在多线程下会出现运行时错误。错误会不时更改。如果我运行两次,一次会出现段错误,另一次会出现双重释放或损坏。

最佳答案

让我们看一下您的分段故障线:

result+=_labels[ nnIdx[i] ];

result 是本地的 -- OK。

nnIdx 是本地的 -- 也可以。

i 是本地的——仍然可以。

_labels ...这是什么?

它是全局性的吗?您是否通过 #pragma shared 定义了对它的访问?

同样适用于前者:

_search_struct->annkSearch(queryPt, k_max,  nnIdx, dists, _eps);

似乎我们这里有一个不容易解决的问题——_search_struct 不是线程安全的——可能其中的值被线程立即修改。每个线程必须有一个专用的 _search_struct,可能是通过在 classify_various_k 中分配它。

然而,真正的坏消息是 ANN 可能是完全不可线程的:

The library allocates a small amount of storage, which is shared by all search struc- tures built during the program’s lifetime. Because the data is shared, it is not deallocated, even when the all the individual structures are deleted.

如上所示,并行数据修改总是会出现问题,因为库本身有一些共享数据——因此它本身不是线程安全的:/。

关于c++ - 滥用 OpenMP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2182306/

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