嵌套循环中的分段错误,用于使用矢量中的每2个元素进行计算

Segmentation fault in a nested loop for doing calculations using each 2 elements in vector

本文关键字:2个 元素 计算 错误 分段 用于 嵌套循环      更新时间:2023-10-16

我有一个非常耗时的函数,它需要使用std::vector中的每两个元素进行一些计算。我现在的做法是,

std::vector<int> vec;
for (auto it = vec.begin(); it != vec.end(); ++ it)
  for (auto it2 = vec.begin(); it2 != vec.end(); ++ it2)
    if (it2 != it)
      f(*it, *it2) // the function

我想知道是否还有其他更好的方法可以做到这一点,因为这个过程花费了太多时间。

此外,我曾尝试使用OpenMP来并行外循环,当我使用std::vector时,它工作得很好,但如果我用std::map做类似的事情,它会返回分段错误。


对并行for循环的更新。

我正在做的事情是使用音乐标签计算音乐相似性。每个音乐的标签都在一个称为map_tagstd::map中,所有歌曲ID都在一种称为song_vecvector中。我在这里没有使用iterator,我的代码的主要部分如下。从map_tag读取数据时似乎会出现问题,因为如果我删除这一部分,并行循环就会正常工作。

unsigned int finishCount = 0;
std::map<std::string, std::vector<std::string>> map_tag;
#pragma omp parallel shared(finishCount) num_threads(2)
{
    #pragma omp for
    for (std::size_t i = 0; i < numOfDoc; ++ i) // numOfDoc is number of music
    {
        std::string song_id = song_vec[i];
        std::vector<std::string> song_tag;
        song_tag = map_tag[song_id]; // problems here
        for (std::size_t j = 0; j < numOfDoc; ++ j)
        {
            std::string song_id2 = song_vec[j];
            std::vector<std::string> song_tag2;
            song_tag2 = map_tag[song_id2]; // problems here
            if (song_id != song_id2) 
                calSimilarity(song_tag, song_tag2);
        }
        // so somethings here
        #pragma omp critical // use this show progress
        {
            finishCount ++;
            cout << finishCount << "r";
            cout.flush();
        }
    }
}

另一个更新,我在问题部分之前添加了#pragma omp critical,程序可以正常工作。我不明白故障是怎么引起的,因为map_tag是只读变量,不能在循环内修改。

我是C++的新手,谢谢你的帮助。

首先,更改这个:

std::vector<int> vec;
for (auto it = vec.begin(); it != vec.end(); ++ it)
  for (auto it2 = vec.begin(); it2 != vec.end(); ++ it2)
    if (it2 != it)
      f(*it, *it2) // the function

对此:

std::vector<int> vec;
/// hopefully fill vec with something here... :(
for (auto it = vec.begin(); it != vec.end(); ++ it)
  for (auto it2 = next(it); it2 != vec.end(); ++ it2) /// SEE INITIAL IT2 VALUE
      f(*it, *it2) // the function

您已经将迭代次数减少了一半以上。

你在做很多重复的工作。每个内部循环调用f()vec.size()-1次。

从那里开始,看看它会把你带到哪里。此外,您的问题中没有任何特定于OpenMP的内容,我也不知道您的并行化发生在哪里。请更新更多代码或详细信息。