首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >滥用OpenMP?

滥用OpenMP?
EN

Stack Overflow用户
提问于 2010-02-02 06:46:14
回答 1查看 1.3K关注 0票数 4

我有一个使用OpenMP并行for循环的程序.在循环中,线程将写入共享变量,因此我需要同步它们。然而,有时我可以得到段错误或双自由或损坏错误。有人知道会发生什么吗?谢谢和问候!以下是代码:

代码语言:javascript
复制
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一样,该代码在单线程上运行良好,但给出了多线程的运行时错误。错误时有发生。如果我运行两次,一个是分段故障,另一个是双倍免费或腐败。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-02-02 07:02:13

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

代码语言:javascript
复制
result+=_labels[ nnIdx[i] ];

result是本地的--好的。

nnIdx是本地的--也可以。

i是本地的--还好。

_labels ...那是什么?

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

前者也是如此:

代码语言:javascript
复制
_search_struct->annkSearch(queryPt, k_max,  nnIdx, dists, _eps);

就像我们在这里遇到的问题一样,一个不易解决的问题-- _search_struct不是线程安全的--其中的值可能是由线程立即修改的。您必须每个线程都有一个专用的_search_struct,可能是通过在classify_various_k中分配它。

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

库分配少量的存储,这是程序生命周期内构建的所有搜索结构所共享的。因为数据是共享的,所以即使删除了所有单个结构,也不会将其解除分配。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2182306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档